2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include <NetworkRoster.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()
38 BNetworkRoster::CountInterfaces() const
40 int socket
= ::socket(AF_INET
, SOCK_DGRAM
, 0);
44 FileDescriptorCloser
closer(socket
);
47 config
.ifc_len
= sizeof(config
.ifc_value
);
48 if (ioctl(socket
, SIOCGIFCOUNT
, &config
, sizeof(struct ifconf
)) != 0)
51 return (size_t)config
.ifc_value
;
56 BNetworkRoster::GetNextInterface(uint32
* cookie
,
57 BNetworkInterface
& interface
) const
59 // TODO: think about caching the interfaces!
64 // get a list of all interfaces
66 int socket
= ::socket(AF_INET
, SOCK_DGRAM
, 0);
70 FileDescriptorCloser
closer(socket
);
73 config
.ifc_len
= sizeof(config
.ifc_value
);
74 if (ioctl(socket
, SIOCGIFCOUNT
, &config
, sizeof(struct ifconf
)) < 0)
77 size_t count
= (size_t)config
.ifc_value
;
81 char* buffer
= (char*)malloc(count
* sizeof(struct ifreq
));
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)
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
);
102 interfaces
= (ifreq
*)((uint8
*)interfaces
103 + _SIZEOF_ADDR_IFREQ(interfaces
[0]));
111 BNetworkRoster::AddInterface(const char* name
)
113 int socket
= ::socket(AF_INET
, SOCK_DGRAM
, 0);
117 FileDescriptorCloser
closer(socket
);
120 memset(&request
, 0, sizeof(ifaliasreq
));
121 strlcpy(request
.ifra_name
, name
, IF_NAMESIZE
);
123 if (ioctl(socket
, SIOCAIFADDR
, &request
, sizeof(request
)) != 0)
131 BNetworkRoster::AddInterface(const BNetworkInterface
& interface
)
133 return AddInterface(interface
.Name());
138 BNetworkRoster::RemoveInterface(const char* name
)
140 int socket
= ::socket(AF_INET
, SOCK_DGRAM
, 0);
144 FileDescriptorCloser
closer(socket
);
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)
159 BNetworkRoster::RemoveInterface(const BNetworkInterface
& interface
)
161 return RemoveInterface(interface
.Name());
166 BNetworkRoster::CountPersistentNetworks() const
168 BMessenger
networkServer(kNetServerSignature
);
169 BMessage
message(kMsgCountPersistentNetworks
);
171 if (networkServer
.SendMessage(&message
, &reply
) != B_OK
)
175 if (reply
.FindInt32("count", &count
) != B_OK
)
183 BNetworkRoster::GetNextPersistentNetwork(uint32
* cookie
,
184 wireless_network
& network
) const
186 BMessenger
networkServer(kNetServerSignature
);
187 BMessage
message(kMsgGetPersistentNetwork
);
188 message
.AddInt32("index", (int32
)*cookie
);
191 status_t result
= networkServer
.SendMessage(&message
, &reply
);
196 if (reply
.FindInt32("status", &status
) != B_OK
)
201 BMessage networkMessage
;
202 if (reply
.FindMessage("network", &networkMessage
) != B_OK
)
206 if (networkMessage
.FindString("name", &networkName
) != B_OK
)
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
)
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
)
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
;
240 BNetworkRoster::AddPersistentNetwork(const wireless_network
& network
)
242 BMessage
message(kMsgAddPersistentNetwork
);
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
);
252 status
= message
.AddUInt32("flags", network
.flags
);
253 if (status
== B_OK
) {
254 status
= message
.AddUInt32("authentication_mode",
255 network
.authentication_mode
);
258 status
= message
.AddUInt32("cipher", network
.cipher
);
260 status
= message
.AddUInt32("group_cipher", network
.group_cipher
);
262 status
= message
.AddUInt32("key_mode", network
.key_mode
);
267 BMessenger
networkServer(kNetServerSignature
);
269 status
= networkServer
.SendMessage(&message
, &reply
);
271 reply
.FindInt32("status", &status
);
278 BNetworkRoster::RemovePersistentNetwork(const char* name
)
280 BMessage
message(kMsgRemovePersistentNetwork
);
281 status_t status
= message
.AddString("name", name
);
285 BMessenger
networkServer(kNetServerSignature
);
287 status
= networkServer
.SendMessage(&message
, &reply
);
289 reply
.FindInt32("status", &status
);
296 BNetworkRoster::StartWatching(const BMessenger
& target
, uint32 eventMask
)
298 return start_watching_network(eventMask
, target
);
303 BNetworkRoster::StopWatching(const BMessenger
& target
)
305 stop_watching_network(target
);
309 // #pragma mark - private
312 BNetworkRoster::BNetworkRoster()
317 BNetworkRoster::~BNetworkRoster()