1bf58f252SAxel Dörfler/*
2bf58f252SAxel Dörfler * Copyright 2010, Axel D��rfler, axeld@pinc-software.de.
3bf58f252SAxel Dörfler * Distributed under the terms of the MIT License.
4bf58f252SAxel Dörfler */
5bf58f252SAxel Dörfler
6bf58f252SAxel Dörfler#include <NetworkInterface.h>
7bf58f252SAxel Dörfler
8c2808ea7SAxel Dörfler#include <errno.h>
9c2808ea7SAxel Dörfler#include <net/if.h>
10c2808ea7SAxel Dörfler#include <sys/sockio.h>
11c2808ea7SAxel Dörfler
12c2808ea7SAxel Dörfler#include <AutoDeleter.h>
132087545cSAxel Dörfler#include <Messenger.h>
142087545cSAxel Dörfler#include <NetServer.h>
153b7b927dSMichael Lotz#include <NetworkRoute.h>
163b7b927dSMichael Lotz
17c2808ea7SAxel Dörfler
1877206143SAxel Dörflerstatic int
1977206143SAxel Dörflerfamily_from_interface_address(const BNetworkInterfaceAddress& address)
2077206143SAxel Dörfler{
2177206143SAxel Dörfler	if (address.Address().Family() != AF_UNSPEC)
2277206143SAxel Dörfler		return address.Address().Family();
2377206143SAxel Dörfler	if (address.Mask().Family() != AF_UNSPEC)
2477206143SAxel Dörfler		return address.Mask().Family();
2577206143SAxel Dörfler	if (address.Destination().Family() != AF_UNSPEC)
2677206143SAxel Dörfler		return address.Destination().Family();
27a690e259SAxel Dörfler
2877206143SAxel Dörfler	return AF_INET;
2977206143SAxel Dörfler}
30a690e259SAxel Dörfler
31a690e259SAxel Dörfler
3277206143SAxel Dörflerstatic status_t
3377206143SAxel Dörflerdo_ifaliasreq(const char* name, int32 option, BNetworkInterfaceAddress& address,
3477206143SAxel Dörfler	bool readBack = false)
3577206143SAxel Dörfler{
3677206143SAxel Dörfler	int family = AF_INET;
3777206143SAxel Dörfler	if (!readBack)
3877206143SAxel Dörfler		family = family_from_interface_address(address);
3977206143SAxel Dörfler
4077206143SAxel Dörfler	int socket = ::socket(family, SOCK_DGRAM, 0);
4177206143SAxel Dörfler	if (socket < 0)
4277206143SAxel Dörfler		return errno;
4377206143SAxel Dörfler
4477206143SAxel Dörfler	FileDescriptorCloser closer(socket);
4577206143SAxel Dörfler
4677206143SAxel Dörfler	ifaliasreq request;
4777206143SAxel Dörfler	strlcpy(request.ifra_name, name, IF_NAMESIZE);
4877206143SAxel Dörfler	request.ifra_index = address.Index();
4977206143SAxel Dörfler	request.ifra_flags = address.Flags();
5077206143SAxel Dörfler
5177206143SAxel Dörfler	memcpy(&request.ifra_addr, &address.Address().SockAddr(),
5277206143SAxel Dörfler		address.Address().Length());
5377206143SAxel Dörfler	memcpy(&request.ifra_mask, &address.Mask().SockAddr(),
5477206143SAxel Dörfler		address.Mask().Length());
5577206143SAxel Dörfler	memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
5677206143SAxel Dörfler		address.Broadcast().Length());
5777206143SAxel Dörfler
5877206143SAxel Dörfler	if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
5977206143SAxel Dörfler		return errno;
6077206143SAxel Dörfler
6177206143SAxel Dörfler	if (readBack) {
6277206143SAxel Dörfler		address.SetFlags(request.ifra_flags);
6377206143SAxel Dörfler		address.Address().SetTo(request.ifra_addr);
6477206143SAxel Dörfler		address.Mask().SetTo(request.ifra_mask);
6577206143SAxel Dörfler		address.Broadcast().SetTo(request.ifra_broadaddr);
6677206143SAxel Dörfler	}
6777206143SAxel Dörfler
6877206143SAxel Dörfler	return B_OK;
6977206143SAxel Dörfler}
7077206143SAxel Dörfler
7177206143SAxel Dörfler
72c2808ea7SAxel Dörflerstatic status_t
73c2808ea7SAxel Dörflerdo_ifaliasreq(const char* name, int32 option,
74c2808ea7SAxel Dörfler	const BNetworkInterfaceAddress& address)
75c2808ea7SAxel Dörfler{
76c2808ea7SAxel Dörfler	return do_ifaliasreq(name, option,
77c2808ea7SAxel Dörfler		const_cast<BNetworkInterfaceAddress&>(address));
78c2808ea7SAxel Dörfler}
79c2808ea7SAxel Dörfler
80c2808ea7SAxel Dörfler
81d72ede75SAxel Dörflertemplate<typename T> status_t
82d72ede75SAxel Dörflerdo_request(int family, T& request, const char* name, int option)
83c2808ea7SAxel Dörfler{
84a690e259SAxel Dörfler	int socket = ::socket(family, SOCK_DGRAM, 0);
85c2808ea7SAxel Dörfler	if (socket < 0)
86c2808ea7SAxel Dörfler		return errno;
87c2808ea7SAxel Dörfler
88cb7ce9a3SAxel Dörfler	FileDescriptorCloser closer(socket);
89c2808ea7SAxel Dörfler
90d72ede75SAxel Dörfler	strlcpy(((struct ifreq&)request).ifr_name, name, IF_NAMESIZE);
91c2808ea7SAxel Dörfler
92d72ede75SAxel Dörfler	if (ioctl(socket, option, &request, sizeof(T)) < 0)
93c2808ea7SAxel Dörfler		return errno;
94c2808ea7SAxel Dörfler
95c2808ea7SAxel Dörfler	return B_OK;
96c2808ea7SAxel Dörfler}
97c2808ea7SAxel Dörfler
98c2808ea7SAxel Dörfler
99c2808ea7SAxel Dörfler// #pragma mark -
100c2808ea7SAxel Dörfler
101c2808ea7SAxel Dörfler
10277206143SAxel DörflerBNetworkInterfaceAddress::BNetworkInterfaceAddress()
10377206143SAxel Dörfler	:
10477206143SAxel Dörfler	fIndex(-1),
10577206143SAxel Dörfler	fFlags(0)
10677206143SAxel Dörfler{
10777206143SAxel Dörfler}
10877206143SAxel Dörfler
10977206143SAxel Dörfler
11077206143SAxel DörflerBNetworkInterfaceAddress::~BNetworkInterfaceAddress()
11177206143SAxel Dörfler{
11277206143SAxel Dörfler}
11377206143SAxel Dörfler
11477206143SAxel Dörfler
11577206143SAxel Dörflerstatus_t
11677206143SAxel DörflerBNetworkInterfaceAddress::SetTo(const BNetworkInterface& interface, int32 index)
11777206143SAxel Dörfler{
11877206143SAxel Dörfler	fIndex = index;
11977206143SAxel Dörfler	return do_ifaliasreq(interface.Name(), B_SOCKET_GET_ALIAS, *this, true);
12077206143SAxel Dörfler}
12177206143SAxel Dörfler
12277206143SAxel Dörfler
12377206143SAxel Dörflervoid
12477206143SAxel DörflerBNetworkInterfaceAddress::SetAddress(const BNetworkAddress& address)
12577206143SAxel Dörfler{
12677206143SAxel Dörfler	fAddress = address;
12777206143SAxel Dörfler}
12877206143SAxel Dörfler
12977206143SAxel Dörfler
13077206143SAxel Dörflervoid
13177206143SAxel DörflerBNetworkInterfaceAddress::SetMask(const BNetworkAddress& mask)
13277206143SAxel Dörfler{
13377206143SAxel Dörfler	fMask = mask;
13477206143SAxel Dörfler}
13577206143SAxel Dörfler
13677206143SAxel Dörfler
13777206143SAxel Dörflervoid
13877206143SAxel DörflerBNetworkInterfaceAddress::SetBroadcast(const BNetworkAddress& broadcast)
13977206143SAxel Dörfler{
14077206143SAxel Dörfler	fBroadcast = broadcast;
14177206143SAxel Dörfler}
14277206143SAxel Dörfler
14377206143SAxel Dörfler
14477206143SAxel Dörflervoid
14577206143SAxel DörflerBNetworkInterfaceAddress::SetDestination(const BNetworkAddress& destination)
14677206143SAxel Dörfler{
14777206143SAxel Dörfler	fBroadcast = destination;
14877206143SAxel Dörfler}
14977206143SAxel Dörfler
15077206143SAxel Dörfler
15177206143SAxel Dörflervoid
15277206143SAxel DörflerBNetworkInterfaceAddress::SetFlags(uint32 flags)
15377206143SAxel Dörfler{
15477206143SAxel Dörfler	fFlags = flags;
15577206143SAxel Dörfler}
15677206143SAxel Dörfler
15777206143SAxel Dörfler
15877206143SAxel Dörfler// #pragma mark -
15977206143SAxel Dörfler
16077206143SAxel Dörfler
161c2808ea7SAxel DörflerBNetworkInterface::BNetworkInterface()
162c2808ea7SAxel Dörfler{
163c2808ea7SAxel Dörfler	Unset();
164c2808ea7SAxel Dörfler}
165c2808ea7SAxel Dörfler
166c2808ea7SAxel Dörfler
167c2808ea7SAxel DörflerBNetworkInterface::BNetworkInterface(const char* name)
168c2808ea7SAxel Dörfler{
169c2808ea7SAxel Dörfler	SetTo(name);
170c2808ea7SAxel Dörfler}
171c2808ea7SAxel Dörfler
172c2808ea7SAxel Dörfler
173c2808ea7SAxel DörflerBNetworkInterface::BNetworkInterface(uint32 index)
174c2808ea7SAxel Dörfler{
175c2808ea7SAxel Dörfler	SetTo(index);
176c2808ea7SAxel Dörfler}
177c2808ea7SAxel Dörfler
178c2808ea7SAxel Dörfler
179c2808ea7SAxel DörflerBNetworkInterface::~BNetworkInterface()
180c2808ea7SAxel Dörfler{
181c2808ea7SAxel Dörfler}
182c2808ea7SAxel Dörfler
183c2808ea7SAxel Dörfler
184c2808ea7SAxel Dörflervoid
185c2808ea7SAxel DörflerBNetworkInterface::Unset()
186c2808ea7SAxel Dörfler{
187c2808ea7SAxel Dörfler	fName[0] = '\0';
188c2808ea7SAxel Dörfler}
189c2808ea7SAxel Dörfler
190c2808ea7SAxel Dörfler
191c2808ea7SAxel Dörflervoid
192c2808ea7SAxel DörflerBNetworkInterface::SetTo(const char* name)
193c2808ea7SAxel Dörfler{
194c2808ea7SAxel Dörfler	strlcpy(fName, name, IF_NAMESIZE);
195c2808ea7SAxel Dörfler}
196c2808ea7SAxel Dörfler
197c2808ea7SAxel Dörfler
198c2808ea7SAxel Dörflerstatus_t
199c2808ea7SAxel DörflerBNetworkInterface::SetTo(uint32 index)
200c2808ea7SAxel Dörfler{
201c2808ea7SAxel Dörfler	ifreq request;
202c2808ea7SAxel Dörfler	request.ifr_index = index;
203c2808ea7SAxel Dörfler
204a690e259SAxel Dörfler	status_t status = do_request(AF_INET, request, "", SIOCGIFNAME);
205c2808ea7SAxel Dörfler	if (status != B_OK)
206c2808ea7SAxel Dörfler		return status;
207c2808ea7SAxel Dörfler
208c2808ea7SAxel Dörfler	strlcpy(fName, request.ifr_name, IF_NAMESIZE);
209c2808ea7SAxel Dörfler	return B_OK;
210c2808ea7SAxel Dörfler}
211c2808ea7SAxel Dörfler
212c2808ea7SAxel Dörfler
213c2808ea7SAxel Dörflerbool
214c2808ea7SAxel DörflerBNetworkInterface::Exists() const
215c2808ea7SAxel Dörfler{
216c2808ea7SAxel Dörfler	ifreq request;
217a690e259SAxel Dörfler	return do_request(AF_INET, request, Name(), SIOCGIFINDEX) == B_OK;
218c2808ea7SAxel Dörfler}
219c2808ea7SAxel Dörfler
220c2808ea7SAxel Dörfler
221c2808ea7SAxel Dörflerconst char*
222c2808ea7SAxel DörflerBNetworkInterface::Name() const
223c2808ea7SAxel Dörfler{
224c2808ea7SAxel Dörfler	return fName;
225c2808ea7SAxel Dörfler}
226c2808ea7SAxel Dörfler
227c2808ea7SAxel Dörfler
2282087545cSAxel Dörfleruint32
2292087545cSAxel DörflerBNetworkInterface::Index() const
2302087545cSAxel Dörfler{
2312087545cSAxel Dörfler	ifreq request;
2322087545cSAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFINDEX) != B_OK)
2332087545cSAxel Dörfler		return 0;
2342087545cSAxel Dörfler
2352087545cSAxel Dörfler	return request.ifr_index;
2362087545cSAxel Dörfler}
2372087545cSAxel Dörfler
2382087545cSAxel Dörfler
239c2808ea7SAxel Dörfleruint32
240c2808ea7SAxel DörflerBNetworkInterface::Flags() const
241c2808ea7SAxel Dörfler{
242c2808ea7SAxel Dörfler	ifreq request;
243a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFFLAGS) != B_OK)
244c2808ea7SAxel Dörfler		return 0;
245c2808ea7SAxel Dörfler
246c2808ea7SAxel Dörfler	return request.ifr_flags;
247c2808ea7SAxel Dörfler}
248c2808ea7SAxel Dörfler
249c2808ea7SAxel Dörfler
250c2808ea7SAxel Dörfleruint32
251c2808ea7SAxel DörflerBNetworkInterface::MTU() const
252c2808ea7SAxel Dörfler{
253c2808ea7SAxel Dörfler	ifreq request;
254a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFMTU) != B_OK)
255c2808ea7SAxel Dörfler		return 0;
256c2808ea7SAxel Dörfler
257c2808ea7SAxel Dörfler	return request.ifr_mtu;
258c2808ea7SAxel Dörfler}
259c2808ea7SAxel Dörfler
260c2808ea7SAxel Dörfler
26197ef73e0SAxel Dörflerint32
2629de96be3SAxel DörflerBNetworkInterface::Media() const
2639de96be3SAxel Dörfler{
264d72ede75SAxel Dörfler	ifmediareq request;
265d72ede75SAxel Dörfler	request.ifm_count = 0;
266d72ede75SAxel Dörfler	request.ifm_ulist = NULL;
267d72ede75SAxel Dörfler
268a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFMEDIA) != B_OK)
26997ef73e0SAxel Dörfler		return -1;
2709de96be3SAxel Dörfler
271d72ede75SAxel Dörfler	return request.ifm_current;
2729de96be3SAxel Dörfler}
2739de96be3SAxel Dörfler
2749de96be3SAxel Dörfler
2759de96be3SAxel Dörfleruint32
2769de96be3SAxel DörflerBNetworkInterface::Metric() const
2779de96be3SAxel Dörfler{
2789de96be3SAxel Dörfler	ifreq request;
279a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFMETRIC) != B_OK)
2809de96be3SAxel Dörfler		return 0;
2819de96be3SAxel Dörfler
2829de96be3SAxel Dörfler	return request.ifr_metric;
2839de96be3SAxel Dörfler}
2849de96be3SAxel Dörfler
2859de96be3SAxel Dörfler
286c2808ea7SAxel Dörfleruint32
287c2808ea7SAxel DörflerBNetworkInterface::Type() const
288c2808ea7SAxel Dörfler{
289c2808ea7SAxel Dörfler	ifreq request;
290a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), SIOCGIFTYPE) != B_OK)
291c2808ea7SAxel Dörfler		return 0;
292c2808ea7SAxel Dörfler
293c2808ea7SAxel Dörfler	return request.ifr_type;
294c2808ea7SAxel Dörfler}
295c2808ea7SAxel Dörfler
296c2808ea7SAxel Dörfler
297c2808ea7SAxel Dörflerstatus_t
298c2808ea7SAxel DörflerBNetworkInterface::GetStats(ifreq_stats& stats)
299c2808ea7SAxel Dörfler{
300c2808ea7SAxel Dörfler	ifreq request;
301a690e259SAxel Dörfler	status_t status = do_request(AF_INET, request, Name(), SIOCGIFSTATS);
302c2808ea7SAxel Dörfler	if (status != B_OK)
303c2808ea7SAxel Dörfler		return status;
304c2808ea7SAxel Dörfler
305c2808ea7SAxel Dörfler	memcpy(&stats, &request.ifr_stats, sizeof(ifreq_stats));
306c2808ea7SAxel Dörfler	return B_OK;
307c2808ea7SAxel Dörfler}
308c2808ea7SAxel Dörfler
309c2808ea7SAxel Dörfler
310c2808ea7SAxel Dörflerbool
311c2808ea7SAxel DörflerBNetworkInterface::HasLink() const
312c2808ea7SAxel Dörfler{
313c2808ea7SAxel Dörfler	return (Flags() & IFF_LINK) != 0;
314c2808ea7SAxel Dörfler}
315c2808ea7SAxel Dörfler
316c2808ea7SAxel Dörfler
317c2808ea7SAxel Dörflerstatus_t
318c2808ea7SAxel DörflerBNetworkInterface::SetFlags(uint32 flags)
319c2808ea7SAxel Dörfler{
320c2808ea7SAxel Dörfler	ifreq request;
321c2808ea7SAxel Dörfler	request.ifr_flags = flags;
322a690e259SAxel Dörfler	return do_request(AF_INET, request, Name(), SIOCSIFFLAGS);
323c2808ea7SAxel Dörfler}
324c2808ea7SAxel Dörfler
325c2808ea7SAxel Dörfler
326c2808ea7SAxel Dörflerstatus_t
327c2808ea7SAxel DörflerBNetworkInterface::SetMTU(uint32 mtu)
328c2808ea7SAxel Dörfler{
329c2808ea7SAxel Dörfler	ifreq request;
330c2808ea7SAxel Dörfler	request.ifr_mtu = mtu;
331a690e259SAxel Dörfler	return do_request(AF_INET, request, Name(), SIOCSIFMTU);
332c2808ea7SAxel Dörfler}
333c2808ea7SAxel Dörfler
334c2808ea7SAxel Dörfler
3359de96be3SAxel Dörflerstatus_t
33697ef73e0SAxel DörflerBNetworkInterface::SetMedia(int32 media)
3379de96be3SAxel Dörfler{
3389de96be3SAxel Dörfler	ifreq request;
3399de96be3SAxel Dörfler	request.ifr_media = media;
340a690e259SAxel Dörfler	return do_request(AF_INET, request, Name(), SIOCSIFMEDIA);
3419de96be3SAxel Dörfler}
3429de96be3SAxel Dörfler
3439de96be3SAxel Dörfler
3449de96be3SAxel Dörflerstatus_t
3459de96be3SAxel DörflerBNetworkInterface::SetMetric(uint32 metric)
3469de96be3SAxel Dörfler{
3479de96be3SAxel Dörfler	ifreq request;
3489de96be3SAxel Dörfler	request.ifr_metric = metric;
349a690e259SAxel Dörfler	return do_request(AF_INET, request, Name(), SIOCSIFMETRIC);
3509de96be3SAxel Dörfler}
3519de96be3SAxel Dörfler
3529de96be3SAxel Dörfler
353c2808ea7SAxel Dörflerint32
354c2808ea7SAxel DörflerBNetworkInterface::CountAddresses() const
355c2808ea7SAxel Dörfler{
356c2808ea7SAxel Dörfler	ifreq request;
357a690e259SAxel Dörfler	if (do_request(AF_INET, request, Name(), B_SOCKET_COUNT_ALIASES) != B_OK)
358c2808ea7SAxel Dörfler		return 0;
359c2808ea7SAxel Dörfler
360c2808ea7SAxel Dörfler	return request.ifr_count;
361c2808ea7SAxel Dörfler}
362c2808ea7SAxel Dörfler
363c2808ea7SAxel Dörfler
364c2808ea7SAxel Dörflerstatus_t
365c2808ea7SAxel DörflerBNetworkInterface::GetAddressAt(int32 index, BNetworkInterfaceAddress& address)
366c2808ea7SAxel Dörfler{
36777206143SAxel Dörfler	return address.SetTo(*this, index);
368c2808ea7SAxel Dörfler}
369c2808ea7SAxel Dörfler
370c2808ea7SAxel Dörfler
37197ef73e0SAxel Dörflerint32
37297ef73e0SAxel DörflerBNetworkInterface::FindAddress(const BNetworkAddress& address)
37397ef73e0SAxel Dörfler{
37497ef73e0SAxel Dörfler	int socket = ::socket(address.Family(), SOCK_DGRAM, 0);
37597ef73e0SAxel Dörfler	if (socket < 0)
376cf93c8c7SAxel Dörfler		return -1;
37797ef73e0SAxel Dörfler
37897ef73e0SAxel Dörfler	FileDescriptorCloser closer(socket);
37997ef73e0SAxel Dörfler
38097ef73e0SAxel Dörfler	ifaliasreq request;
38197ef73e0SAxel Dörfler	memset(&request, 0, sizeof(ifaliasreq));
38297ef73e0SAxel Dörfler
38397ef73e0SAxel Dörfler	strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
38497ef73e0SAxel Dörfler	request.ifra_index = -1;
38597ef73e0SAxel Dörfler	memcpy(&request.ifra_addr, &address.SockAddr(), address.Length());
386a690e259SAxel Dörfler
38797ef73e0SAxel Dörfler	if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
388754bbf48SJérôme Duval			< 0) {
389cf93c8c7SAxel Dörfler		return -1;
390754bbf48SJérôme Duval	}
39197ef73e0SAxel Dörfler
39297ef73e0SAxel Dörfler	return request.ifra_index;
39397ef73e0SAxel Dörfler}
39497ef73e0SAxel Dörfler
39597ef73e0SAxel Dörfler
39697ef73e0SAxel Dörflerint32
39797ef73e0SAxel DörflerBNetworkInterface::FindFirstAddress(int family)
39897ef73e0SAxel Dörfler{
39997ef73e0SAxel Dörfler	int socket = ::socket(family, SOCK_DGRAM, 0);
40097ef73e0SAxel Dörfler	if (socket < 0)
401cf93c8c7SAxel Dörfler		return -1;
40297ef73e0SAxel Dörfler
40397ef73e0SAxel Dörfler	FileDescriptorCloser closer(socket);
40497ef73e0SAxel Dörfler
40597ef73e0SAxel Dörfler	ifaliasreq request;
40697ef73e0SAxel Dörfler	memset(&request, 0, sizeof(ifaliasreq));
40797ef73e0SAxel Dörfler
40897ef73e0SAxel Dörfler	strlcpy(request.ifra_name, Name(), IF_NAMESIZE);
40997ef73e0SAxel Dörfler	request.ifra_index = -1;
4100e4bbb1bSAxel Dörfler	request.ifra_addr.ss_family = AF_UNSPEC;
411a690e259SAxel Dörfler
41297ef73e0SAxel Dörfler	if (ioctl(socket, B_SOCKET_GET_ALIAS, &request, sizeof(struct ifaliasreq))
413754bbf48SJérôme Duval			< 0) {
414cf93c8c7SAxel Dörfler		return -1;
415754bbf48SJérôme Duval	}
41697ef73e0SAxel Dörfler
41797ef73e0SAxel Dörfler	return request.ifra_index;
41897ef73e0SAxel Dörfler}
41997ef73e0SAxel Dörfler
42097ef73e0SAxel Dörfler
421c2808ea7SAxel Dörflerstatus_t
422c2808ea7SAxel DörflerBNetworkInterface::AddAddress(const BNetworkInterfaceAddress& address)
423c2808ea7SAxel Dörfler{
424c2808ea7SAxel Dörfler	return do_ifaliasreq(Name(), B_SOCKET_ADD_ALIAS, address);
425c2808ea7SAxel Dörfler}
426c2808ea7SAxel Dörfler
427c2808ea7SAxel Dörfler
42897ef73e0SAxel Dörflerstatus_t
42997ef73e0SAxel DörflerBNetworkInterface::AddAddress(const BNetworkAddress& local)
43097ef73e0SAxel Dörfler{
43197ef73e0SAxel Dörfler	BNetworkInterfaceAddress address;
43277206143SAxel Dörfler	address.SetAddress(local);
43397ef73e0SAxel Dörfler
43497ef73e0SAxel Dörfler	return do_ifaliasreq(Name(), B_SOCKET_ADD_ALIAS, address);
43597ef73e0SAxel Dörfler}
43697ef73e0SAxel Dörfler
43797ef73e0SAxel Dörfler
438c2808ea7SAxel Dörflerstatus_t
439c2808ea7SAxel DörflerBNetworkInterface::SetAddress(const BNetworkInterfaceAddress& address)
440c2808ea7SAxel Dörfler{
441c2808ea7SAxel Dörfler	return do_ifaliasreq(Name(), B_SOCKET_SET_ALIAS, address);
442c2808ea7SAxel Dörfler}
443c2808ea7SAxel Dörfler
444c2808ea7SAxel Dörfler
445c2808ea7SAxel Dörflerstatus_t
446c2808ea7SAxel DörflerBNetworkInterface::RemoveAddress(const BNetworkInterfaceAddress& address)
447c2808ea7SAxel Dörfler{
448c2808ea7SAxel Dörfler	ifreq request;
44977206143SAxel Dörfler	memcpy(&request.ifr_addr, &address.Address().SockAddr(),
45077206143SAxel Dörfler		address.Address().Length());
451c2808ea7SAxel Dörfler
452a690e259SAxel Dörfler	return do_request(family_from_interface_address(address), request, Name(),
453a690e259SAxel Dörfler		B_SOCKET_REMOVE_ALIAS);
454c2808ea7SAxel Dörfler}
455c2808ea7SAxel Dörfler
456c2808ea7SAxel Dörfler
45797ef73e0SAxel Dörflerstatus_t
45897ef73e0SAxel DörflerBNetworkInterface::RemoveAddress(const BNetworkAddress& address)
45997ef73e0SAxel Dörfler{
46097ef73e0SAxel Dörfler	ifreq request;
46197ef73e0SAxel Dörfler	memcpy(&request.ifr_addr, &address.SockAddr(), address.Length());
46297ef73e0SAxel Dörfler
463a690e259SAxel Dörfler	return do_request(address.Family(), request, Name(), B_SOCKET_REMOVE_ALIAS);
46497ef73e0SAxel Dörfler}
46597ef73e0SAxel Dörfler
46697ef73e0SAxel Dörfler
467c2808ea7SAxel Dörflerstatus_t
468c2808ea7SAxel DörflerBNetworkInterface::RemoveAddressAt(int32 index)
469c2808ea7SAxel Dörfler{
470c2808ea7SAxel Dörfler	BNetworkInterfaceAddress address;
471c2808ea7SAxel Dörfler	status_t status = GetAddressAt(index, address);
472c2808ea7SAxel Dörfler	if (status != B_OK)
473c2808ea7SAxel Dörfler		return status;
474c2808ea7SAxel Dörfler
475c2808ea7SAxel Dörfler	return RemoveAddress(address);
476c2808ea7SAxel Dörfler}
477c2808ea7SAxel Dörfler
478c2808ea7SAxel Dörfler
479c2808ea7SAxel Dörflerstatus_t
480c2808ea7SAxel DörflerBNetworkInterface::GetHardwareAddress(BNetworkAddress& address)
481c2808ea7SAxel Dörfler{
482c2808ea7SAxel Dörfler	int socket = ::socket(AF_LINK, SOCK_DGRAM, 0);
483c2808ea7SAxel Dörfler	if (socket < 0)
484c2808ea7SAxel Dörfler		return errno;
485c2808ea7SAxel Dörfler
486cb7ce9a3SAxel Dörfler	FileDescriptorCloser closer(socket);
487c2808ea7SAxel Dörfler
488c2808ea7SAxel Dörfler	ifreq request;
489c2808ea7SAxel Dörfler	strlcpy(request.ifr_name, Name(), IF_NAMESIZE);
490c2808ea7SAxel Dörfler
491c2808ea7SAxel Dörfler	if (ioctl(socket, SIOCGIFADDR, &request, sizeof(struct ifreq)) < 0)
492c2808ea7SAxel Dörfler		return errno;
493c2808ea7SAxel Dörfler
494c2808ea7SAxel Dörfler	address.SetTo(request.ifr_addr);
495c2808ea7SAxel Dörfler	return B_OK;
496c2808ea7SAxel Dörfler}
4972087545cSAxel Dörfler
4982087545cSAxel Dörfler
4992087545cSAxel Dörflerstatus_t
5003b7b927dSMichael LotzBNetworkInterface::AddRoute(const BNetworkRoute& route)
5012087545cSAxel Dörfler{
5023b7b927dSMichael Lotz	int family = route.AddressFamily();
5032087545cSAxel Dörfler	if (family == AF_UNSPEC)
5042087545cSAxel Dörfler		return B_BAD_VALUE;
5052087545cSAxel Dörfler
5062087545cSAxel Dörfler	ifreq request;
5073b7b927dSMichael Lotz	request.ifr_route = route.RouteEntry();
5082087545cSAxel Dörfler	return do_request(family, request, Name(), SIOCADDRT);
5092087545cSAxel Dörfler}
5102087545cSAxel Dörfler
5112087545cSAxel Dörfler
5122087545cSAxel Dörflerstatus_t
5132087545cSAxel DörflerBNetworkInterface::AddDefaultRoute(const BNetworkAddress& gateway)
5142087545cSAxel Dörfler{
5153b7b927dSMichael Lotz	BNetworkRoute route;
5163b7b927dSMichael Lotz	status_t result = route.SetGateway(gateway);
5173b7b927dSMichael Lotz	if (result != B_OK)
5183b7b927dSMichael Lotz		return result;
5192087545cSAxel Dörfler
5203b7b927dSMichael Lotz	route.SetFlags(RTF_STATIC | RTF_DEFAULT | RTF_GATEWAY);
5212087545cSAxel Dörfler	return AddRoute(route);
5222087545cSAxel Dörfler}
5232087545cSAxel Dörfler
5242087545cSAxel Dörfler
5252087545cSAxel Dörflerstatus_t
5263b7b927dSMichael LotzBNetworkInterface::RemoveRoute(const BNetworkRoute& route)
5272087545cSAxel Dörfler{
5283b7b927dSMichael Lotz	int family = route.AddressFamily();
5292087545cSAxel Dörfler	if (family == AF_UNSPEC)
5302087545cSAxel Dörfler		return B_BAD_VALUE;
5312087545cSAxel Dörfler
5322087545cSAxel Dörfler	return RemoveRoute(family, route);
5332087545cSAxel Dörfler}
5342087545cSAxel Dörfler
5352087545cSAxel Dörfler
5362087545cSAxel Dörflerstatus_t
5373b7b927dSMichael LotzBNetworkInterface::RemoveRoute(int family, const BNetworkRoute& route)
5382087545cSAxel Dörfler{
5392087545cSAxel Dörfler	ifreq request;
5403b7b927dSMichael Lotz	request.ifr_route = route.RouteEntry();
5412087545cSAxel Dörfler	return do_request(family, request, Name(), SIOCDELRT);
5422087545cSAxel Dörfler}
5432087545cSAxel Dörfler
5442087545cSAxel Dörfler
5452087545cSAxel Dörflerstatus_t
5462087545cSAxel DörflerBNetworkInterface::RemoveDefaultRoute(int family)
5472087545cSAxel Dörfler{
5483b7b927dSMichael Lotz	BNetworkRoute route;
5493b7b927dSMichael Lotz	route.SetFlags(RTF_STATIC | RTF_DEFAULT);
5502087545cSAxel Dörfler	return RemoveRoute(family, route);
5512087545cSAxel Dörfler}
5522087545cSAxel Dörfler
5532087545cSAxel Dörfler
554905f910eSStefano Ceccherinistatus_t
5553b7b927dSMichael LotzBNetworkInterface::GetRoutes(int family,
5563b7b927dSMichael Lotz	BObjectList<BNetworkRoute>& routes) const
557905f910eSStefano Ceccherini{
5583b7b927dSMichael Lotz	return BNetworkRoute::GetRoutes(family, Name(), routes);
559905f910eSStefano Ceccherini}
560905f910eSStefano Ceccherini
561905f910eSStefano Ceccherini
562905f910eSStefano Ceccherinistatus_t
5633b7b927dSMichael LotzBNetworkInterface::GetDefaultRoute(int family, BNetworkRoute& route) const
564905f910eSStefano Ceccherini{
5653b7b927dSMichael Lotz	return BNetworkRoute::GetDefaultRoute(family, Name(), route);
5663b7b927dSMichael Lotz}
567905f910eSStefano Ceccherini
568905f910eSStefano Ceccherini
5693b7b927dSMichael Lotzstatus_t
5703b7b927dSMichael LotzBNetworkInterface::GetDefaultGateway(int family, BNetworkAddress& gateway) const
5713b7b927dSMichael Lotz{
5723b7b927dSMichael Lotz	return BNetworkRoute::GetDefaultGateway(family, Name(), gateway);
573905f910eSStefano Ceccherini}
574905f910eSStefano Ceccherini
575905f910eSStefano Ceccherini
5762087545cSAxel Dörflerstatus_t
5772087545cSAxel DörflerBNetworkInterface::AutoConfigure(int family)
5782087545cSAxel Dörfler{
5792087545cSAxel Dörfler	BMessage message(kMsgConfigureInterface);
5802087545cSAxel Dörfler	message.AddString("device", Name());
5812087545cSAxel Dörfler
5822087545cSAxel Dörfler	BMessage address;
5832087545cSAxel Dörfler	address.AddInt32("family", family);
5842087545cSAxel Dörfler	address.AddBool("auto_config", true);
5852087545cSAxel Dörfler	message.AddMessage("address", &address);
5862087545cSAxel Dörfler
5872087545cSAxel Dörfler	BMessenger networkServer(kNetServerSignature);
5882087545cSAxel Dörfler	BMessage reply;
5892087545cSAxel Dörfler	status_t status = networkServer.SendMessage(&message, &reply);
5902087545cSAxel Dörfler	if (status == B_OK)
5912087545cSAxel Dörfler		reply.FindInt32("status", &status);
5922087545cSAxel Dörfler
5932087545cSAxel Dörfler	return status;
5942087545cSAxel Dörfler}
595