1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include <errno.h> 11 #include <net/if.h> 12 #include <sys/socket.h> 13 #include <sys/sockio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <unistd.h> 17 18 #include <AutoDeleter.h> 19 20 #include "compatibility/bsd/ifaddrs.h" 21 22 23 namespace BPrivate { 24 class Socket { 25 public: 26 Socket() 27 { 28 fFD = socket(AF_INET, SOCK_DGRAM, 0); 29 } 30 31 ~Socket() 32 { 33 if (fFD >= 0) 34 close(fFD); 35 } 36 37 int FD() const { return fFD; } 38 39 private: 40 int fFD; 41 }; 42 } // namespace BPrivate 43 44 45 // #pragma mark - 46 47 48 unsigned 49 if_nametoindex(const char* name) 50 { 51 BPrivate::Socket socket; 52 if (socket.FD() < 0) 53 return 0; 54 55 ifreq request; 56 strlcpy(request.ifr_name, name, IF_NAMESIZE); 57 if (ioctl(socket.FD(), SIOCGIFINDEX, &request, sizeof(struct ifreq)) < 0) 58 return 0; 59 60 return request.ifr_index; 61 } 62 63 64 char* 65 if_indextoname(unsigned index, char* nameBuffer) 66 { 67 BPrivate::Socket socket; 68 if (socket.FD() < 0) 69 return NULL; 70 71 ifreq request; 72 request.ifr_index = index; 73 if (ioctl(socket.FD(), SIOCGIFNAME, &request, sizeof(struct ifreq)) < 0) 74 return NULL; 75 76 strlcpy(nameBuffer, request.ifr_name, IF_NAMESIZE); 77 return nameBuffer; 78 } 79 80 81 struct if_nameindex* 82 if_nameindex(void) 83 { 84 BPrivate::Socket socket; 85 if (socket.FD() < 0) 86 return NULL; 87 88 // get a list of all interfaces 89 90 ifconf config; 91 config.ifc_len = sizeof(config.ifc_value); 92 if (ioctl(socket.FD(), SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 93 return NULL; 94 95 int count = (int)config.ifc_value; 96 ifreq* interfaces = (ifreq*)malloc(count * sizeof(struct ifreq)); 97 if (interfaces == NULL) 98 return NULL; 99 100 MemoryDeleter deleter(interfaces); 101 102 config.ifc_len = count * sizeof(struct ifreq); 103 config.ifc_req = interfaces; 104 if (ioctl(socket.FD(), SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) 105 return NULL; 106 107 struct if_nameindex* interfaceArray = (struct if_nameindex*)malloc( 108 sizeof(struct if_nameindex) * (count + 1)); 109 if (interfaceArray == NULL) 110 return NULL; 111 112 int i = 0; 113 while (count > 0) { 114 // retrieve interface index 115 ifreq request; 116 strlcpy(((struct ifreq&)request).ifr_name, interfaces->ifr_name, 117 IF_NAMESIZE); 118 119 if (ioctl(socket.FD(), SIOCGIFINDEX, &request, 120 sizeof(struct ifreq)) >= 0) { 121 interfaceArray[i].if_index = request.ifr_index; 122 interfaceArray[i].if_name = strdup(interfaces->ifr_name); 123 i++; 124 } 125 126 interfaces = (ifreq*)((char*)interfaces 127 + _SIZEOF_ADDR_IFREQ(interfaces[0])); 128 count--; 129 } 130 131 interfaceArray[i].if_index = 0; 132 interfaceArray[i].if_name = NULL; 133 134 return interfaceArray; 135 } 136 137 138 void 139 if_freenameindex(struct if_nameindex *interfaceArray) 140 { 141 for (int i = 0; interfaceArray[i].if_name; i++) 142 free(interfaceArray[i].if_name); 143 144 free(interfaceArray); 145 } 146