BPicture: Fix archive constructor.
[haiku.git] / src / kits / network / libnetapi / NetworkRoster.cpp
blob3171aaffaf9c5626e3910c676c7138f5db383894
1 /*
2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <NetworkRoster.h>
9 #include <errno.h>
10 #include <sys/sockio.h>
12 #include <NetworkDevice.h>
13 #include <NetworkInterface.h>
15 #include <net_notifications.h>
16 #include <AutoDeleter.h>
17 #include <NetServer.h>
20 // TODO: using AF_INET for the socket isn't really a smart idea, as one
21 // could completely remove IPv4 support from the stack easily.
22 // Since in the stack, device_interfaces are pretty much interfaces now, we
23 // could get rid of them more or less, and make AF_LINK provide the same
24 // information as AF_INET for the interface functions mostly.
27 BNetworkRoster BNetworkRoster::sDefault;
30 /*static*/ BNetworkRoster&
31 BNetworkRoster::Default()
33 return sDefault;
37 size_t
38 BNetworkRoster::CountInterfaces() const
40 int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
41 if (socket < 0)
42 return 0;
44 FileDescriptorCloser closer(socket);
46 ifconf config;
47 config.ifc_len = sizeof(config.ifc_value);
48 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) != 0)
49 return 0;
51 return (size_t)config.ifc_value;
55 status_t
56 BNetworkRoster::GetNextInterface(uint32* cookie,
57 BNetworkInterface& interface) const
59 // TODO: think about caching the interfaces!
61 if (cookie == NULL)
62 return B_BAD_VALUE;
64 // get a list of all interfaces
66 int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
67 if (socket < 0)
68 return errno;
70 FileDescriptorCloser closer(socket);
72 ifconf config;
73 config.ifc_len = sizeof(config.ifc_value);
74 if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
75 return errno;
77 size_t count = (size_t)config.ifc_value;
78 if (count == 0)
79 return B_BAD_VALUE;
81 char* buffer = (char*)malloc(count * sizeof(struct ifreq));
82 if (buffer == NULL)
83 return B_NO_MEMORY;
85 MemoryDeleter deleter(buffer);
87 config.ifc_len = count * sizeof(struct ifreq);
88 config.ifc_buf = buffer;
89 if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
90 return errno;
92 ifreq* interfaces = (ifreq*)buffer;
93 ifreq* end = (ifreq*)(buffer + config.ifc_len);
95 for (uint32 i = 0; interfaces < end; i++) {
96 interface.SetTo(interfaces[0].ifr_name);
97 if (i == *cookie) {
98 (*cookie)++;
99 return B_OK;
102 interfaces = (ifreq*)((uint8*)interfaces
103 + _SIZEOF_ADDR_IFREQ(interfaces[0]));
106 return B_BAD_VALUE;
110 status_t
111 BNetworkRoster::AddInterface(const char* name)
113 int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
114 if (socket < 0)
115 return errno;
117 FileDescriptorCloser closer(socket);
119 ifaliasreq request;
120 memset(&request, 0, sizeof(ifaliasreq));
121 strlcpy(request.ifra_name, name, IF_NAMESIZE);
123 if (ioctl(socket, SIOCAIFADDR, &request, sizeof(request)) != 0)
124 return errno;
126 return B_OK;
130 status_t
131 BNetworkRoster::AddInterface(const BNetworkInterface& interface)
133 return AddInterface(interface.Name());
137 status_t
138 BNetworkRoster::RemoveInterface(const char* name)
140 int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
141 if (socket < 0)
142 return errno;
144 FileDescriptorCloser closer(socket);
146 ifreq request;
147 strlcpy(request.ifr_name, name, IF_NAMESIZE);
149 request.ifr_addr.sa_family = AF_UNSPEC;
151 if (ioctl(socket, SIOCDIFADDR, &request, sizeof(request)) != 0)
152 return errno;
154 return B_OK;
158 status_t
159 BNetworkRoster::RemoveInterface(const BNetworkInterface& interface)
161 return RemoveInterface(interface.Name());
165 int32
166 BNetworkRoster::CountPersistentNetworks() const
168 BMessenger networkServer(kNetServerSignature);
169 BMessage message(kMsgCountPersistentNetworks);
170 BMessage reply;
171 if (networkServer.SendMessage(&message, &reply) != B_OK)
172 return 0;
174 int32 count = 0;
175 if (reply.FindInt32("count", &count) != B_OK)
176 return 0;
178 return count;
182 status_t
183 BNetworkRoster::GetNextPersistentNetwork(uint32* cookie,
184 wireless_network& network) const
186 BMessenger networkServer(kNetServerSignature);
187 BMessage message(kMsgGetPersistentNetwork);
188 message.AddInt32("index", (int32)*cookie);
190 BMessage reply;
191 status_t result = networkServer.SendMessage(&message, &reply);
192 if (result != B_OK)
193 return result;
195 status_t status;
196 if (reply.FindInt32("status", &status) != B_OK)
197 return B_ERROR;
198 if (status != B_OK)
199 return status;
201 BMessage networkMessage;
202 if (reply.FindMessage("network", &networkMessage) != B_OK)
203 return B_ERROR;
205 BString networkName;
206 if (networkMessage.FindString("name", &networkName) != B_OK)
207 return B_ERROR;
209 memset(network.name, 0, sizeof(network.name));
210 strncpy(network.name, networkName.String(), sizeof(network.name));
212 BNetworkAddress address;
213 if (networkMessage.FindFlat("address", &network.address) != B_OK)
214 network.address.Unset();
216 if (networkMessage.FindUInt32("flags", &network.flags) != B_OK)
217 network.flags = 0;
219 if (networkMessage.FindUInt32("authentication_mode",
220 &network.authentication_mode) != B_OK) {
221 network.authentication_mode = B_NETWORK_AUTHENTICATION_NONE;
224 if (networkMessage.FindUInt32("cipher", &network.cipher) != B_OK)
225 network.cipher = B_NETWORK_CIPHER_NONE;
227 if (networkMessage.FindUInt32("group_cipher", &network.group_cipher)
228 != B_OK) {
229 network.group_cipher = B_NETWORK_CIPHER_NONE;
232 if (networkMessage.FindUInt32("key_mode", &network.key_mode) != B_OK)
233 network.key_mode = B_KEY_MODE_NONE;
235 return B_OK;
239 status_t
240 BNetworkRoster::AddPersistentNetwork(const wireless_network& network)
242 BMessage message(kMsgAddPersistentNetwork);
243 BString networkName;
244 networkName.SetTo(network.name, sizeof(network.name));
245 status_t status = message.AddString("name", networkName);
246 if (status == B_OK) {
247 BNetworkAddress address = network.address;
248 status = message.AddFlat("address", &address);
251 if (status == B_OK)
252 status = message.AddUInt32("flags", network.flags);
253 if (status == B_OK) {
254 status = message.AddUInt32("authentication_mode",
255 network.authentication_mode);
257 if (status == B_OK)
258 status = message.AddUInt32("cipher", network.cipher);
259 if (status == B_OK)
260 status = message.AddUInt32("group_cipher", network.group_cipher);
261 if (status == B_OK)
262 status = message.AddUInt32("key_mode", network.key_mode);
264 if (status != B_OK)
265 return status;
267 BMessenger networkServer(kNetServerSignature);
268 BMessage reply;
269 status = networkServer.SendMessage(&message, &reply);
270 if (status == B_OK)
271 reply.FindInt32("status", &status);
273 return status;
277 status_t
278 BNetworkRoster::RemovePersistentNetwork(const char* name)
280 BMessage message(kMsgRemovePersistentNetwork);
281 status_t status = message.AddString("name", name);
282 if (status != B_OK)
283 return status;
285 BMessenger networkServer(kNetServerSignature);
286 BMessage reply;
287 status = networkServer.SendMessage(&message, &reply);
288 if (status == B_OK)
289 reply.FindInt32("status", &status);
291 return status;
295 status_t
296 BNetworkRoster::StartWatching(const BMessenger& target, uint32 eventMask)
298 return start_watching_network(eventMask, target);
302 void
303 BNetworkRoster::StopWatching(const BMessenger& target)
305 stop_watching_network(target);
309 // #pragma mark - private
312 BNetworkRoster::BNetworkRoster()
317 BNetworkRoster::~BNetworkRoster()