1/*
2 * Copyright 2006-2015, 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 <NetworkSettings.h>
11
12#include <netdb.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include <Directory.h>
18#include <File.h>
19#include <FindDirectory.h>
20#include <fs_interface.h>
21#include <NetworkDevice.h>
22#include <NetworkInterface.h>
23#include <Path.h>
24#include <PathMonitor.h>
25#include <String.h>
26
27#include <DriverSettingsMessageAdapter.h>
28#include <NetServer.h>
29
30
31using namespace BNetworkKit;
32
33
34static const char* kInterfaceSettingsName = "interfaces";
35static const char* kServicesSettingsName = "services";
36static const char* kNetworksSettingsName = "wireless_networks";
37
38
39// Interface templates
40
41namespace BPrivate {
42
43
44class InterfaceAddressFamilyConverter : public DriverSettingsConverter {
45public:
46	virtual	status_t			ConvertFromDriverSettings(
47									const driver_parameter& parameter,
48									const char* name, int32 index, uint32 type,
49									BMessage& target);
50	virtual	status_t			ConvertToDriverSettings(const BMessage& source,
51									const char* name, int32 index,
52									uint32 type, BString& value);
53};
54
55
56}	// namespace BPrivate
57
58using BPrivate::InterfaceAddressFamilyConverter;
59
60
61const static settings_template kInterfaceAddressTemplate[] = {
62	{B_STRING_TYPE, "family", NULL, true, new InterfaceAddressFamilyConverter},
63	{B_STRING_TYPE, "address", NULL},
64	{B_STRING_TYPE, "mask", NULL},
65	{B_STRING_TYPE, "peer", NULL},
66	{B_STRING_TYPE, "broadcast", NULL},
67	{B_STRING_TYPE, "gateway", NULL},
68	{B_BOOL_TYPE, "auto_config", NULL},
69	{0, NULL, NULL}
70};
71
72const static settings_template kInterfaceNetworkTemplate[] = {
73	{B_STRING_TYPE, "name", NULL, true},
74	{B_STRING_TYPE, "mac", NULL},
75};
76
77const static settings_template kInterfaceTemplate[] = {
78	{B_STRING_TYPE, "device", NULL, true},
79	{B_BOOL_TYPE, "disabled", NULL},
80	{B_MESSAGE_TYPE, "address", kInterfaceAddressTemplate},
81	{B_MESSAGE_TYPE, "network", kInterfaceNetworkTemplate},
82	{B_INT32_TYPE, "flags", NULL},
83	{B_INT32_TYPE, "metric", NULL},
84	{B_INT32_TYPE, "mtu", NULL},
85	{0, NULL, NULL}
86};
87
88const static settings_template kInterfacesTemplate[] = {
89	{B_MESSAGE_TYPE, "interface", kInterfaceTemplate},
90	{0, NULL, NULL}
91};
92
93// Network templates
94
95const static settings_template kNetworkTemplate[] = {
96	{B_STRING_TYPE, "name", NULL, true},
97	{B_STRING_TYPE, "mac", NULL},
98	{B_STRING_TYPE, "password", NULL},
99	{B_STRING_TYPE, "authentication", NULL},
100	{B_STRING_TYPE, "cipher", NULL},
101	{B_STRING_TYPE, "group_cipher", NULL},
102	{B_STRING_TYPE, "key", NULL},
103	{0, NULL, NULL}
104};
105
106const static settings_template kNetworksTemplate[] = {
107	{B_MESSAGE_TYPE, "network", kNetworkTemplate},
108	{0, NULL, NULL}
109};
110
111// Service templates
112
113const static settings_template kServiceAddressTemplate[] = {
114	{B_STRING_TYPE, "family", NULL, true},
115	{B_STRING_TYPE, "type", NULL},
116	{B_STRING_TYPE, "protocol", NULL},
117	{B_STRING_TYPE, "address", NULL},
118	{B_INT32_TYPE, "port", NULL},
119	{0, NULL, NULL}
120};
121
122const static settings_template kServiceTemplate[] = {
123	{B_STRING_TYPE, "name", NULL, true},
124	{B_BOOL_TYPE, "disabled", NULL},
125	{B_MESSAGE_TYPE, "address", kServiceAddressTemplate},
126	{B_STRING_TYPE, "user", NULL},
127	{B_STRING_TYPE, "group", NULL},
128	{B_STRING_TYPE, "launch", NULL},
129	{B_STRING_TYPE, "family", NULL},
130	{B_STRING_TYPE, "type", NULL},
131	{B_STRING_TYPE, "protocol", NULL},
132	{B_INT32_TYPE, "port", NULL},
133	{B_BOOL_TYPE, "stand_alone", NULL},
134	{0, NULL, NULL}
135};
136
137const static settings_template kServicesTemplate[] = {
138	{B_MESSAGE_TYPE, "service", kServiceTemplate},
139	{0, NULL, NULL}
140};
141
142
143struct address_family {
144	int			family;
145	const char*	name;
146	const char*	identifiers[4];
147};
148
149
150static const address_family kFamilies[] = {
151	{
152		AF_INET,
153		"inet",
154		{"AF_INET", "inet", "ipv4", NULL},
155	},
156	{
157		AF_INET6,
158		"inet6",
159		{"AF_INET6", "inet6", "ipv6", NULL},
160	},
161	{ -1, NULL, {NULL} }
162};
163
164
165static const char*
166get_family_name(int family)
167{
168	for (int32 i = 0; kFamilies[i].family >= 0; i++) {
169		if (kFamilies[i].family == family)
170			return kFamilies[i].name;
171	}
172	return NULL;
173}
174
175
176static int
177get_address_family(const char* argument)
178{
179	for (int32 i = 0; kFamilies[i].family >= 0; i++) {
180		for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
181			if (!strcmp(argument, kFamilies[i].identifiers[j])) {
182				// found a match
183				return kFamilies[i].family;
184			}
185		}
186	}
187
188	return AF_UNSPEC;
189}
190
191
192/*!	Parses the \a argument as network \a address for the specified \a family.
193	If \a family is \c AF_UNSPEC, \a family will be overwritten with the family
194	of the successfully parsed address.
195*/
196static bool
197parse_address(int32& family, const char* argument, BNetworkAddress& address)
198{
199	if (argument == NULL) {
200		if (family != AF_UNSPEC)
201			address.SetToWildcard(family);
202		return false;
203	}
204
205	status_t status = address.SetTo(family, argument, (uint16)0,
206		B_NO_ADDRESS_RESOLUTION);
207	if (status != B_OK)
208		return false;
209
210	if (family == AF_UNSPEC) {
211		// Test if we support the resulting address family
212		bool supported = false;
213
214		for (int32 i = 0; kFamilies[i].family >= 0; i++) {
215			if (kFamilies[i].family == address.Family()) {
216				supported = true;
217				break;
218			}
219		}
220		if (!supported)
221			return false;
222
223		// Take over family from address
224		family = address.Family();
225	}
226
227	return true;
228}
229
230
231static int
232parse_type(const char* string)
233{
234	if (!strcasecmp(string, "stream"))
235		return SOCK_STREAM;
236
237	return SOCK_DGRAM;
238}
239
240
241static int
242parse_protocol(const char* string)
243{
244	struct protoent* proto = getprotobyname(string);
245	if (proto == NULL)
246		return IPPROTO_TCP;
247
248	return proto->p_proto;
249}
250
251
252static int
253type_for_protocol(int protocol)
254{
255	// default determined by protocol
256	switch (protocol) {
257		case IPPROTO_TCP:
258			return SOCK_STREAM;
259
260		case IPPROTO_UDP:
261		default:
262			return SOCK_DGRAM;
263	}
264}
265
266
267// #pragma mark -
268
269
270status_t
271InterfaceAddressFamilyConverter::ConvertFromDriverSettings(
272	const driver_parameter& parameter, const char* name, int32 index,
273	uint32 type, BMessage& target)
274{
275	return B_NOT_SUPPORTED;
276}
277
278
279status_t
280InterfaceAddressFamilyConverter::ConvertToDriverSettings(const BMessage& source,
281	const char* name, int32 index, uint32 type, BString& value)
282{
283	int32 family;
284	if (source.FindInt32("family", &family) == B_OK) {
285		const char* familyName = get_family_name(family);
286		if (familyName != NULL)
287			value << familyName;
288		else
289			value << family;
290
291		return B_OK;
292	}
293
294	return B_NOT_SUPPORTED;
295}
296
297
298// #pragma mark -
299
300
301BNetworkSettings::BNetworkSettings()
302{
303	_Load();
304}
305
306
307BNetworkSettings::~BNetworkSettings()
308{
309}
310
311
312status_t
313BNetworkSettings::GetNextInterface(uint32& cookie, BMessage& interface)
314{
315	status_t status = fInterfaces.FindMessage("interface", cookie, &interface);
316	if (status != B_OK)
317		return status;
318
319	cookie++;
320	return B_OK;
321}
322
323
324status_t
325BNetworkSettings::GetInterface(const char* name, BMessage& interface) const
326{
327	int32 index;
328	return _GetItem(fInterfaces, "interface", "device", name, index, interface);
329}
330
331
332status_t
333BNetworkSettings::AddInterface(const BMessage& interface)
334{
335	const char* name = NULL;
336	if (interface.FindString("device", &name) != B_OK)
337		return B_BAD_VALUE;
338
339	_RemoveItem(fInterfaces, "interface", "device", name);
340
341	status_t result = fInterfaces.AddMessage("interface", &interface);
342	if (result != B_OK)
343		return result;
344
345	return _Save(kInterfaceSettingsName);
346}
347
348
349status_t
350BNetworkSettings::RemoveInterface(const char* name)
351{
352	return _RemoveItem(fInterfaces, "interface", "device", name,
353		kInterfaceSettingsName);
354}
355
356
357BNetworkInterfaceSettings
358BNetworkSettings::Interface(const char* name)
359{
360	BMessage interface;
361	GetInterface(name, interface);
362	return BNetworkInterfaceSettings(interface);
363}
364
365
366const BNetworkInterfaceSettings
367BNetworkSettings::Interface(const char* name) const
368{
369	BMessage interface;
370	GetInterface(name, interface);
371	return BNetworkInterfaceSettings(interface);
372}
373
374
375int32
376BNetworkSettings::CountNetworks() const
377{
378	int32 count = 0;
379	if (fNetworks.GetInfo("network", NULL, &count) != B_OK)
380		return 0;
381
382	return count;
383}
384
385
386status_t
387BNetworkSettings::GetNextNetwork(uint32& cookie, BMessage& network) const
388{
389	status_t status = fNetworks.FindMessage("network", cookie, &network);
390	if (status != B_OK)
391		return status;
392
393	cookie++;
394	return B_OK;
395}
396
397
398status_t
399BNetworkSettings::GetNetwork(const char* name, BMessage& network) const
400{
401	int32 index;
402	return _GetItem(fNetworks, "network", "name", name, index, network);
403}
404
405
406status_t
407BNetworkSettings::AddNetwork(const BMessage& network)
408{
409	const char* name = NULL;
410	if (network.FindString("name", &name) != B_OK)
411		return B_BAD_VALUE;
412
413	_RemoveItem(fNetworks, "network", "name", name);
414
415	status_t result = fNetworks.AddMessage("network", &network);
416	if (result != B_OK)
417		return result;
418
419	return _Save(kNetworksSettingsName);
420}
421
422
423status_t
424BNetworkSettings::RemoveNetwork(const char* name)
425{
426	return _RemoveItem(fNetworks, "network", "name", name,
427		kNetworksSettingsName);
428}
429
430
431const BMessage&
432BNetworkSettings::Services() const
433{
434	return fServices;
435}
436
437
438status_t
439BNetworkSettings::GetNextService(uint32& cookie, BMessage& service)
440{
441	status_t status = fServices.FindMessage("service", cookie, &service);
442	if (status != B_OK)
443		return status;
444
445	cookie++;
446	return B_OK;
447}
448
449
450status_t
451BNetworkSettings::GetService(const char* name, BMessage& service) const
452{
453	int32 index;
454	return _GetItem(fServices, "service", "name", name, index, service);
455}
456
457
458status_t
459BNetworkSettings::AddService(const BMessage& service)
460{
461	const char* name = service.GetString("name");
462	if (name == NULL)
463		return B_BAD_VALUE;
464
465	_RemoveItem(fServices, "service", "name", name);
466
467	status_t result = fServices.AddMessage("service", &service);
468	if (result != B_OK)
469		return result;
470
471	return _Save(kServicesSettingsName);
472}
473
474
475status_t
476BNetworkSettings::RemoveService(const char* name)
477{
478	return _RemoveItem(fServices, "service", "name", name,
479		kServicesSettingsName);
480}
481
482
483BNetworkServiceSettings
484BNetworkSettings::Service(const char* name)
485{
486	BMessage service;
487	GetService(name, service);
488	return BNetworkServiceSettings(service);
489}
490
491
492const BNetworkServiceSettings
493BNetworkSettings::Service(const char* name) const
494{
495	BMessage service;
496	GetService(name, service);
497	return BNetworkServiceSettings(service);
498}
499
500
501status_t
502BNetworkSettings::StartMonitoring(const BMessenger& target)
503{
504	if (_IsWatching(target))
505		return B_OK;
506	if (_IsWatching())
507		StopMonitoring(fListener);
508
509	fListener = target;
510
511	status_t status = _StartWatching(kInterfaceSettingsName, target);
512	if (status == B_OK)
513		status = _StartWatching(kNetworksSettingsName, target);
514	if (status == B_OK)
515		status = _StartWatching(kServicesSettingsName, target);
516
517	return status;
518}
519
520
521status_t
522BNetworkSettings::StopMonitoring(const BMessenger& target)
523{
524	// TODO: this needs to be changed in case the server will watch
525	//	anything else but settings
526	return BPrivate::BPathMonitor::StopWatching(target);
527}
528
529
530status_t
531BNetworkSettings::Update(BMessage* message)
532{
533	const char* pathName;
534	int32 opcode;
535	if (message->FindInt32("opcode", &opcode) != B_OK
536		|| message->FindString("path", &pathName) != B_OK)
537		return B_BAD_VALUE;
538
539	BPath settingsFolderPath;
540	_GetPath(NULL, settingsFolderPath);
541	if (strncmp(pathName, settingsFolderPath.Path(),
542			strlen(settingsFolderPath.Path()))) {
543		return B_NAME_NOT_FOUND;
544	}
545
546	if (message->FindBool("removed")) {
547		// for now, we only consider existing settings files
548		// (ie. deleting "services" won't stop any)
549		return B_OK;
550	}
551
552	int32 fields;
553	if (opcode == B_STAT_CHANGED
554		&& message->FindInt32("fields", &fields) == B_OK
555		&& (fields & (B_STAT_MODIFICATION_TIME | B_STAT_SIZE)) == 0) {
556		// only update when the modified time or size has changed
557		return B_OK;
558	}
559
560	BPath path(pathName);
561	uint32 type;
562	if (_Load(path.Leaf(), &type) == B_OK) {
563		BMessage update(type);
564		fListener.SendMessage(&update);
565	}
566
567	return B_OK;
568}
569
570
571// #pragma mark - private
572
573
574status_t
575BNetworkSettings::_Load(const char* name, uint32* _type)
576{
577	BPath path;
578	status_t status = _GetPath(NULL, path);
579	if (status != B_OK)
580		return status;
581
582	DriverSettingsMessageAdapter adapter;
583	status = B_ENTRY_NOT_FOUND;
584
585	if (name == NULL || strcmp(name, kInterfaceSettingsName) == 0) {
586		status = adapter.ConvertFromDriverSettings(
587			_Path(path, kInterfaceSettingsName).Path(), kInterfacesTemplate,
588			fInterfaces);
589		if (status == B_OK && _type != NULL)
590			*_type = kMsgInterfaceSettingsUpdated;
591	}
592	if (name == NULL || strcmp(name, kNetworksSettingsName) == 0) {
593		status = adapter.ConvertFromDriverSettings(
594			_Path(path, kNetworksSettingsName).Path(),
595			kNetworksTemplate, fNetworks);
596		if (status == B_OK) {
597			// Convert settings for simpler consumption
598			BMessage network;
599			for (int32 index = 0; fNetworks.FindMessage("network", index,
600					&network); index++) {
601				if (_ConvertNetworkFromSettings(network) == B_OK)
602					fNetworks.ReplaceMessage("network", index, &network);
603			}
604
605			if (_type != NULL)
606				*_type = kMsgNetworkSettingsUpdated;
607		}
608	}
609	if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
610		status = adapter.ConvertFromDriverSettings(
611			_Path(path, kServicesSettingsName).Path(), kServicesTemplate,
612			fServices);
613		if (status == B_OK && _type != NULL)
614			*_type = kMsgServiceSettingsUpdated;
615	}
616
617	return status;
618}
619
620
621status_t
622BNetworkSettings::_Save(const char* name)
623{
624	BPath path;
625	status_t status = _GetPath(NULL, path);
626	if (status != B_OK)
627		return status;
628
629	DriverSettingsMessageAdapter adapter;
630	status = B_ENTRY_NOT_FOUND;
631
632	if (name == NULL || strcmp(name, kInterfaceSettingsName) == 0) {
633		status = adapter.ConvertToDriverSettings(
634			_Path(path, kInterfaceSettingsName).Path(),
635			kInterfacesTemplate, fInterfaces);
636	}
637	if (name == NULL || strcmp(name, kNetworksSettingsName) == 0) {
638		// Convert settings to storage format
639		BMessage networks = fNetworks;
640		BMessage network;
641		for (int32 index = 0; networks.FindMessage("network", index,
642				&network); index++) {
643			if (_ConvertNetworkToSettings(network) == B_OK)
644				networks.ReplaceMessage("network", index, &network);
645		}
646
647		status = adapter.ConvertToDriverSettings(
648			_Path(path, kNetworksSettingsName).Path(),
649			kNetworksTemplate, networks);
650	}
651	if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
652		status = adapter.ConvertToDriverSettings(
653			_Path(path, kServicesSettingsName).Path(),
654			kServicesTemplate, fServices);
655	}
656
657	return status;
658}
659
660
661BPath
662BNetworkSettings::_Path(BPath& parent, const char* leaf)
663{
664	return BPath(parent.Path(), leaf);
665}
666
667
668status_t
669BNetworkSettings::_GetPath(const char* name, BPath& path)
670{
671	if (find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path, true) != B_OK)
672		return B_ERROR;
673
674	path.Append("network");
675	create_directory(path.Path(), 0755);
676
677	if (name != NULL)
678		path.Append(name);
679	return B_OK;
680}
681
682
683status_t
684BNetworkSettings::_StartWatching(const char* name, const BMessenger& target)
685{
686	BPath path;
687	status_t status = _GetPath(name, path);
688	if (status != B_OK)
689		return status;
690
691	return BPrivate::BPathMonitor::StartWatching(path.Path(), B_WATCH_STAT,
692		target);
693}
694
695
696status_t
697BNetworkSettings::_ConvertNetworkToSettings(BMessage& message)
698{
699	BNetworkAddress address;
700	status_t result = message.FindFlat("address", &address);
701	if (result == B_OK)
702		message.RemoveName("address");
703
704	if (result == B_OK && address.Family() == AF_LINK) {
705		size_t addressLength = address.LinkLevelAddressLength();
706		uint8* macAddress = address.LinkLevelAddress();
707		bool usable = false;
708		BString formatted;
709
710		for (size_t index = 0; index < addressLength; index++) {
711			if (index > 0)
712				formatted.Append(":");
713			char buffer[3];
714			snprintf(buffer, sizeof(buffer), "%2x", macAddress[index]);
715			formatted.Append(buffer, sizeof(buffer));
716
717			if (macAddress[index] != 0)
718				usable = true;
719		}
720
721		if (usable)
722			message.AddString("mac", formatted);
723	}
724
725	uint32 authentication = 0;
726	result = message.FindUInt32("authentication_mode", &authentication);
727	if (result == B_OK) {
728		message.RemoveName("authentication_mode");
729
730		const char* authenticationString = NULL;
731		switch (authentication) {
732			case B_NETWORK_AUTHENTICATION_NONE:
733				authenticationString = "none";
734				break;
735			case B_NETWORK_AUTHENTICATION_WEP:
736				authenticationString = "wep";
737				break;
738			case B_NETWORK_AUTHENTICATION_WPA:
739				authenticationString = "wpa";
740				break;
741			case B_NETWORK_AUTHENTICATION_WPA2:
742				authenticationString = "wpa2";
743				break;
744		}
745
746		if (result == B_OK && authenticationString != NULL)
747			message.AddString("authentication", authenticationString);
748	}
749
750	uint32 cipher = 0;
751	result = message.FindUInt32("cipher", &cipher);
752	if (result == B_OK) {
753		message.RemoveName("cipher");
754
755		if ((cipher & B_NETWORK_CIPHER_NONE) != 0)
756			message.AddString("cipher", "none");
757		if ((cipher & B_NETWORK_CIPHER_TKIP) != 0)
758			message.AddString("cipher", "tkip");
759		if ((cipher & B_NETWORK_CIPHER_CCMP) != 0)
760			message.AddString("cipher", "ccmp");
761	}
762
763	uint32 groupCipher = 0;
764	result = message.FindUInt32("group_cipher", &groupCipher);
765	if (result == B_OK) {
766		message.RemoveName("group_cipher");
767
768		if ((groupCipher & B_NETWORK_CIPHER_NONE) != 0)
769			message.AddString("group_cipher", "none");
770		if ((groupCipher & B_NETWORK_CIPHER_WEP_40) != 0)
771			message.AddString("group_cipher", "wep40");
772		if ((groupCipher & B_NETWORK_CIPHER_WEP_104) != 0)
773			message.AddString("group_cipher", "wep104");
774		if ((groupCipher & B_NETWORK_CIPHER_TKIP) != 0)
775			message.AddString("group_cipher", "tkip");
776		if ((groupCipher & B_NETWORK_CIPHER_CCMP) != 0)
777			message.AddString("group_cipher", "ccmp");
778	}
779
780	// TODO: the other fields aren't currently used, add them when they are
781	// and when it's clear how they will be stored
782	message.RemoveName("noise_level");
783	message.RemoveName("signal_strength");
784	message.RemoveName("flags");
785	message.RemoveName("key_mode");
786
787	return B_OK;
788}
789
790
791status_t
792BNetworkSettings::_ConvertNetworkFromSettings(BMessage& message)
793{
794	message.RemoveName("mac");
795		// TODO: convert into a flat BNetworkAddress "address"
796
797	const char* authentication = NULL;
798	if (message.FindString("authentication", &authentication) == B_OK) {
799		message.RemoveName("authentication");
800
801		if (strcasecmp(authentication, "none") == 0) {
802			message.AddUInt32("authentication_mode",
803				B_NETWORK_AUTHENTICATION_NONE);
804		} else if (strcasecmp(authentication, "wep") == 0) {
805			message.AddUInt32("authentication_mode",
806				B_NETWORK_AUTHENTICATION_WEP);
807		} else if (strcasecmp(authentication, "wpa") == 0) {
808			message.AddUInt32("authentication_mode",
809				B_NETWORK_AUTHENTICATION_WPA);
810		} else if (strcasecmp(authentication, "wpa2") == 0) {
811			message.AddUInt32("authentication_mode",
812				B_NETWORK_AUTHENTICATION_WPA2);
813		}
814	}
815
816	int32 index = 0;
817	uint32 cipher = 0;
818	const char* cipherString = NULL;
819	while (message.FindString("cipher", index++, &cipherString) == B_OK) {
820		if (strcasecmp(cipherString, "none") == 0)
821			cipher |= B_NETWORK_CIPHER_NONE;
822		else if (strcasecmp(cipherString, "tkip") == 0)
823			cipher |= B_NETWORK_CIPHER_TKIP;
824		else if (strcasecmp(cipherString, "ccmp") == 0)
825			cipher |= B_NETWORK_CIPHER_CCMP;
826	}
827
828	message.RemoveName("cipher");
829	if (cipher != 0)
830		message.AddUInt32("cipher", cipher);
831
832	index = 0;
833	cipher = 0;
834	while (message.FindString("group_cipher", index++, &cipherString) == B_OK) {
835		if (strcasecmp(cipherString, "none") == 0)
836			cipher |= B_NETWORK_CIPHER_NONE;
837		else if (strcasecmp(cipherString, "wep40") == 0)
838			cipher |= B_NETWORK_CIPHER_WEP_40;
839		else if (strcasecmp(cipherString, "wep104") == 0)
840			cipher |= B_NETWORK_CIPHER_WEP_104;
841		else if (strcasecmp(cipherString, "tkip") == 0)
842			cipher |= B_NETWORK_CIPHER_TKIP;
843		else if (strcasecmp(cipherString, "ccmp") == 0)
844			cipher |= B_NETWORK_CIPHER_CCMP;
845	}
846
847	message.RemoveName("group_cipher");
848	if (cipher != 0)
849		message.AddUInt32("group_cipher", cipher);
850
851	message.AddUInt32("flags", B_NETWORK_IS_PERSISTENT);
852
853	// TODO: add the other fields
854	message.RemoveName("key");
855	return B_OK;
856}
857
858
859status_t
860BNetworkSettings::_GetItem(const BMessage& container, const char* itemField,
861	const char* nameField, const char* name, int32& _index,
862	BMessage& item) const
863{
864	int32 index = 0;
865	while (container.FindMessage(itemField, index, &item) == B_OK) {
866		const char* itemName = NULL;
867		if (item.FindString(nameField, &itemName) == B_OK
868			&& strcmp(itemName, name) == 0) {
869			_index = index;
870			return B_OK;
871		}
872
873		index++;
874	}
875
876	return B_ENTRY_NOT_FOUND;
877}
878
879
880status_t
881BNetworkSettings::_RemoveItem(BMessage& container, const char* itemField,
882	const char* nameField, const char* name, const char* store)
883{
884	BMessage item;
885	int32 index;
886	if (_GetItem(container, itemField, nameField, name, index, item) == B_OK) {
887		container.RemoveData(itemField, index);
888		if (store != NULL)
889			return _Save(store);
890		return B_OK;
891	}
892
893	return B_ENTRY_NOT_FOUND;
894}
895
896
897// #pragma mark - BNetworkInterfaceAddressSettings
898
899
900BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings()
901	:
902	fFamily(AF_UNSPEC),
903	fAutoConfigure(true)
904{
905}
906
907
908BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
909	const BMessage& data)
910{
911	if (data.FindInt32("family", &fFamily) != B_OK) {
912		const char* familyString;
913		if (data.FindString("family", &familyString) == B_OK) {
914			fFamily = get_address_family(familyString);
915			if (fFamily == AF_UNSPEC) {
916				// we don't support this family
917				fprintf(stderr, "Ignore unknown family: %s\n",
918					familyString);
919				return;
920			}
921		} else
922			fFamily = AF_UNSPEC;
923	}
924
925	fAutoConfigure = data.GetBool("auto_config", false);
926
927	if (!fAutoConfigure) {
928		if (parse_address(fFamily, data.GetString("address", NULL), fAddress))
929			parse_address(fFamily, data.GetString("mask", NULL), fMask);
930
931		parse_address(fFamily, data.GetString("peer", NULL), fPeer);
932		parse_address(fFamily, data.GetString("broadcast", NULL), fBroadcast);
933		parse_address(fFamily, data.GetString("gateway", NULL), fGateway);
934	}
935}
936
937
938BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
939	const BNetworkInterfaceAddressSettings& other)
940	:
941	fFamily(other.fFamily),
942	fAutoConfigure(other.fAutoConfigure),
943	fAddress(other.fAddress),
944	fMask(other.fMask),
945	fPeer(other.fPeer),
946	fBroadcast(other.fBroadcast),
947	fGateway(other.fGateway)
948{
949}
950
951
952BNetworkInterfaceAddressSettings::~BNetworkInterfaceAddressSettings()
953{
954}
955
956
957int
958BNetworkInterfaceAddressSettings::Family() const
959{
960	return fFamily;
961}
962
963
964void
965BNetworkInterfaceAddressSettings::SetFamily(int family)
966{
967	fFamily = family;
968}
969
970
971bool
972BNetworkInterfaceAddressSettings::IsAutoConfigure() const
973{
974	return fAutoConfigure;
975}
976
977
978void
979BNetworkInterfaceAddressSettings::SetAutoConfigure(bool configure)
980{
981	fAutoConfigure = configure;
982}
983
984
985const BNetworkAddress&
986BNetworkInterfaceAddressSettings::Address() const
987{
988	return fAddress;
989}
990
991
992BNetworkAddress&
993BNetworkInterfaceAddressSettings::Address()
994{
995	return fAddress;
996}
997
998
999const BNetworkAddress&
1000BNetworkInterfaceAddressSettings::Mask() const
1001{
1002	return fMask;
1003}
1004
1005
1006BNetworkAddress&
1007BNetworkInterfaceAddressSettings::Mask()
1008{
1009	return fMask;
1010}
1011
1012
1013const BNetworkAddress&
1014BNetworkInterfaceAddressSettings::Peer() const
1015{
1016	return fPeer;
1017}
1018
1019
1020BNetworkAddress&
1021BNetworkInterfaceAddressSettings::Peer()
1022{
1023	return fPeer;
1024}
1025
1026
1027const BNetworkAddress&
1028BNetworkInterfaceAddressSettings::Broadcast() const
1029{
1030	return fBroadcast;
1031}
1032
1033
1034BNetworkAddress&
1035BNetworkInterfaceAddressSettings::Broadcast()
1036{
1037	return fBroadcast;
1038}
1039
1040
1041const BNetworkAddress&
1042BNetworkInterfaceAddressSettings::Gateway() const
1043{
1044	return fGateway;
1045}
1046
1047
1048BNetworkAddress&
1049BNetworkInterfaceAddressSettings::Gateway()
1050{
1051	return fGateway;
1052}
1053
1054
1055status_t
1056BNetworkInterfaceAddressSettings::GetMessage(BMessage& data) const
1057{
1058	status_t status = B_OK;
1059	if (fFamily != AF_UNSPEC)
1060		status = data.SetInt32("family", fFamily);
1061	if (status == B_OK && fAutoConfigure)
1062		return data.SetBool("auto_config", fAutoConfigure);
1063
1064	if (status == B_OK && !fAddress.IsEmpty()) {
1065		status = data.SetString("address", fAddress.ToString());
1066		if (status == B_OK && !fMask.IsEmpty())
1067			status = data.SetString("mask", fMask.ToString());
1068	}
1069	if (status == B_OK && !fPeer.IsEmpty())
1070		status = data.SetString("peer", fPeer.ToString());
1071	if (status == B_OK && !fBroadcast.IsEmpty())
1072		status = data.SetString("broadcast", fBroadcast.ToString());
1073	if (status == B_OK && !fGateway.IsEmpty())
1074		status = data.SetString("gateway", fGateway.ToString());
1075
1076	return status;
1077}
1078
1079
1080BNetworkInterfaceAddressSettings&
1081BNetworkInterfaceAddressSettings::operator=(
1082	const BNetworkInterfaceAddressSettings& other)
1083{
1084	fFamily = other.fFamily;
1085	fAutoConfigure = other.fAutoConfigure;
1086	fAddress = other.fAddress;
1087	fMask = other.fMask;
1088	fPeer = other.fPeer;
1089	fBroadcast = other.fBroadcast;
1090	fGateway = other.fGateway;
1091
1092	return *this;
1093}
1094
1095
1096// #pragma mark - BNetworkInterfaceSettings
1097
1098
1099BNetworkInterfaceSettings::BNetworkInterfaceSettings()
1100	:
1101	fFlags(0),
1102	fMTU(0),
1103	fMetric(0)
1104{
1105}
1106
1107
1108BNetworkInterfaceSettings::BNetworkInterfaceSettings(const BMessage& message)
1109{
1110	fName = message.GetString("device");
1111	fFlags = message.GetInt32("flags", 0);
1112	fMTU = message.GetInt32("mtu", 0);
1113	fMetric = message.GetInt32("metric", 0);
1114
1115	BMessage addressData;
1116	for (int32 index = 0; message.FindMessage("address", index,
1117			&addressData) == B_OK; index++) {
1118		BNetworkInterfaceAddressSettings address(addressData);
1119		fAddresses.push_back(address);
1120	}
1121}
1122
1123
1124BNetworkInterfaceSettings::~BNetworkInterfaceSettings()
1125{
1126}
1127
1128
1129const char*
1130BNetworkInterfaceSettings::Name() const
1131{
1132	return fName;
1133}
1134
1135
1136void
1137BNetworkInterfaceSettings::SetName(const char* name)
1138{
1139	fName = name;
1140}
1141
1142
1143int32
1144BNetworkInterfaceSettings::Flags() const
1145{
1146	return fFlags;
1147}
1148
1149
1150void
1151BNetworkInterfaceSettings::SetFlags(int32 flags)
1152{
1153	fFlags = flags;
1154}
1155
1156
1157int32
1158BNetworkInterfaceSettings::MTU() const
1159{
1160	return fMTU;
1161}
1162
1163
1164void
1165BNetworkInterfaceSettings::SetMTU(int32 mtu)
1166{
1167	fMTU = mtu;
1168}
1169
1170
1171int32
1172BNetworkInterfaceSettings::Metric() const
1173{
1174	return fMetric;
1175}
1176
1177
1178void
1179BNetworkInterfaceSettings::SetMetric(int32 metric)
1180{
1181	fMetric = metric;
1182}
1183
1184
1185int32
1186BNetworkInterfaceSettings::CountAddresses() const
1187{
1188	return fAddresses.size();
1189}
1190
1191
1192const BNetworkInterfaceAddressSettings&
1193BNetworkInterfaceSettings::AddressAt(int32 index) const
1194{
1195	return fAddresses[index];
1196}
1197
1198
1199BNetworkInterfaceAddressSettings&
1200BNetworkInterfaceSettings::AddressAt(int32 index)
1201{
1202	return fAddresses[index];
1203}
1204
1205
1206int32
1207BNetworkInterfaceSettings::FindFirstAddress(int family) const
1208{
1209	for (int32 index = 0; index < CountAddresses(); index++) {
1210		const BNetworkInterfaceAddressSettings address = AddressAt(index);
1211		if (address.Family() == family)
1212			return index;
1213	}
1214	return -1;
1215}
1216
1217
1218void
1219BNetworkInterfaceSettings::AddAddress(
1220	const BNetworkInterfaceAddressSettings& address)
1221{
1222	fAddresses.push_back(address);
1223}
1224
1225
1226void
1227BNetworkInterfaceSettings::RemoveAddress(int32 index)
1228{
1229	fAddresses.erase(fAddresses.begin() + index);
1230}
1231
1232
1233/*!	This is a convenience method that returns the current state of the
1234	interface, not just the one configured.
1235
1236	This means, even if the settings say: auto configured, this method
1237	may still return false, if the configuration has been manually tempered
1238	with.
1239*/
1240bool
1241BNetworkInterfaceSettings::IsAutoConfigure(int family) const
1242{
1243	BNetworkInterface interface(fName);
1244	// TODO: this needs to happen at protocol level
1245	if ((interface.Flags() & (IFF_AUTO_CONFIGURED | IFF_CONFIGURING)) != 0)
1246		return true;
1247
1248	BNetworkInterfaceAddress address;
1249	status_t status = B_ERROR;
1250
1251	int32 index = interface.FindFirstAddress(family);
1252	if (index >= 0)
1253		status = interface.GetAddressAt(index, address);
1254	if (index < 0 || status != B_OK || address.Address().IsEmpty()) {
1255		if (status == B_OK) {
1256			// Check persistent settings for the mode -- the address
1257			// can also be empty if the automatic configuration hasn't
1258			// started yet (for example, because there is no link).
1259			int32 index = FindFirstAddress(family);
1260			if (index < 0)
1261				index = FindFirstAddress(AF_UNSPEC);
1262			if (index >= 0) {
1263				const BNetworkInterfaceAddressSettings& address
1264					= AddressAt(index);
1265				return address.IsAutoConfigure();
1266			}
1267		}
1268	}
1269
1270	return false;
1271}
1272
1273
1274status_t
1275BNetworkInterfaceSettings::GetMessage(BMessage& data) const
1276{
1277	status_t status = data.SetString("device", fName);
1278	if (status == B_OK && fFlags != 0)
1279		status = data.SetInt32("flags", fFlags);
1280	if (status == B_OK && fMTU != 0)
1281		status = data.SetInt32("mtu", fMTU);
1282	if (status == B_OK && fMetric != 0)
1283		status = data.SetInt32("metric", fMetric);
1284
1285	for (int32 i = 0; i < CountAddresses(); i++) {
1286		BMessage address;
1287		status = AddressAt(i).GetMessage(address);
1288		if (status == B_OK)
1289			status = data.AddMessage("address", &address);
1290		if (status != B_OK)
1291			break;
1292	}
1293	return status;
1294}
1295
1296
1297// #pragma mark - BNetworkServiceAddressSettings
1298
1299
1300BNetworkServiceAddressSettings::BNetworkServiceAddressSettings()
1301{
1302}
1303
1304
1305BNetworkServiceAddressSettings::BNetworkServiceAddressSettings(
1306	const BMessage& data, int serviceFamily, int serviceType,
1307	int serviceProtocol, int servicePort)
1308{
1309	// TODO: dump problems in the settings to syslog
1310	if (data.FindInt32("family", &fFamily) != B_OK) {
1311		const char* familyString;
1312		if (data.FindString("family", &familyString) == B_OK) {
1313			fFamily = get_address_family(familyString);
1314			if (fFamily == AF_UNSPEC) {
1315				// we don't support this family
1316				fprintf(stderr, "Ignore unknown family: %s\n",
1317					familyString);
1318				return;
1319			}
1320		} else
1321			fFamily = serviceFamily;
1322	}
1323
1324	if (!parse_address(fFamily, data.GetString("address"), fAddress))
1325		fAddress.SetToWildcard(fFamily);
1326
1327	const char* string;
1328	if (data.FindString("protocol", &string) == B_OK)
1329		fProtocol = parse_protocol(string);
1330	else
1331		fProtocol = serviceProtocol;
1332
1333	if (data.FindString("type", &string) == B_OK)
1334		fType = parse_type(string);
1335	else if (fProtocol != serviceProtocol)
1336		fType = type_for_protocol(fProtocol);
1337	else
1338		fType = serviceType;
1339
1340	fAddress.SetPort(data.GetInt32("port", servicePort));
1341}
1342
1343
1344BNetworkServiceAddressSettings::~BNetworkServiceAddressSettings()
1345{
1346}
1347
1348
1349int
1350BNetworkServiceAddressSettings::Family() const
1351{
1352	return fFamily;
1353}
1354
1355
1356void
1357BNetworkServiceAddressSettings::SetFamily(int family)
1358{
1359	fFamily = family;
1360}
1361
1362
1363int
1364BNetworkServiceAddressSettings::Protocol() const
1365{
1366	return fProtocol;
1367}
1368
1369
1370void
1371BNetworkServiceAddressSettings::SetProtocol(int protocol)
1372{
1373	fProtocol = protocol;
1374}
1375
1376
1377int
1378BNetworkServiceAddressSettings::Type() const
1379{
1380	return fType;
1381}
1382
1383
1384void
1385BNetworkServiceAddressSettings::SetType(int type)
1386{
1387	fType = type;
1388}
1389
1390
1391const BNetworkAddress&
1392BNetworkServiceAddressSettings::Address() const
1393{
1394	return fAddress;
1395}
1396
1397
1398BNetworkAddress&
1399BNetworkServiceAddressSettings::Address()
1400{
1401	return fAddress;
1402}
1403
1404
1405status_t
1406BNetworkServiceAddressSettings::GetMessage(BMessage& data) const
1407{
1408	// TODO!
1409	return B_NOT_SUPPORTED;
1410}
1411
1412
1413bool
1414BNetworkServiceAddressSettings::operator==(
1415	const BNetworkServiceAddressSettings& other) const
1416{
1417	return Family() == other.Family()
1418		&& Type() == other.Type()
1419		&& Protocol() == other.Protocol()
1420		&& Address() == other.Address();
1421}
1422
1423
1424// #pragma mark - BNetworkServiceSettings
1425
1426
1427BNetworkServiceSettings::BNetworkServiceSettings()
1428	:
1429	fFamily(AF_UNSPEC),
1430	fType(-1),
1431	fProtocol(-1),
1432	fPort(-1),
1433	fEnabled(true),
1434	fStandAlone(false)
1435{
1436}
1437
1438
1439BNetworkServiceSettings::BNetworkServiceSettings(const BMessage& message)
1440	:
1441	fType(-1),
1442	fProtocol(-1),
1443	fPort(-1),
1444	fEnabled(true),
1445	fStandAlone(false)
1446{
1447	// TODO: user/group is currently ignored!
1448
1449	fName = message.GetString("name");
1450
1451	// Default family/port/protocol/type for all addresses
1452
1453	// we default to inet/tcp/port-from-service-name if nothing is specified
1454	const char* string;
1455	if (message.FindString("family", &string) != B_OK)
1456		string = "inet";
1457
1458	fFamily = get_address_family(string);
1459	if (fFamily == AF_UNSPEC)
1460		fFamily = AF_INET;
1461
1462	if (message.FindString("protocol", &string) == B_OK)
1463		fProtocol = parse_protocol(string);
1464	else {
1465		string = "tcp";
1466			// we set 'string' here for an eventual call to getservbyname()
1467			// below
1468		fProtocol = IPPROTO_TCP;
1469	}
1470
1471	if (message.FindInt32("port", &fPort) != B_OK) {
1472		struct servent* servent = getservbyname(Name(), string);
1473		if (servent != NULL)
1474			fPort = ntohs(servent->s_port);
1475		else
1476			fPort = -1;
1477	}
1478
1479	if (message.FindString("type", &string) == B_OK)
1480		fType = parse_type(string);
1481	else
1482		fType = type_for_protocol(fProtocol);
1483
1484	fStandAlone = message.GetBool("stand_alone");
1485
1486	const char* argument;
1487	for (int i = 0; message.FindString("launch", i, &argument) == B_OK; i++) {
1488		fArguments.Add(argument);
1489	}
1490
1491	BMessage addressData;
1492	int32 i = 0;
1493	for (; message.FindMessage("address", i, &addressData) == B_OK; i++) {
1494		BNetworkServiceAddressSettings address(addressData, fFamily,
1495			fType, fProtocol, fPort);
1496		fAddresses.push_back(address);
1497	}
1498
1499	if (i == 0 && (fFamily < 0 || fPort < 0)) {
1500		// no address specified
1501		printf("service %s has no address specified\n", Name());
1502		return;
1503	}
1504
1505	if (i == 0) {
1506		// no address specified, but family/port were given; add empty address
1507		BNetworkServiceAddressSettings address;
1508		address.SetFamily(fFamily);
1509		address.SetType(fType);
1510		address.SetProtocol(fProtocol);
1511		address.Address().SetToWildcard(fFamily, fPort);
1512
1513		fAddresses.push_back(address);
1514	}
1515}
1516
1517
1518BNetworkServiceSettings::~BNetworkServiceSettings()
1519{
1520}
1521
1522
1523status_t
1524BNetworkServiceSettings::InitCheck() const
1525{
1526	if (!fName.IsEmpty() && !fArguments.IsEmpty() && CountAddresses() > 0)
1527		return B_OK;
1528
1529	return B_BAD_VALUE;
1530}
1531
1532
1533const char*
1534BNetworkServiceSettings::Name() const
1535{
1536	return fName.String();
1537}
1538
1539
1540void
1541BNetworkServiceSettings::SetName(const char* name)
1542{
1543	fName = name;
1544}
1545
1546
1547bool
1548BNetworkServiceSettings::IsStandAlone() const
1549{
1550	return fStandAlone;
1551}
1552
1553
1554void
1555BNetworkServiceSettings::SetStandAlone(bool alone)
1556{
1557	fStandAlone = alone;
1558}
1559
1560
1561bool
1562BNetworkServiceSettings::IsEnabled() const
1563{
1564	return InitCheck() == B_OK && fEnabled;
1565}
1566
1567
1568void
1569BNetworkServiceSettings::SetEnabled(bool enable)
1570{
1571	fEnabled = enable;
1572}
1573
1574
1575int
1576BNetworkServiceSettings::Family() const
1577{
1578	return fFamily;
1579}
1580
1581
1582void
1583BNetworkServiceSettings::SetFamily(int family)
1584{
1585	fFamily = family;
1586}
1587
1588
1589int
1590BNetworkServiceSettings::Protocol() const
1591{
1592	return fProtocol;
1593}
1594
1595
1596void
1597BNetworkServiceSettings::SetProtocol(int protocol)
1598{
1599	fProtocol = protocol;
1600}
1601
1602
1603int
1604BNetworkServiceSettings::Type() const
1605{
1606	return fType;
1607}
1608
1609
1610void
1611BNetworkServiceSettings::SetType(int type)
1612{
1613	fType = type;
1614}
1615
1616
1617int
1618BNetworkServiceSettings::Port() const
1619{
1620	return fPort;
1621}
1622
1623
1624void
1625BNetworkServiceSettings::SetPort(int port)
1626{
1627	fPort = port;
1628}
1629
1630
1631int32
1632BNetworkServiceSettings::CountArguments() const
1633{
1634	return fArguments.CountStrings();
1635}
1636
1637
1638const char*
1639BNetworkServiceSettings::ArgumentAt(int32 index) const
1640{
1641	return fArguments.StringAt(index);
1642}
1643
1644
1645void
1646BNetworkServiceSettings::AddArgument(const char* argument)
1647{
1648	fArguments.Add(argument);
1649}
1650
1651
1652void
1653BNetworkServiceSettings::RemoveArgument(int32 index)
1654{
1655	fArguments.Remove(index);
1656}
1657
1658
1659int32
1660BNetworkServiceSettings::CountAddresses() const
1661{
1662	return fAddresses.size();
1663}
1664
1665
1666const BNetworkServiceAddressSettings&
1667BNetworkServiceSettings::AddressAt(int32 index) const
1668{
1669	return fAddresses[index];
1670}
1671
1672
1673void
1674BNetworkServiceSettings::AddAddress(
1675	const BNetworkServiceAddressSettings& address)
1676{
1677	fAddresses.push_back(address);
1678}
1679
1680
1681void
1682BNetworkServiceSettings::RemoveAddress(int32 index)
1683{
1684	fAddresses.erase(fAddresses.begin() + index);
1685}
1686
1687
1688/*!	This is a convenience method that returns the current state of the
1689	service, independent of the current settings.
1690*/
1691bool
1692BNetworkServiceSettings::IsRunning() const
1693{
1694	BMessage request(kMsgIsServiceRunning);
1695	request.AddString("name", fName);
1696
1697	BMessenger networkServer(kNetServerSignature);
1698	BMessage reply;
1699	status_t status = networkServer.SendMessage(&request, &reply);
1700	if (status == B_OK)
1701		return reply.GetBool("running");
1702
1703	return false;
1704}
1705
1706
1707status_t
1708BNetworkServiceSettings::GetMessage(BMessage& data) const
1709{
1710	status_t status = data.SetString("name", fName);
1711	if (status == B_OK && !fEnabled)
1712		status = data.SetBool("disabled", true);
1713	if (status == B_OK && fStandAlone)
1714		status = data.SetBool("stand_alone", true);
1715
1716	if (fFamily != AF_UNSPEC)
1717		status = data.SetInt32("family", fFamily);
1718	if (fType != -1)
1719		status = data.SetInt32("type", fType);
1720	if (fProtocol != -1)
1721		status = data.SetInt32("protocol", fProtocol);
1722	if (fPort != -1)
1723		status = data.SetInt32("port", fPort);
1724
1725	for (int32 i = 0; i < fArguments.CountStrings(); i++) {
1726		if (status == B_OK)
1727			status = data.AddString("launch", fArguments.StringAt(i));
1728		if (status != B_OK)
1729			break;
1730	}
1731
1732	for (int32 i = 0; i < CountAddresses(); i++) {
1733		BNetworkServiceAddressSettings address = AddressAt(i);
1734		if (address.Family() == Family()
1735			&& address.Type() == Type()
1736			&& address.Protocol() == Protocol()
1737			&& address.Address().IsWildcard()
1738			&& address.Address().Port() == Port()) {
1739			// This address will be created automatically, no need to store it
1740			continue;
1741		}
1742
1743		BMessage addressMessage;
1744		status = AddressAt(i).GetMessage(addressMessage);
1745		if (status == B_OK)
1746			status = data.AddMessage("address", &addressMessage);
1747		if (status != B_OK)
1748			break;
1749	}
1750	return status;
1751}
1752