1 /* 2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <NetworkRoster.h> 8 9 #include <errno.h> 10 #include <sys/sockio.h> 11 12 #include <NetworkInterface.h> 13 14 #include <net_notifications.h> 15 #include <AutoDeleter.h> 16 17 18 BNetworkRoster BNetworkRoster::sDefault; 19 20 21 /*static*/ BNetworkRoster& 22 BNetworkRoster::Default() 23 { 24 return sDefault; 25 } 26 27 28 size_t 29 BNetworkRoster::CountInterfaces() const 30 { 31 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 32 if (socket < 0) 33 return 0; 34 35 FileDescriptorCloser closer(socket); 36 37 ifconf config; 38 config.ifc_len = sizeof(config.ifc_value); 39 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) != 0) 40 return 0; 41 42 return (size_t)config.ifc_value; 43 } 44 45 46 status_t 47 BNetworkRoster::GetNextInterface(uint32* cookie, 48 BNetworkInterface& interface) const 49 { 50 // TODO: think about caching the interfaces! 51 52 if (cookie == NULL) 53 return B_BAD_VALUE; 54 55 // get a list of all interfaces 56 57 int socket = ::socket(AF_INET, SOCK_DGRAM, 0); 58 if (socket < 0) 59 return errno; 60 61 FileDescriptorCloser closer(socket); 62 63 ifconf config; 64 config.ifc_len = sizeof(config.ifc_value); 65 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) 66 return errno; 67 68 size_t count = (size_t)config.ifc_value; 69 if (count == 0) 70 return B_BAD_VALUE; 71 72 char* buffer = (char*)malloc(count * sizeof(struct ifreq)); 73 if (buffer == NULL) 74 return B_NO_MEMORY; 75 76 MemoryDeleter deleter(buffer); 77 78 config.ifc_len = count * sizeof(struct ifreq); 79 config.ifc_buf = buffer; 80 if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) 81 return errno; 82 83 ifreq* interfaces = (ifreq*)buffer; 84 ifreq* end = (ifreq*)(buffer + config.ifc_len); 85 86 for (uint32 i = 0; interfaces < end; i++) { 87 interface.SetTo(interfaces[0].ifr_name); 88 if (i == *cookie) { 89 (*cookie)++; 90 return B_OK; 91 } 92 93 interfaces = (ifreq*)((uint8*)interfaces 94 + _SIZEOF_ADDR_IFREQ(interfaces[0])); 95 } 96 97 return B_BAD_VALUE; 98 } 99 100 101 status_t 102 BNetworkRoster::AddInterface(const BNetworkInterface& interface) 103 { 104 // TODO: implement me 105 return B_NOT_SUPPORTED; 106 } 107 108 109 status_t 110 BNetworkRoster::RemoveInterface(const BNetworkInterface& interface) 111 { 112 // TODO: implement me 113 return B_NOT_SUPPORTED; 114 } 115 116 117 status_t 118 BNetworkRoster::StartWatching(const BMessenger& target, uint32 eventMask) 119 { 120 return start_watching_network(eventMask, target); 121 } 122 123 124 void 125 BNetworkRoster::StopWatching(const BMessenger& target) 126 { 127 stop_watching_network(target); 128 } 129 130 131 // #pragma mark - private 132 133 134 BNetworkRoster::BNetworkRoster() 135 { 136 } 137 138 139 BNetworkRoster::~BNetworkRoster() 140 { 141 } 142