]> Creatis software - gdcm.git/commitdiff
ENH: Seriously rewrote the GetMacAddress stuff. There is lot less redundancy. I could...
authormalaterre <malaterre>
Sat, 15 Jan 2005 20:24:02 +0000 (20:24 +0000)
committermalaterre <malaterre>
Sat, 15 Jan 2005 20:24:02 +0000 (20:24 +0000)
CMakeLists.txt
gdcmConfigure.h.in
src/gdcmCommon.h
src/gdcmUtil.cxx

index 052c3cc69bd02bd20c08f62306780523263307bc..12d11f997f8dca69ca2cae8d5a04212593018d0c 100644 (file)
@@ -97,7 +97,17 @@ INCLUDE (${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
 TEST_BIG_ENDIAN(GDCM_WORDS_BIGENDIAN)
 
 INCLUDE (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
-CHECK_INCLUDE_FILE("stdint.h" GDCM_HAVE_STDINT_H)
+CHECK_INCLUDE_FILE("stdint.h"       CMAKE_HAVE_STDINT_H)
+
+# Need those header for GetMacAddress in Util
+CHECK_INCLUDE_FILE("unistd.h"       CMAKE_HAVE_UNISTD_H)
+CHECK_INCLUDE_FILE("stdlib.h"       CMAKE_HAVE_STDLIB_H)
+CHECK_INCLUDE_FILE("sys/ioctl.h"    CMAKE_HAVE_SYS_IOCTL_H)
+CHECK_INCLUDE_FILE("sys/socket.h"   CMAKE_HAVE_SYS_SOCKET_H)
+CHECK_INCLUDE_FILE("sys/sockio.h"   CMAKE_HAVE_SYS_SOCKIO_H)
+CHECK_INCLUDE_FILE("net/if.h"       CMAKE_HAVE_NET_IF_H)
+CHECK_INCLUDE_FILE("netinet/in.h"   CMAKE_HAVE_NETINET_IN_H)
+CHECK_INCLUDE_FILE("net/if_dl.h"    CMAKE_HAVE_NET_IF_DL_H)
 
 CONFIGURE_FILE(${GDCM_SOURCE_DIR}/gdcmConfigure.h.in
                ${GDCM_BINARY_DIR}/gdcmConfigure.h @ONLY IMMEDIATE)
index 3a6f66c47cdae7c0b20c1cd3d0cd58bdfbd87b58..83297de2f3fe866c4df58bf9ed6b40c3f47ab0c4 100644 (file)
@@ -22,7 +22,7 @@
 #cmakedefine GDCM_NO_ANSI_STRING_STREAM
 
 /* I guess something important */
-#cmakedefine GDCM_HAVE_STDINT_H
+#cmakedefine CMAKE_HAVE_STDINT_H
 
 /* This variable allows you to have helpful debug statement */
 /* That are in between #ifdef / endif in the gdcm code */
 #cmakedefine GDCM_COMPILER_HAS_FUNCTION
 
 
+/* GetMacAddress require a lot of include file to access low level API */
+#cmakedefine CMAKE_HAVE_UNISTD_H
+#cmakedefine CMAKE_HAVE_STDLIB_H
+#cmakedefine CMAKE_HAVE_SYS_IOCTL_H
+#cmakedefine CMAKE_HAVE_SYS_SOCKET_H
+#cmakedefine CMAKE_HAVE_SYS_SOCKIO_H
+#cmakedefine CMAKE_HAVE_NET_IF_H
+#cmakedefine CMAKE_HAVE_NETINET_IN_H
+#cmakedefine CMAKE_HAVE_NET_IF_DL_H
+
+
 /*--------------------------------------------------------------------------*/
 /* GDCM Versioning                                                          */
 
index a7e02aa9d3cf4c78505d82c6f010eab945183f4e..233a3d116887ec3c1faf5ec3de1efd2858545436 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmCommon.h,v $
   Language:  C++
-  Date:      $Date: 2005/01/10 20:52:39 $
-  Version:   $Revision: 1.49 $
+  Date:      $Date: 2005/01/15 20:24:02 $
+  Version:   $Revision: 1.50 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -45,7 +45,7 @@
 #endif //_MSC_VER
 
 //-----------------------------------------------------------------------------
-#ifdef GDCM_HAVE_STDINT_H
+#ifdef CMAKE_HAVE_STDINT_H
 #include <stdint.h>   // For uint8_t uint16_t and uint32_t
 #else
 #if defined(_MSC_VER) || defined(__BORLANDC__)
index 8457f0a366084f3ad3b989129734cc788bc7b58b..7f21531e74cacf93953b45957d80eb79804bb26d 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmUtil.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/01/15 03:49:49 $
-  Version:   $Revision: 1.91 $
+  Date:      $Date: 2005/01/15 20:24:02 $
+  Version:   $Revision: 1.92 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
 #endif
 
 // For GetMACAddress
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-
 #ifdef _WIN32
 #include <snmp.h>
 #include <conio.h>
 #else
-#include <strings.h> //for bzero on unix
-#endif
-
-#if defined(__linux__) || defined(__CYGWIN__)
-#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+//#include <errno.h>
 #include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#ifdef CMAKE_HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>  // For SIOCGIFCONF on Linux
+#endif
+#ifdef CMAKE_HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#include <netinet/in.h>
 #endif
-#ifdef __linux__
-#include <linux/if.h>
+#ifdef CMAKE_HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>  // For SIOCGIFCONF on SunOS
 #endif
-
-#ifdef __FreeBSD__
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <ifaddrs.h>
-#include <net/if_dl.h>
+#ifdef CMAKE_HAVE_NET_IF_H
+#include <net/if.h>
 #endif
-
-#ifdef __HP_aCC
-#include <netio.h>
+#ifdef CMAKE_HAVE_NETINET_IN_H
+#include <netinet/in.h>   //For IPPROTO_IP
 #endif
-
-#ifdef _AIX
-#include <sys/ndd_var.h>
-#include <sys/kinfo.h>
+#ifdef CMAKE_HAVE_NET_IF_DL_H
+#include <net/if_dl.h>
 #endif
 
+// How do I do that in CMake ?
 #ifdef __APPLE__
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/network/IOEthernetInterface.h>
-#include <IOKit/network/IONetworkInterface.h>
-#include <IOKit/network/IOEthernetController.h>
-#endif //__APPLE__
-// End For GetMACAddress
+#define HAVE_SA_LEN
+#endif //APPLE
+
+#endif //_WIN32
 
 namespace gdcm 
 {
@@ -382,178 +375,7 @@ typedef BOOL(WINAPI * pSnmpExtensionInitEx) (
 #endif //_WIN32
 
 
-#ifdef __APPLE__
-// Returns an iterator containing the primary (built-in) Ethernet interface. 
-// The caller is responsible for releasing the iterator after the caller is 
-// done with it.
-static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
-{
-   kern_return_t   kernResult; 
-   mach_port_t     masterPort;
-   CFMutableDictionaryRef  matchingDict;
-   CFMutableDictionaryRef  propertyMatchDict;
-   
-   // Retrieve the Mach port used to initiate communication with I/O Kit
-   kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
-   if (KERN_SUCCESS != kernResult)
-   {
-       printf("IOMasterPort returned %d\n", kernResult);
-       return kernResult;
-   }
-   
-   // Ethernet interfaces are instances of class kIOEthernetInterfaceClass. 
-   // IOServiceMatching is a convenience function to create a dictionary 
-   // with the key kIOProviderClassKey and 
-   // the specified value.
-   matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);
-
-   // Note that another option here would be:
-   // matchingDict = IOBSDMatching("en0");
-       
-   if (NULL == matchingDict)
-   {
-       printf("IOServiceMatching returned a NULL dictionary.\n");
-   }
-   else 
-   {
-      // Each IONetworkInterface object has a Boolean property with the 
-      // key kIOPrimaryInterface. Only the
-      // primary (built-in) interface has this property set to TRUE.
-      
-      // IOServiceGetMatchingServices uses the default matching criteria 
-      // defined by IOService. This considers
-      // only the following properties plus any family-specific matching 
-      // in this order of precedence 
-      // (see IOService::passiveMatch):
-      //
-      // kIOProviderClassKey (IOServiceMatching)
-      // kIONameMatchKey (IOServiceNameMatching)
-      // kIOPropertyMatchKey
-      // kIOPathMatchKey
-      // kIOMatchedServiceCountKey
-      // family-specific matching
-      // kIOBSDNameKey (IOBSDNameMatching)
-      // kIOLocationMatchKey
-      
-      // The IONetworkingFamily does not define any family-specific 
-      // matching. This means that in order to have 
-      // IOServiceGetMatchingServices consider the kIOPrimaryInterface 
-      // property, we must add that property to a separate dictionary and 
-      // then add that to our matching dictionary specifying 
-      // kIOPropertyMatchKey.
-          
-      propertyMatchDict = 
-         CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
-                                    &kCFTypeDictionaryKeyCallBacks,
-                                    &kCFTypeDictionaryValueCallBacks);
-   
-      if (NULL == propertyMatchDict)
-      {
-          printf("CFDictionaryCreateMutable returned a NULL dictionary.\n");
-      }
-      else 
-      {
-         // Set the value in the dictionary of the property with the given 
-         // key, or add the key to the dictionary if it doesn't exist. 
-         // This call retains the value object passed in.
-         CFDictionarySetValue(propertyMatchDict, CFSTR(kIOPrimaryInterface), 
-                              kCFBooleanTrue); 
-         
-         // Now add the dictionary containing the matching value for 
-         // kIOPrimaryInterface to our main matching dictionary. This call 
-         // will retain propertyMatchDict, so we can release our reference 
-         // on propertyMatchDict after adding it to matchingDict.
-         CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), 
-                              propertyMatchDict);
-         CFRelease(propertyMatchDict);
-      }
-   }
-
-   // IOServiceGetMatchingServices retains the returned iterator, so release
-   // the iterator when we're done with it.
-   // IOServiceGetMatchingServices also consumes a reference on the matching
-   // dictionary so we don't need to release the dictionary explicitly.
-   kernResult = 
-     IOServiceGetMatchingServices(masterPort, matchingDict, matchingServices);
-   if (KERN_SUCCESS != kernResult)
-   {
-       printf("IOServiceGetMatchingServices returned %d\n", kernResult);
-   }
-
-   return kernResult;
-}
-    
-// Given an iterator across a set of Ethernet interfaces, return the MAC 
-// address of the last one.
-// If no interfaces are found the MAC address is set to an empty string.
-// In this sample the iterator should contain just the primary interface.
-static kern_return_t GetMACAddress_MAC(io_iterator_t intfIterator, 
-                                       UInt8 *MACAddress)
-{
-   io_object_t   intfService;
-   io_object_t   controllerService;
-   kern_return_t kernResult = KERN_FAILURE;
-   
-   // Initialize the returned address
-   bzero(MACAddress, kIOEthernetAddressSize);
-   
-   // IOIteratorNext retains the returned object, so release it when we're 
-   // done with it.
-   while ( (intfService = IOIteratorNext(intfIterator)))
-   {
-      CFTypeRef MACAddressAsCFData;        
-
-      // IONetworkControllers can't be found directly by the 
-      // IOServiceGetMatchingServices call, since they are hardware nubs 
-      // and do not participate in driver matching. In other words,
-      // registerService() is never called on them. So we've found the 
-      // IONetworkInterface and will 
-      // get its parent controller by asking for it specifically.
-      
-      // IORegistryEntryGetParentEntry retains the returned object, so 
-      // release it when we're done with it.
-      kernResult = IORegistryEntryGetParentEntry( intfService,
-                                                  kIOServicePlane,
-                                                  &controllerService );
-
-      if (KERN_SUCCESS != kernResult)
-      {
-         printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kernResult);
-      }
-      else
-      {
-         // Retrieve the MAC address property from the I/O Registry in the 
-         // form of a CFData
-         MACAddressAsCFData = 
-            IORegistryEntryCreateCFProperty( controllerService,
-                                             CFSTR(kIOMACAddress),
-                                             kCFAllocatorDefault,
-                                             0);
-         if (MACAddressAsCFData)
-         {
-            // for display purposes only; output goes to stderr
-            //CFShow(MACAddressAsCFData);
-            
-            // Get the raw bytes of the MAC address from the CFData
-            CFDataGetBytes(MACAddressAsCFData, 
-                           CFRangeMake(0, kIOEthernetAddressSize), 
-                           MACAddress);
-            CFRelease(MACAddressAsCFData);
-         }
-
-         // Done with the parent Ethernet controller object so we release it.
-         (void) IOObjectRelease(controllerService);
-      }
-
-      // Done with the Ethernet interface object so we release it.
-      (void) IOObjectRelease(intfService);
-   }
-
-   return kernResult;
-}
-#endif
-
-long GetMacAddrSys ( u_char *addr)
+long GetMacAddrSys ( unsigned char *addr)
 {
 #ifdef _WIN32
    WSADATA WinsockData;
@@ -684,186 +506,92 @@ long GetMacAddrSys ( u_char *addr)
    SNMP_FreeVarBind(&varBind[0]);
    SNMP_FreeVarBind(&varBind[1]);
    return 0;
-#endif //_WIN32
-
-// implementation for GNU/Linux  and cygwin
-#if defined(__linux__) || defined(__CYGWIN__)
-   struct ifreq ifr;
-   struct ifreq *IFR;
-   struct ifconf ifc;
+#else
+// implementation for POSIX system
+#ifdef CMAKE_HAVE_NET_IF_H
+   int       sd;
+   struct ifreq    ifr, *ifrp;
+   struct ifconf    ifc;
    char buf[1024];
-   int s, i;
-   int ok = 0;
-
-   s = socket(AF_INET, SOCK_DGRAM, 0);
-   if (s == -1)
-   {
-       return -1;
-   }
-
-   ifc.ifc_len = sizeof(buf);
-   ifc.ifc_buf = buf;
-   ioctl(s, SIOCGIFCONF, &ifc);
-   IFR = ifc.ifc_req;
-   for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++)
-   {
-      strcpy(ifr.ifr_name, IFR->ifr_name);
-      if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0)
-      {
-         if (! (ifr.ifr_flags & IFF_LOOPBACK))
-         {
-            if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0)
-            {
-               ok = 1;
-               break;
-            }
-         }
-      }
-   }
-
-   close(s);
-   if (ok)
-   {
-      bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);
-   }
-   else
-   {
-      return -1;
-   }
-   return 0;
+   int      n, i;
+   unsigned char    *a;
+#ifdef AF_LINK
+   struct sockaddr_dl *sdlp;
 #endif
 
-// implementation for FreeBSD
-#ifdef __FreeBSD__
-   struct ifaddrs *ifap, *ifaphead;
-   int rtnerr;
-   const struct sockaddr_dl *sdl;
-   caddr_t ap;
-   int alen;
-   rtnerr = getifaddrs(&ifaphead);
-   if (rtnerr)
-   {
-     //perror(NULL);
-     return -1;
-   }
-   for (ifap = ifaphead; ifap; ifap = ifap->ifa_next)
-   {
-      if (ifap->ifa_addr->sa_family == AF_LINK)
-      {
-         sdl = (const struct sockaddr_dl *) ifap->ifa_addr;
-         ap = ((caddr_t)((sdl)->sdl_data + (sdl)->sdl_nlen));
-         alen = sdl->sdl_alen;
-         if (ap && alen > 0) 
-         {
-            //int i;
-            //printf ("%s:", ifap->ifa_name);
-            //for (i = 0; i < alen; i++, ap++)
-              {
-              //printf("%c%02x", i > 0 ? ':' : ' ', 0xff&*ap);
-              }
-            bcopy( ap, addr, 6);
-            //putchar('\n');
-         }
-      }
-   }
-   //putchar('\n');
-   freeifaddrs(ifaphead);
-   return 0;
-#endif //FreeBSD
-
-// implementation for HP-UX
-#ifdef __HP_aCC
-   const char LAN_DEV0[] = "/dev/lan0";
-
-   int fd;
-   struct fis iocnt_block;
-   char net_buf[sizeof(LAN_DEV0)+1];
-
-   (void)sprintf(net_buf, "%s", LAN_DEV0);
-   char *p = net_buf + strlen(net_buf) - 1;
-
-   // 
-   // Get 802.3 address from card by opening the driver and interrogating it.
-   //
-   for (int i = 0; i < 10; i++, (*p)++)
-   {
-      if ((fd = open (net_buf, O_RDONLY)) != -1) 
-      {
-         iocnt_block.reqtype = LOCAL_ADDRESS;
-         ioctl (fd, NETSTAT, &iocnt_block);
-         close (fd);
-
-         if (iocnt_block.vtype == 6) break;
-      }
-   }
-
-   if (fd == -1 || iocnt_block.vtype != 6)
-   {
-      return -1;
-   }
-
-   bcopy( &iocnt_block.value.s[0], addr, 6);
-   return 0;
-#endif // HP-UX
+//
+// BSD 4.4 defines the size of an ifreq to be
+// max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+// However, under earlier systems, sa_len isn't present, so the size is 
+// just sizeof(struct ifreq)
+// We should investiage the use of SIZEOF_ADDR_IFREQ
+//
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif // HAVE_SA_LEN
 
-/* implementation for AIX */
-#ifdef _AIX
-   int size = getkerninfo(KINFO_NDD, 0, 0, 0);
-   if (size <= 0)
+   if( (sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0 )
    {
       return -1;
    }
-   struct kinfo_ndd *nddp = (struct kinfo_ndd *)malloc(size);
-         
-   if (!nddp)
+   memset(buf, 0, sizeof(buf));
+   ifc.ifc_len = sizeof(buf);
+   ifc.ifc_buf = buf;
+   if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
    {
+      close(sd);
       return -1;
    }
-   if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0)
+   n = ifc.ifc_len;
+   for (i = 0; i < n; i+= ifreq_size(*ifrp) )
    {
-      free(nddp);
+      ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
+      strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+      if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+         continue;
+      a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+      if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+         continue;
+      a = (unsigned char *) ifr.ifr_enaddr;
+#else
+#ifdef AF_LINK
+      sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
+      if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
+         continue;
+      a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
+#else
+      /*
+       * XXX we don't have a way of getting the hardware
+       * address
+       */
+      close(sd);
       return -1;
-   }
-   bcopy(nddp->ndd_addr, addr, 6);
-   free(nddp);
-
-   return 0;
-#endif //_AIX
-
-#ifdef __APPLE__
-   io_iterator_t intfIterator;
-   UInt8 MACAddress[ kIOEthernetAddressSize ];
-   kern_return_t kernResult = FindEthernetInterfaces(&intfIterator);
-   
-   if (KERN_SUCCESS != kernResult)
-   {
-       printf("FindEthernetInterfaces returned 0x%08x\n", kernResult);
-   }
-   else
-   {
-      kernResult = GetMACAddress_MAC(intfIterator, MACAddress);
+#endif // AF_LINK
+#endif // SIOCGENADDR
+#endif // SIOCGIFHWADDR
+      if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) continue;
 
-      if (KERN_SUCCESS != kernResult)
+      if (addr) 
       {
-          printf("GetMACAddress returned 0x%08x\n", kernResult);
+         memcpy(addr, a, 6);
+         close(sd);
+         return 0;
       }
    }
+   close(sd);
+#endif
+   return -1;
+#endif //_WIN32
 
-   (void) IOObjectRelease(intfIterator); // Release the iterator.
-       
-   memcpy(addr, MACAddress, kIOEthernetAddressSize);
-   return kernResult;
-#endif //APPLE
-
-/* Not implemented platforms */
-  memset(addr,0,6);
-  return -1;
 }
 
 std::string Util::GetMACAddress()
@@ -884,7 +612,7 @@ std::string Util::GetMACAddress()
          //printf("%2.2x", addr[i]);
          macaddr += Format("%2.2x", addr[i]);
       }
-      // printf( "\n");
+       //printf( "\n");
       return macaddr;
    }
    else