You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

357 lines
11 KiB

  1. Index: squeezelite-1.9.1-1130/main.c
  2. ===================================================================
  3. --- squeezelite-1.9.1-1130.orig/main.c
  4. +++ squeezelite-1.9.1-1130/main.c
  5. @@ -84,6 +84,7 @@ static void usage(const char *argv0) {
  6. #if IR
  7. " -i [<filename>]\tEnable lirc remote control support (lirc config file ~/.lircrc used if filename not specified)\n"
  8. #endif
  9. + " -I <interface>\tNetwork interface used to send discovery\n"
  10. " -m <mac addr>\t\tSet mac address, format: ab:cd:ef:12:34:56\n"
  11. " -M <modelname>\tSet the squeezelite player model name sent to the server (default: " MODEL_NAME_STRING ")\n"
  12. " -n <name>\t\tSet the player name\n"
  13. @@ -267,6 +268,8 @@ int main(int argc, char **argv) {
  14. extern bool user_rates;
  15. char *logfile = NULL;
  16. u8_t mac[6];
  17. + char *iface = NULL;
  18. + in_addr_t bcast_addr = 0;
  19. unsigned stream_buf_size = STREAMBUF_SIZE;
  20. unsigned output_buf_size = 0; // set later
  21. unsigned rates[MAX_SUPPORTED_SAMPLERATES] = { 0 };
  22. @@ -307,6 +310,7 @@ int main(int argc, char **argv) {
  23. int maxSampleRate = 0;
  24. + memset(mac, 0, sizeof(mac));
  25. char *optarg = NULL;
  26. int optind = 1;
  27. int i;
  28. @@ -314,8 +318,6 @@ int main(int argc, char **argv) {
  29. #define MAXCMDLINE 512
  30. char cmdline[MAXCMDLINE] = "";
  31. - get_mac(mac);
  32. -
  33. for (i = 0; i < argc && (strlen(argv[i]) + strlen(cmdline) + 2 < MAXCMDLINE); i++) {
  34. strcat(cmdline, argv[i]);
  35. strcat(cmdline, " ");
  36. @@ -323,7 +325,7 @@ int main(int argc, char **argv) {
  37. while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') {
  38. char *opt = argv[optind] + 1;
  39. - if (strstr("oabcCdefmMnNpPrs"
  40. + if (strstr("oabcCdefImMnNpPrs"
  41. #if ALSA
  42. "UVO"
  43. #endif
  44. @@ -424,6 +426,9 @@ int main(int argc, char **argv) {
  45. case 'f':
  46. logfile = optarg;
  47. break;
  48. + case 'I':
  49. + iface = optarg;
  50. + break;
  51. case 'm':
  52. {
  53. int byte = 0;
  54. @@ -733,6 +738,11 @@ int main(int argc, char **argv) {
  55. winsock_init();
  56. #endif
  57. + if (!(bcast_addr = get_iface_info(log_slimproto, iface, mac))) {
  58. + fprintf(stderr, "Error binding to network or none given\n");
  59. + exit(1);
  60. + }
  61. +
  62. stream_init(log_stream, stream_buf_size);
  63. if (!strcmp(output_device, "-")) {
  64. @@ -776,7 +786,7 @@ int main(int argc, char **argv) {
  65. exit(1);
  66. }
  67. - slimproto(log_slimproto, server, mac, name, namefile, modelname, maxSampleRate);
  68. + slimproto(log_slimproto, server, bcast_addr, mac, name, namefile, modelname, maxSampleRate);
  69. decode_close();
  70. stream_close();
  71. Index: squeezelite-1.9.1-1130/squeezelite.h
  72. ===================================================================
  73. --- squeezelite-1.9.1-1130.orig/squeezelite.h
  74. +++ squeezelite-1.9.1-1130/squeezelite.h
  75. @@ -414,7 +414,7 @@ typedef enum { EVENT_TIMEOUT = 0, EVENT_
  76. char *next_param(char *src, char c);
  77. u32_t gettime_ms(void);
  78. -void get_mac(u8_t *mac);
  79. +in_addr_t get_iface_info(log_level level, char *iface, u8_t *mac);
  80. void set_nonblock(sockfd s);
  81. int connect_timeout(sockfd sock, const struct sockaddr *addr, socklen_t addrlen, int timeout);
  82. void server_addr(char *server, in_addr_t *ip_ptr, unsigned *port_ptr);
  83. @@ -470,7 +470,7 @@ void buf_init(struct buffer *buf, size_t
  84. void buf_destroy(struct buffer *buf);
  85. // slimproto.c
  86. -void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate);
  87. +void slimproto(log_level level, char *server, in_addr_t bcast_addr, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate);
  88. void slimproto_stop(void);
  89. void wake_controller(void);
  90. Index: squeezelite-1.9.1-1130/slimproto.c
  91. ===================================================================
  92. --- squeezelite-1.9.1-1130.orig/slimproto.c
  93. +++ squeezelite-1.9.1-1130/slimproto.c
  94. @@ -113,7 +113,7 @@ void send_packet(u8_t *packet, size_t le
  95. }
  96. }
  97. -static void sendHELO(bool reconnect, const char *fixed_cap, const char *var_cap, u8_t mac[6]) {
  98. +static void sendHELO(bool reconnect, const char *fixed_cap, const char *var_cap, u8_t *mac) {
  99. const char *base_cap = "Model=squeezelite,AccuratePlayPoints=1,HasDigitalOut=1,HasPolarityInversion=1,Firmware=" VERSION;
  100. struct HELO_packet pkt;
  101. @@ -757,7 +757,7 @@ void wake_controller(void) {
  102. wake_signal(wake_e);
  103. }
  104. -in_addr_t discover_server(char *default_server) {
  105. +in_addr_t discover_server(char *default_server, in_addr_t bcast_addr) {
  106. struct sockaddr_in d;
  107. struct sockaddr_in s;
  108. char *buf;
  109. @@ -774,7 +774,7 @@ in_addr_t discover_server(char *default_
  110. memset(&d, 0, sizeof(d));
  111. d.sin_family = AF_INET;
  112. d.sin_port = htons(PORT);
  113. - d.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  114. + d.sin_addr.s_addr = bcast_addr;
  115. pollinfo.fd = disc_sock;
  116. pollinfo.events = POLLIN;
  117. @@ -809,7 +809,7 @@ in_addr_t discover_server(char *default_
  118. #define FIXED_CAP_LEN 256
  119. #define VAR_CAP_LEN 128
  120. -void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate) {
  121. +void slimproto(log_level level, char *server, in_addr_t bcast_addr, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate) {
  122. struct sockaddr_in serv_addr;
  123. static char fixed_cap[FIXED_CAP_LEN], var_cap[VAR_CAP_LEN] = "";
  124. bool reconnect = false;
  125. @@ -830,7 +830,7 @@ void slimproto(log_level level, char *se
  126. }
  127. if (!slimproto_ip) {
  128. - slimproto_ip = discover_server(server);
  129. + slimproto_ip = discover_server(server, bcast_addr);
  130. }
  131. if (!slimproto_port) {
  132. @@ -911,7 +911,7 @@ void slimproto(log_level level, char *se
  133. // rediscover server if it was not set at startup
  134. if (!server && ++failed_connect > 5) {
  135. - slimproto_ip = serv_addr.sin_addr.s_addr = discover_server(NULL);
  136. + slimproto_ip = serv_addr.sin_addr.s_addr = discover_server(NULL, bcast_addr);
  137. }
  138. } else {
  139. Index: squeezelite-1.9.1-1130/utils.c
  140. ===================================================================
  141. --- squeezelite-1.9.1-1130.orig/utils.c
  142. +++ squeezelite-1.9.1-1130/utils.c
  143. @@ -22,11 +22,11 @@
  144. #include "squeezelite.h"
  145. #if LINUX || OSX || FREEBSD
  146. -#include <sys/ioctl.h>
  147. +#include <sys/types.h>
  148. #include <net/if.h>
  149. -#include <netdb.h>
  150. -#if FREEBSD
  151. #include <ifaddrs.h>
  152. +#include <netdb.h>
  153. +#if FREEBSD || OSX
  154. #include <net/if_dl.h>
  155. #include <net/if_types.h>
  156. #endif
  157. @@ -44,15 +44,11 @@
  158. #if WIN
  159. #include <iphlpapi.h>
  160. #endif
  161. -#if OSX
  162. -#include <net/if_dl.h>
  163. -#include <net/if_types.h>
  164. -#include <ifaddrs.h>
  165. -#include <netdb.h>
  166. -#endif
  167. #include <fcntl.h>
  168. +static log_level loglevel;
  169. +
  170. // logging functions
  171. const char *logtime(void) {
  172. static char buf[100];
  173. @@ -114,58 +110,94 @@ u32_t gettime_ms(void) {
  174. #endif
  175. }
  176. -// mac address
  177. -#if LINUX && !defined(SUN)
  178. -// search first 4 interfaces returned by IFCONF
  179. -void get_mac(u8_t mac[]) {
  180. - char *utmac;
  181. - struct ifconf ifc;
  182. - struct ifreq *ifr, *ifend;
  183. - struct ifreq ifreq;
  184. - struct ifreq ifs[4];
  185. +// Get broadcast address for interface (given or first available)
  186. +// Return MAC address if none given
  187. +#if LINUX || OSX || FREEBSD
  188. - utmac = getenv("UTMAC");
  189. - if (utmac)
  190. - {
  191. - if ( strlen(utmac) == 17 )
  192. - {
  193. - if (sscanf(utmac,"%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
  194. - &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) == 6)
  195. - {
  196. - return;
  197. - }
  198. - }
  199. +in_addr_t get_iface_info(log_level level, char *iface, u8_t *mac) {
  200. + struct ifaddrs *addrs, *ifa;
  201. + struct sockaddr *sdl;
  202. + char ifname[16];
  203. + unsigned char *ptr;
  204. + in_addr_t bcast_addr = 0;
  205. + int have_mac = 0, have_ifname = 0;
  206. +
  207. + loglevel = level;
  208. +
  209. + // Check for non-zero MAC
  210. + if (mac[0] | mac[1] | mac[2] != 0)
  211. + have_mac = 1;
  212. +
  213. + // Copy interface name, if it was provided.
  214. + if (iface != NULL) {
  215. + if (strlen(iface) > sizeof(ifname))
  216. + return -1;
  217. + strncpy(ifname, iface, sizeof(ifname));
  218. + have_ifname = 1;
  219. }
  220. - mac[0] = mac[1] = mac[2] = mac[3] = mac[4] = mac[5] = 0;
  221. + if (getifaddrs(&addrs) == 0) {
  222. + //iterate to find corresponding ethernet address
  223. + for (ifa = addrs; ifa; ifa = ifa->ifa_next) {
  224. + // Skip LOOPBACK interfaces, DOWN interfaces and interfaces that
  225. + // don't support BROADCAST.
  226. + if (ifa->ifa_flags & IFF_LOOPBACK
  227. + || !ifa->ifa_flags & IFF_UP
  228. + || !ifa->ifa_flags & IFF_BROADCAST) {
  229. + continue;
  230. + }
  231. - int s = socket(AF_INET, SOCK_DGRAM, 0);
  232. + if (!have_ifname) {
  233. + // We have found a valid interface name. Keep it.
  234. + strncpy(ifname, ifa->ifa_name, sizeof(ifname));
  235. + have_ifname = 1;
  236. + } else {
  237. + if (strncmp(ifname, ifa->ifa_name, sizeof(ifname)) != 0) {
  238. + // This is not the interface we're looking for.
  239. + continue;
  240. + }
  241. + }
  242. - ifc.ifc_len = sizeof(ifs);
  243. - ifc.ifc_req = ifs;
  244. - if (ioctl(s, SIOCGIFCONF, &ifc) == 0) {
  245. - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
  246. + // Check address family.
  247. + if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET &&
  248. + ((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr.s_addr != 0) {
  249. + // Get broadcast address and MAC address
  250. + bcast_addr = ((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr.s_addr;
  251. + break;
  252. + }
  253. + else {
  254. + // Address is not IPv4
  255. + if (iface == NULL)
  256. + have_ifname = 0;
  257. + }
  258. + }
  259. - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
  260. - if (ifr->ifr_addr.sa_family == AF_INET) {
  261. -
  262. - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
  263. - if (ioctl (s, SIOCGIFHWADDR, &ifreq) == 0) {
  264. - memcpy(mac, ifreq.ifr_hwaddr.sa_data, 6);
  265. - if (mac[0]+mac[1]+mac[2] != 0) {
  266. - break;
  267. - }
  268. + // Find MAC address matching interface
  269. + if (!have_mac && bcast_addr != 0) {
  270. + for (ifa = addrs; ifa; ifa = ifa->ifa_next) {
  271. + if (ifa->ifa_addr && ifa->ifa_addr->sa_family == PF_PACKET &&
  272. + strncmp(ifname, ifa->ifa_name, sizeof(ifname)) == 0) {
  273. + sdl = (struct sockaddr *)(ifa->ifa_addr);
  274. + ptr = (unsigned char *)sdl->sa_data;
  275. + memcpy(mac, ptr + 10, 6);
  276. + have_mac = 1;
  277. }
  278. }
  279. }
  280. +
  281. + freeifaddrs(addrs);
  282. }
  283. - close(s);
  284. + LOG_INFO("Interface: %s, broadcast: %08X, macaddr = %02x:%02x:%02x:%02x:%02x:%02x",
  285. + ifname, bcast_addr, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  286. +
  287. + return bcast_addr;
  288. }
  289. #endif
  290. +
  291. #if SUN
  292. void get_mac(u8_t mac[]) {
  293. struct arpreq parpreq;
  294. @@ -232,30 +264,6 @@ void get_mac(u8_t mac[]) {
  295. }
  296. #endif
  297. -#if OSX || FREEBSD
  298. -void get_mac(u8_t mac[]) {
  299. - struct ifaddrs *addrs, *ptr;
  300. - const struct sockaddr_dl *dlAddr;
  301. - const unsigned char *base;
  302. -
  303. - mac[0] = mac[1] = mac[2] = mac[3] = mac[4] = mac[5] = 0;
  304. -
  305. - if (getifaddrs(&addrs) == 0) {
  306. - ptr = addrs;
  307. - while (ptr) {
  308. - if (ptr->ifa_addr->sa_family == AF_LINK && ((const struct sockaddr_dl *) ptr->ifa_addr)->sdl_type == IFT_ETHER) {
  309. - dlAddr = (const struct sockaddr_dl *)ptr->ifa_addr;
  310. - base = (const unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen];
  311. - memcpy(mac, base, min(dlAddr->sdl_alen, 6));
  312. - break;
  313. - }
  314. - ptr = ptr->ifa_next;
  315. - }
  316. - freeifaddrs(addrs);
  317. - }
  318. -}
  319. -#endif
  320. -
  321. #if WIN
  322. #pragma comment(lib, "IPHLPAPI.lib")
  323. void get_mac(u8_t mac[]) {