lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

010-select_broadcast_interface.patch (10478B)


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