From 745457e8142291f2b5fd4ff8b37d6a59e642d24b Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Fri, 23 Oct 2009 22:01:05 +0000 Subject: [PATCH] * Don't use getifaddrs(), since it's not portable; and rework the MAC address reading code. --- getifaddr.c | 75 +++++++++++++++++++++++++++++++---------------------- getifaddr.h | 2 +- minidlna.c | 6 ++--- uuid.c | 49 ++++++++-------------------------- 4 files changed, 58 insertions(+), 74 deletions(-) diff --git a/getifaddr.c b/getifaddr.c index 35d3a3b..c67ade7 100644 --- a/getifaddr.c +++ b/getifaddr.c @@ -91,41 +91,54 @@ getsysaddr(char * buf, int len) } int -getifhwaddr(const char * ifname, char * buf, int len) +getsyshwaddr(char * buf, int len) { - /* SIOCGIFADDR struct ifreq * */ - int s; + struct if_nameindex *ifaces, *if_idx; + unsigned char mac[6]; struct ifreq ifr; - int ifrlen; - unsigned char addr[6]; - char mac_string[4]; - int i; - ifrlen = sizeof(ifr); - if( len < 12 ) - { - return -2; - } - s = socket(AF_INET, SOCK_DGRAM, 0); - if(s < 0) - { - DPRINTF(E_ERROR, L_GENERAL, "socket(PF_INET, SOCK_DGRAM): %s\n", strerror(errno)); - return -1; - } - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if(ioctl(s, SIOCGIFHWADDR, &ifr, &ifrlen) < 0) - { - DPRINTF(E_ERROR, L_GENERAL, "ioctl(s, SIOCGIFHWADDR, ...): %s\n", strerror(errno)); - close(s); - return -1; - } - close(s); + int fd; + int ret = -1; - memmove( addr, ifr.ifr_hwaddr.sa_data, 6); - for (i=0; i<6; ++i) { - sprintf(mac_string, "%2.2x", addr[i]); - strcat(buf, mac_string); + memset(&mac, '\0', sizeof(mac)); + /* Get the spatially unique node identifier */ + fd = socket(AF_INET, SOCK_DGRAM, 0); + if( fd < 0 ) + return(ret); + + ifaces = if_nameindex(); + if(!ifaces) + return(ret); + + for(if_idx = ifaces+2; if_idx->if_index; if_idx++) + { + strncpy(ifr.ifr_name, if_idx->if_name, IFNAMSIZ); + if(ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) + continue; + if(ifr.ifr_ifru.ifru_flags & IFF_LOOPBACK) + continue; + if( ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 ) + continue; + ret = 0; + break; } - return 0; + if_freenameindex(ifaces); + close(fd); + + if(ret == 0) + { + if(len > 12) + { + memmove(mac, ifr.ifr_hwaddr.sa_data, 6); + sprintf(buf, "%02x%02x%02x%02x%02x%02x", + mac[0]&0xFF, mac[1]&0xFF, mac[2]&0xFF, + mac[3]&0xFF, mac[4]&0xFF, mac[5]&0xFF); + } + else if(len == 6) + { + memmove(buf, ifr.ifr_hwaddr.sa_data, 6); + } + } + return ret; } int diff --git a/getifaddr.h b/getifaddr.h index d6651ad..b7ac3fc 100644 --- a/getifaddr.h +++ b/getifaddr.h @@ -19,7 +19,7 @@ int getsysaddr(char * buf, int len); int -getifhwaddr(const char * ifname, char * buf, int len); +getsyshwaddr(char * buf, int len); int get_remote_mac(struct in_addr ip_addr, unsigned char * mac); diff --git a/minidlna.c b/minidlna.c index 6361656..1695ad8 100644 --- a/minidlna.c +++ b/minidlna.c @@ -214,7 +214,7 @@ init(int argc, char * * argv) /*const char * logfilename = 0;*/ const char * presurl = 0; const char * optionsfile = "/etc/minidlna.conf"; - char * mac_str = calloc(1, 64); + char mac_str[13]; char * string, * word; enum media_types type; char * path; @@ -233,15 +233,13 @@ init(int argc, char * * argv) } /* set up uuid based on mac address */ - if( (getifhwaddr("eth0", mac_str, 64) < 0) && - (getifhwaddr("eth1", mac_str, 64) < 0) ) + if( getsyshwaddr(mac_str, sizeof(mac_str)) < 0 ) { DPRINTF(E_OFF, L_GENERAL, "No MAC address found. Falling back to generic UUID.\n"); strcpy(mac_str, "554e4b4e4f57"); } strcpy(uuidvalue+5, "4d696e69-444c-164e-9d41-"); strncat(uuidvalue, mac_str, 12); - free(mac_str); getfriendlyname(friendly_name, FRIENDLYNAME_MAX_LEN); diff --git a/uuid.c b/uuid.c index 56dd49f..3263241 100644 --- a/uuid.c +++ b/uuid.c @@ -22,6 +22,7 @@ #include #include +#include "getifaddr.h" #include "log.h" #define ETH_ALEN 6 @@ -109,55 +110,21 @@ generate_uuid(unsigned char uuid_out[16]) { static u_int64_t last_time_all; static unsigned int clock_seq_started; - static char last_node[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + static char last_node[6] = { 0, 0, 0, 0, 0, 0 }; struct timespec ts; u_int64_t time_all; int inc_clock_seq = 0; - struct ifaddrs *ifaddr, *ifa; unsigned char mac[6]; - struct ifreq ifr; - int fd; - - int found_mac = 0; + int mac_error; memset(&mac, '\0', sizeof(mac)); /* Get the spatially unique node identifier */ - fd = socket(AF_INET, SOCK_DGRAM, 0); - if( fd < 0 ) - return -1; - if(getifaddrs(&ifaddr) == -1) - { - DPRINTF(E_ERROR, L_HTTP, "getifaddrs(): %s\n", strerror(errno)); - return -1; - } + mac_error = getsyshwaddr((char *)mac, sizeof(mac)); - for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) - { - if(ifa->ifa_addr->sa_family != AF_PACKET) - continue; - if(ifa->ifa_flags & IFF_LOOPBACK) - continue; - - strcpy(ifr.ifr_name, ifa->ifa_name); - if(strncmp(last_node, ifa->ifa_name, sizeof(last_node)) != 0) - { - inc_clock_seq = 1; - strncpy(last_node, ifa->ifa_name, sizeof(last_node)); - } - - if(ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) - memmove(mac, ifr.ifr_hwaddr.sa_data, 6); - - found_mac = 1; - break; - } - close(fd); - freeifaddrs(ifaddr); - - if(found_mac) + if(!mac_error) { memcpy(&uuid_out[10], mac, ETH_ALEN); } @@ -172,6 +139,12 @@ generate_uuid(unsigned char uuid_out[16]) } } + if(memcmp(last_node, uuid_out+10, 6) != 0) + { + inc_clock_seq = 1; + memcpy(last_node, uuid_out+10, 6); + } + /* Determine 60-bit timestamp value. For UUID version 1, this is * represented by Coordinated Universal Time (UTC) as a count of 100- * nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of