xref: /haiku/src/kits/network/libnetapi/NetworkSettings.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
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 
31 using namespace BNetworkKit;
32 
33 
34 static const char* kInterfaceSettingsName = "interfaces";
35 static const char* kServicesSettingsName = "services";
36 static const char* kNetworksSettingsName = "wireless_networks";
37 
38 
39 // Interface templates
40 
41 namespace BPrivate {
42 
43 
44 class InterfaceAddressFamilyConverter : public DriverSettingsConverter {
45 public:
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 
58 using BPrivate::InterfaceAddressFamilyConverter;
59 
60 
61 const 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 
72 const static settings_template kInterfaceNetworkTemplate[] = {
73 	{B_STRING_TYPE, "name", NULL, true},
74 	{B_STRING_TYPE, "mac", NULL},
75 };
76 
77 const 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 
88 const static settings_template kInterfacesTemplate[] = {
89 	{B_MESSAGE_TYPE, "interface", kInterfaceTemplate},
90 	{0, NULL, NULL}
91 };
92 
93 // Network templates
94 
95 const 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 
106 const static settings_template kNetworksTemplate[] = {
107 	{B_MESSAGE_TYPE, "network", kNetworkTemplate},
108 	{0, NULL, NULL}
109 };
110 
111 // Service templates
112 
113 const 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 
122 const 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 
137 const static settings_template kServicesTemplate[] = {
138 	{B_MESSAGE_TYPE, "service", kServiceTemplate},
139 	{0, NULL, NULL}
140 };
141 
142 
143 struct address_family {
144 	int			family;
145 	const char*	name;
146 	const char*	identifiers[4];
147 };
148 
149 
150 static 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 
165 static const char*
166 get_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 
176 static int
177 get_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 */
196 static bool
197 parse_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 
231 static int
232 parse_type(const char* string)
233 {
234 	if (!strcasecmp(string, "stream"))
235 		return SOCK_STREAM;
236 
237 	return SOCK_DGRAM;
238 }
239 
240 
241 static int
242 parse_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 
252 static int
253 type_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 
270 status_t
271 InterfaceAddressFamilyConverter::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 
279 status_t
280 InterfaceAddressFamilyConverter::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 
301 BNetworkSettings::BNetworkSettings()
302 {
303 	_Load();
304 }
305 
306 
307 BNetworkSettings::~BNetworkSettings()
308 {
309 }
310 
311 
312 status_t
313 BNetworkSettings::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 
324 status_t
325 BNetworkSettings::GetInterface(const char* name, BMessage& interface) const
326 {
327 	int32 index;
328 	return _GetItem(fInterfaces, "interface", "device", name, index, interface);
329 }
330 
331 
332 status_t
333 BNetworkSettings::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 
349 status_t
350 BNetworkSettings::RemoveInterface(const char* name)
351 {
352 	return _RemoveItem(fInterfaces, "interface", "device", name,
353 		kInterfaceSettingsName);
354 }
355 
356 
357 BNetworkInterfaceSettings
358 BNetworkSettings::Interface(const char* name)
359 {
360 	BMessage interface;
361 	GetInterface(name, interface);
362 	return BNetworkInterfaceSettings(interface);
363 }
364 
365 
366 const BNetworkInterfaceSettings
367 BNetworkSettings::Interface(const char* name) const
368 {
369 	BMessage interface;
370 	GetInterface(name, interface);
371 	return BNetworkInterfaceSettings(interface);
372 }
373 
374 
375 int32
376 BNetworkSettings::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 
386 status_t
387 BNetworkSettings::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 
398 status_t
399 BNetworkSettings::GetNetwork(const char* name, BMessage& network) const
400 {
401 	int32 index;
402 	return _GetItem(fNetworks, "network", "name", name, index, network);
403 }
404 
405 
406 status_t
407 BNetworkSettings::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 
423 status_t
424 BNetworkSettings::RemoveNetwork(const char* name)
425 {
426 	return _RemoveItem(fNetworks, "network", "name", name,
427 		kNetworksSettingsName);
428 }
429 
430 
431 const BMessage&
432 BNetworkSettings::Services() const
433 {
434 	return fServices;
435 }
436 
437 
438 status_t
439 BNetworkSettings::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 
450 status_t
451 BNetworkSettings::GetService(const char* name, BMessage& service) const
452 {
453 	int32 index;
454 	return _GetItem(fServices, "service", "name", name, index, service);
455 }
456 
457 
458 status_t
459 BNetworkSettings::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 
475 status_t
476 BNetworkSettings::RemoveService(const char* name)
477 {
478 	return _RemoveItem(fServices, "service", "name", name,
479 		kServicesSettingsName);
480 }
481 
482 
483 BNetworkServiceSettings
484 BNetworkSettings::Service(const char* name)
485 {
486 	BMessage service;
487 	GetService(name, service);
488 	return BNetworkServiceSettings(service);
489 }
490 
491 
492 const BNetworkServiceSettings
493 BNetworkSettings::Service(const char* name) const
494 {
495 	BMessage service;
496 	GetService(name, service);
497 	return BNetworkServiceSettings(service);
498 }
499 
500 
501 status_t
502 BNetworkSettings::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 
521 status_t
522 BNetworkSettings::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 
530 status_t
531 BNetworkSettings::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 
574 status_t
575 BNetworkSettings::_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 
621 status_t
622 BNetworkSettings::_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 
661 BPath
662 BNetworkSettings::_Path(BPath& parent, const char* leaf)
663 {
664 	return BPath(parent.Path(), leaf);
665 }
666 
667 
668 status_t
669 BNetworkSettings::_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 
683 status_t
684 BNetworkSettings::_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 
696 status_t
697 BNetworkSettings::_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 
791 status_t
792 BNetworkSettings::_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 
859 status_t
860 BNetworkSettings::_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 
880 status_t
881 BNetworkSettings::_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 
900 BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings()
901 	:
902 	fFamily(AF_UNSPEC),
903 	fAutoConfigure(true)
904 {
905 }
906 
907 
908 BNetworkInterfaceAddressSettings::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 
938 BNetworkInterfaceAddressSettings::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 
952 BNetworkInterfaceAddressSettings::~BNetworkInterfaceAddressSettings()
953 {
954 }
955 
956 
957 int
958 BNetworkInterfaceAddressSettings::Family() const
959 {
960 	return fFamily;
961 }
962 
963 
964 void
965 BNetworkInterfaceAddressSettings::SetFamily(int family)
966 {
967 	fFamily = family;
968 }
969 
970 
971 bool
972 BNetworkInterfaceAddressSettings::IsAutoConfigure() const
973 {
974 	return fAutoConfigure;
975 }
976 
977 
978 void
979 BNetworkInterfaceAddressSettings::SetAutoConfigure(bool configure)
980 {
981 	fAutoConfigure = configure;
982 }
983 
984 
985 const BNetworkAddress&
986 BNetworkInterfaceAddressSettings::Address() const
987 {
988 	return fAddress;
989 }
990 
991 
992 BNetworkAddress&
993 BNetworkInterfaceAddressSettings::Address()
994 {
995 	return fAddress;
996 }
997 
998 
999 const BNetworkAddress&
1000 BNetworkInterfaceAddressSettings::Mask() const
1001 {
1002 	return fMask;
1003 }
1004 
1005 
1006 BNetworkAddress&
1007 BNetworkInterfaceAddressSettings::Mask()
1008 {
1009 	return fMask;
1010 }
1011 
1012 
1013 const BNetworkAddress&
1014 BNetworkInterfaceAddressSettings::Peer() const
1015 {
1016 	return fPeer;
1017 }
1018 
1019 
1020 BNetworkAddress&
1021 BNetworkInterfaceAddressSettings::Peer()
1022 {
1023 	return fPeer;
1024 }
1025 
1026 
1027 const BNetworkAddress&
1028 BNetworkInterfaceAddressSettings::Broadcast() const
1029 {
1030 	return fBroadcast;
1031 }
1032 
1033 
1034 BNetworkAddress&
1035 BNetworkInterfaceAddressSettings::Broadcast()
1036 {
1037 	return fBroadcast;
1038 }
1039 
1040 
1041 const BNetworkAddress&
1042 BNetworkInterfaceAddressSettings::Gateway() const
1043 {
1044 	return fGateway;
1045 }
1046 
1047 
1048 BNetworkAddress&
1049 BNetworkInterfaceAddressSettings::Gateway()
1050 {
1051 	return fGateway;
1052 }
1053 
1054 
1055 status_t
1056 BNetworkInterfaceAddressSettings::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 
1080 BNetworkInterfaceAddressSettings&
1081 BNetworkInterfaceAddressSettings::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 
1099 BNetworkInterfaceSettings::BNetworkInterfaceSettings()
1100 	:
1101 	fFlags(0),
1102 	fMTU(0),
1103 	fMetric(0)
1104 {
1105 }
1106 
1107 
1108 BNetworkInterfaceSettings::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 
1124 BNetworkInterfaceSettings::~BNetworkInterfaceSettings()
1125 {
1126 }
1127 
1128 
1129 const char*
1130 BNetworkInterfaceSettings::Name() const
1131 {
1132 	return fName;
1133 }
1134 
1135 
1136 void
1137 BNetworkInterfaceSettings::SetName(const char* name)
1138 {
1139 	fName = name;
1140 }
1141 
1142 
1143 int32
1144 BNetworkInterfaceSettings::Flags() const
1145 {
1146 	return fFlags;
1147 }
1148 
1149 
1150 void
1151 BNetworkInterfaceSettings::SetFlags(int32 flags)
1152 {
1153 	fFlags = flags;
1154 }
1155 
1156 
1157 int32
1158 BNetworkInterfaceSettings::MTU() const
1159 {
1160 	return fMTU;
1161 }
1162 
1163 
1164 void
1165 BNetworkInterfaceSettings::SetMTU(int32 mtu)
1166 {
1167 	fMTU = mtu;
1168 }
1169 
1170 
1171 int32
1172 BNetworkInterfaceSettings::Metric() const
1173 {
1174 	return fMetric;
1175 }
1176 
1177 
1178 void
1179 BNetworkInterfaceSettings::SetMetric(int32 metric)
1180 {
1181 	fMetric = metric;
1182 }
1183 
1184 
1185 int32
1186 BNetworkInterfaceSettings::CountAddresses() const
1187 {
1188 	return fAddresses.size();
1189 }
1190 
1191 
1192 const BNetworkInterfaceAddressSettings&
1193 BNetworkInterfaceSettings::AddressAt(int32 index) const
1194 {
1195 	return fAddresses[index];
1196 }
1197 
1198 
1199 BNetworkInterfaceAddressSettings&
1200 BNetworkInterfaceSettings::AddressAt(int32 index)
1201 {
1202 	return fAddresses[index];
1203 }
1204 
1205 
1206 int32
1207 BNetworkInterfaceSettings::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 
1218 void
1219 BNetworkInterfaceSettings::AddAddress(
1220 	const BNetworkInterfaceAddressSettings& address)
1221 {
1222 	fAddresses.push_back(address);
1223 }
1224 
1225 
1226 void
1227 BNetworkInterfaceSettings::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 */
1240 bool
1241 BNetworkInterfaceSettings::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 
1274 status_t
1275 BNetworkInterfaceSettings::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 
1300 BNetworkServiceAddressSettings::BNetworkServiceAddressSettings()
1301 {
1302 }
1303 
1304 
1305 BNetworkServiceAddressSettings::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 
1344 BNetworkServiceAddressSettings::~BNetworkServiceAddressSettings()
1345 {
1346 }
1347 
1348 
1349 int
1350 BNetworkServiceAddressSettings::Family() const
1351 {
1352 	return fFamily;
1353 }
1354 
1355 
1356 void
1357 BNetworkServiceAddressSettings::SetFamily(int family)
1358 {
1359 	fFamily = family;
1360 }
1361 
1362 
1363 int
1364 BNetworkServiceAddressSettings::Protocol() const
1365 {
1366 	return fProtocol;
1367 }
1368 
1369 
1370 void
1371 BNetworkServiceAddressSettings::SetProtocol(int protocol)
1372 {
1373 	fProtocol = protocol;
1374 }
1375 
1376 
1377 int
1378 BNetworkServiceAddressSettings::Type() const
1379 {
1380 	return fType;
1381 }
1382 
1383 
1384 void
1385 BNetworkServiceAddressSettings::SetType(int type)
1386 {
1387 	fType = type;
1388 }
1389 
1390 
1391 const BNetworkAddress&
1392 BNetworkServiceAddressSettings::Address() const
1393 {
1394 	return fAddress;
1395 }
1396 
1397 
1398 BNetworkAddress&
1399 BNetworkServiceAddressSettings::Address()
1400 {
1401 	return fAddress;
1402 }
1403 
1404 
1405 status_t
1406 BNetworkServiceAddressSettings::GetMessage(BMessage& data) const
1407 {
1408 	// TODO!
1409 	return B_NOT_SUPPORTED;
1410 }
1411 
1412 
1413 bool
1414 BNetworkServiceAddressSettings::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 
1427 BNetworkServiceSettings::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 
1439 BNetworkServiceSettings::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 
1518 BNetworkServiceSettings::~BNetworkServiceSettings()
1519 {
1520 }
1521 
1522 
1523 status_t
1524 BNetworkServiceSettings::InitCheck() const
1525 {
1526 	if (!fName.IsEmpty() && !fArguments.IsEmpty() && CountAddresses() > 0)
1527 		return B_OK;
1528 
1529 	return B_BAD_VALUE;
1530 }
1531 
1532 
1533 const char*
1534 BNetworkServiceSettings::Name() const
1535 {
1536 	return fName.String();
1537 }
1538 
1539 
1540 void
1541 BNetworkServiceSettings::SetName(const char* name)
1542 {
1543 	fName = name;
1544 }
1545 
1546 
1547 bool
1548 BNetworkServiceSettings::IsStandAlone() const
1549 {
1550 	return fStandAlone;
1551 }
1552 
1553 
1554 void
1555 BNetworkServiceSettings::SetStandAlone(bool alone)
1556 {
1557 	fStandAlone = alone;
1558 }
1559 
1560 
1561 bool
1562 BNetworkServiceSettings::IsEnabled() const
1563 {
1564 	return InitCheck() == B_OK && fEnabled;
1565 }
1566 
1567 
1568 void
1569 BNetworkServiceSettings::SetEnabled(bool enable)
1570 {
1571 	fEnabled = enable;
1572 }
1573 
1574 
1575 int
1576 BNetworkServiceSettings::Family() const
1577 {
1578 	return fFamily;
1579 }
1580 
1581 
1582 void
1583 BNetworkServiceSettings::SetFamily(int family)
1584 {
1585 	fFamily = family;
1586 }
1587 
1588 
1589 int
1590 BNetworkServiceSettings::Protocol() const
1591 {
1592 	return fProtocol;
1593 }
1594 
1595 
1596 void
1597 BNetworkServiceSettings::SetProtocol(int protocol)
1598 {
1599 	fProtocol = protocol;
1600 }
1601 
1602 
1603 int
1604 BNetworkServiceSettings::Type() const
1605 {
1606 	return fType;
1607 }
1608 
1609 
1610 void
1611 BNetworkServiceSettings::SetType(int type)
1612 {
1613 	fType = type;
1614 }
1615 
1616 
1617 int
1618 BNetworkServiceSettings::Port() const
1619 {
1620 	return fPort;
1621 }
1622 
1623 
1624 void
1625 BNetworkServiceSettings::SetPort(int port)
1626 {
1627 	fPort = port;
1628 }
1629 
1630 
1631 int32
1632 BNetworkServiceSettings::CountArguments() const
1633 {
1634 	return fArguments.CountStrings();
1635 }
1636 
1637 
1638 const char*
1639 BNetworkServiceSettings::ArgumentAt(int32 index) const
1640 {
1641 	return fArguments.StringAt(index);
1642 }
1643 
1644 
1645 void
1646 BNetworkServiceSettings::AddArgument(const char* argument)
1647 {
1648 	fArguments.Add(argument);
1649 }
1650 
1651 
1652 void
1653 BNetworkServiceSettings::RemoveArgument(int32 index)
1654 {
1655 	fArguments.Remove(index);
1656 }
1657 
1658 
1659 int32
1660 BNetworkServiceSettings::CountAddresses() const
1661 {
1662 	return fAddresses.size();
1663 }
1664 
1665 
1666 const BNetworkServiceAddressSettings&
1667 BNetworkServiceSettings::AddressAt(int32 index) const
1668 {
1669 	return fAddresses[index];
1670 }
1671 
1672 
1673 void
1674 BNetworkServiceSettings::AddAddress(
1675 	const BNetworkServiceAddressSettings& address)
1676 {
1677 	fAddresses.push_back(address);
1678 }
1679 
1680 
1681 void
1682 BNetworkServiceSettings::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 */
1691 bool
1692 BNetworkServiceSettings::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 
1707 status_t
1708 BNetworkServiceSettings::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