From 5a12e216fdd3615e3c7c584fc3a898d91643f8f4 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Wed, 3 Nov 2021 13:13:42 +0900 Subject: [PATCH] rewrite CReflector::UpdateListenMac() for multply sockets Please consider not only Apple but also all other *BSDs. --- src/creflector.cpp | 166 +++++++++++---------------------------------- src/creflector.h | 8 +-- 2 files changed, 42 insertions(+), 132 deletions(-) diff --git a/src/creflector.cpp b/src/creflector.cpp index 1f5e65b..dc6761e 100644 --- a/src/creflector.cpp +++ b/src/creflector.cpp @@ -31,6 +31,11 @@ #include "ctranscoder.h" #include "cysfnodedirfile.h" #include "cysfnodedirhttp.h" +#if defined(AF_PACKET) +#include +#elif defined(AF_LINK) +#include +#endif //////////////////////////////////////////////////////////////////////////////////////// // constructor @@ -774,148 +779,53 @@ void CReflector::SendJsonOffairObject(CUdpSocket &Socket, CIp &Ip, const CCallsi //////////////////////////////////////////////////////////////////////////////////////// // MAC address helpers -#ifdef __linux__ -#include -bool CReflector::UpdateListenMac(void) +bool CReflector::UpdateListenMac(int i) { - struct ifaddrs *ifap, *ifaptr; - char host[NI_MAXHOST]; + struct ifaddrs *ifa_top, *ifa; char *ifname = NULL; bool found = false; + socklen_t ss_len; - // iterate through all our AF_INET interface to find the one - // of our listening ip - if ( getifaddrs(&ifap) == 0 ) - { - for ( ifaptr = ifap; (ifaptr != NULL) && !found; ifaptr = (ifaptr)->ifa_next ) - { - // is it an AF_INET? - if ( ifaptr->ifa_addr->sa_family == AF_INET ) - { - if (ifaptr->ifa_addr == NULL) - continue; - - // get the IP - if ( getnameinfo(ifaptr->ifa_addr, - sizeof(struct sockaddr_in), - host, NI_MAXHOST, - NULL, 0, NI_NUMERICHOST) == 0 ) - { - if ( CIp(host) == m_Ip ) - { - // yes, found it - found = true; - ifname = new char[strlen(ifaptr->ifa_name)+1]; - strcpy(ifname, ifaptr->ifa_name); - } - } - } - - } - freeifaddrs(ifap); - } + if ( getifaddrs(&ifa_top) < 0 ) + return false; - // if listening interface name found, iterate again - // to find the corresponding AF_PACKET interface - if ( found ) + m_Ip[i].GetSockAddr(ss_len); + + // get interface name associated with IP address + for ( ifa = ifa_top; ifa != NULL; ifa = ifa->ifa_next ) { - found = false; - if ( getifaddrs(&ifap) == 0 ) - { - for ( ifaptr = ifap; (ifaptr != NULL) && !found; ifaptr = (ifaptr)->ifa_next ) - { - if ( !strcmp((ifaptr)->ifa_name, ifname) && (ifaptr->ifa_addr->sa_family == AF_PACKET) ) - { - found = true; - struct sockaddr_ll *s = (struct sockaddr_ll *)(ifaptr->ifa_addr); - for ( int i = 0; i < 6; i++ ) - { - m_Mac[i] = s->sll_addr[i]; - } - } - } + if ( CIp((struct sockaddr_storage *)ifa->ifa_addr, ss_len) == m_Ip[i] ) { + found = true; + ifname = new char[strlen(ifa->ifa_name) + 1]; + strcpy(ifname, ifa->ifa_name); + break; } - freeifaddrs(ifap); } - // done - return found; -} -#endif - -#if defined(__APPLE__) && defined(__MACH__) -#include -bool CReflector::UpdateListenMac(void) -{ - struct ifaddrs *ifaddr; - int s; - char host[NI_MAXHOST]; - char *ifname = NULL; - bool found = false; - bool ok = false; - - if ( getifaddrs(&ifaddr) != -1) - { - // Walk through linked list, maintaining head pointer so we can free list later. - // until finding our listening AF_INET interface - for (struct ifaddrs *ifa = ifaddr; (ifa != NULL) && !found; ifa = ifa->ifa_next) + // get MAC address from interface name + if ( found ) { + void *p = NULL; + found = false; + for ( ifa = ifa_top; ifa != NULL; ifa = ifa->ifa_next ) { - if (ifa->ifa_addr == NULL) + if ( strcmp(ifa->ifa_name, ifname ) ) continue; - - // is it an AF_INET? - if (ifa->ifa_addr->sa_family == AF_INET) - { - // get IP - s = getnameinfo(ifa->ifa_addr, - sizeof(struct sockaddr_in), - host, NI_MAXHOST, - NULL, 0, NI_NUMERICHOST); - if (s != 0) - { - return false; - } - // is it our listening ip ? - if ( CIp(host) == m_Ip ) - { - // yes, found it - found = true; - ifname = new char[strlen(ifa->ifa_name)+1]; - strcpy(ifname, ifa->ifa_name); - } - } - } - freeifaddrs(ifaddr); - - // found our interface ? - if ( found ) - { - // yes - //std::cout << ifname << " : " << host << std::endl; - - // Walk again through linked list - // until finding our listening AF_LINK interface - if ( getifaddrs(&ifaddr) != -1 ) +#if defined(AF_PACKET) + found = ( ifa->ifa_addr->sa_family == AF_PACKET ); + p = ifa->ifa_addr; +#elif defined(AF_LINK) + found = ( ifa->ifa_addr->sa_family == AF_LINK ); + p = LLADDR((struct sockaddr_dl *)ifa->ifa_addr); +#endif + if ( found ) { - found = false; - for (struct ifaddrs *ifa = ifaddr; (ifa != NULL) && !found; ifa = ifa->ifa_next) - { - if (ifa->ifa_addr == NULL) - continue; - - if ( !strcmp(ifa->ifa_name, ifname) && (ifa->ifa_addr->sa_family == AF_LINK)) - { - ::memcpy((void *)m_Mac, (void *)LLADDR((struct sockaddr_dl *)(ifa)->ifa_addr), sizeof(m_Mac)); - ok = true; - found = true; - } - } - freeifaddrs(ifaddr); + memcpy(m_Mac[i], p, 6); + break; } } - delete [] ifname; } - return ok; + + freeifaddrs(ifa_top); + return found; } -#endif diff --git a/src/creflector.h b/src/creflector.h index 8a59144..354ec3d 100644 --- a/src/creflector.h +++ b/src/creflector.h @@ -58,10 +58,10 @@ public: // settings void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; } const CCallsign &GetCallsign(void) const { return m_Callsign; } - void SetListenIp(int i, const CIp &ip) { m_Ip[i] = ip; UpdateListenMac(); } + void SetListenIp(int i, const CIp &ip) { m_Ip[i] = ip; UpdateListenMac(i); } void SetTranscoderIp(const CIp &ip) { m_AmbedIp = ip; } const CIp &GetListenIp(int i = 0) const { return m_Ip[i]; } - const uint8 *GetListenMac(void) const { return (const uint8 *)m_Mac; } + const uint8 *GetListenMac(int i = 0) const { return (const uint8 *)m_Mac[i]; } const CIp &GetTranscoderIp(void) const { return m_AmbedIp; } // operation @@ -119,13 +119,13 @@ protected: void SendJsonOffairObject(CUdpSocket &, CIp &, const CCallsign &); // MAC address helpers - bool UpdateListenMac(void); + bool UpdateListenMac(int i); protected: // identity CCallsign m_Callsign; CIp m_Ip[UDP_SOCKET_MAX]; - uint8 m_Mac[6]; + uint8 m_Mac[UDP_SOCKET_MAX][6]; CIp m_AmbedIp; // objects