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 <net/if.h> 11#include <sys/socket.h> 12#include <sys/sockio.h> 13#include <stdlib.h> 14#include <string.h> 15#include <unistd.h> 16 17#include <AutoDeleter.h> 18 19 20namespace BPrivate { 21 class Socket { 22 public: 23 Socket() 24 { 25 fFD = socket(AF_INET, SOCK_DGRAM, 0); 26 } 27 28 ~Socket() 29 { 30 if (fFD >= 0) 31 close(fFD); 32 } 33 34 int FD() const { return fFD; } 35 36 private: 37 int fFD; 38 }; 39} // namespace BPrivate 40 41 42// #pragma mark - 43 44 45unsigned 46if_nametoindex(const char* name) 47{ 48 BPrivate::Socket socket; 49 if (socket.FD() < 0) 50 return 0; 51 52 ifreq request; 53 strlcpy(request.ifr_name, name, IF_NAMESIZE); 54 if (ioctl(socket.FD(), SIOCGIFINDEX, &request, sizeof(struct ifreq)) < 0) 55 return 0; 56 57 return request.ifr_index; 58} 59 60 61char* 62if_indextoname(unsigned index, char* nameBuffer) 63{ 64 BPrivate::Socket socket; 65 if (socket.FD() < 0) 66 return NULL; 67 68 ifreq request; 69 request.ifr_index = index; 70 if (ioctl(socket.FD(), SIOCGIFNAME, &request, sizeof(struct ifreq)) < 0) 71 return NULL; 72 73 strlcpy(nameBuffer, request.ifr_name, IF_NAMESIZE); 74 return nameBuffer; 75} 76 77 78struct if_nameindex* 79if_nameindex(void) 80{ 81 BPrivate::Socket socket; 82 if (socket.FD() < 0) 83 return NULL; 84 85 // get a list of all interfaces 86 87 ifconf config; 88 config.ifc_len = sizeof(config.ifc_value); 89 if (ioctl(socket.FD(), SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 90 return NULL; 91 92 int count = (int)config.ifc_value; 93 ifreq* interfaces = (ifreq*)malloc(count * sizeof(struct ifreq)); 94 if (interfaces == NULL) 95 return NULL; 96 97 MemoryDeleter deleter(interfaces); 98 99 config.ifc_len = count * sizeof(struct ifreq); 100 config.ifc_req = interfaces; 101 if (ioctl(socket.FD(), SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) 102 return NULL; 103 104 struct if_nameindex* interfaceArray = (struct if_nameindex*)malloc( 105 sizeof(struct if_nameindex) * (count + 1)); 106 if (interfaceArray == NULL) 107 return NULL; 108 109 for (int i = 0; i < count; i++) { 110 interfaceArray[i].if_index = interfaces->ifr_index; 111 interfaceArray[i].if_name = strdup(interfaces->ifr_name); 112 113 interfaces 114 = (ifreq*)((char*)interfaces + _SIZEOF_ADDR_IFREQ(interfaces[0])); 115 } 116 117 interfaceArray[count].if_index = 0; 118 interfaceArray[count].if_name = NULL; 119 120 return interfaceArray; 121} 122 123 124void 125if_freenameindex(struct if_nameindex *interfaceArray) 126{ 127 for (int i = 0; interfaceArray[i].if_name; i++) { 128 free(interfaceArray[i].if_name); 129 } 130 free(interfaceArray); 131} 132 133