tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / network / libnetapi / NetworkSettings.cpp
blob6dd760e61c0bf4282b1fe648975466c661c5d28f
1 /*
2 * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include <NetworkSettings.h>
12 #include <netdb.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
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>
27 #include <DriverSettingsMessageAdapter.h>
28 #include <NetServer.h>
31 using namespace BNetworkKit;
34 static const char* kInterfaceSettingsName = "interfaces";
35 static const char* kServicesSettingsName = "services";
36 static const char* kNetworksSettingsName = "wireless_networks";
39 // Interface templates
41 namespace BPrivate {
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);
56 } // namespace BPrivate
58 using BPrivate::InterfaceAddressFamilyConverter;
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}
72 const static settings_template kInterfaceNetworkTemplate[] = {
73 {B_STRING_TYPE, "name", NULL, true},
74 {B_STRING_TYPE, "mac", NULL},
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}
88 const static settings_template kInterfacesTemplate[] = {
89 {B_MESSAGE_TYPE, "interface", kInterfaceTemplate},
90 {0, NULL, NULL}
93 // Network templates
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}
106 const static settings_template kNetworksTemplate[] = {
107 {B_MESSAGE_TYPE, "network", kNetworkTemplate},
108 {0, NULL, NULL}
111 // Service templates
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}
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}
137 const static settings_template kServicesTemplate[] = {
138 {B_MESSAGE_TYPE, "service", kServiceTemplate},
139 {0, NULL, NULL}
143 struct address_family {
144 int family;
145 const char* name;
146 const char* identifiers[4];
150 static const address_family kFamilies[] = {
152 AF_INET,
153 "inet",
154 {"AF_INET", "inet", "ipv4", NULL},
157 AF_INET6,
158 "inet6",
159 {"AF_INET6", "inet6", "ipv6", NULL},
161 { -1, NULL, {NULL} }
165 static const char*
166 get_family_name(int family)
168 for (int32 i = 0; kFamilies[i].family >= 0; i++) {
169 if (kFamilies[i].family == family)
170 return kFamilies[i].name;
172 return NULL;
176 static int
177 get_address_family(const char* argument)
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;
188 return AF_UNSPEC;
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.
196 static bool
197 parse_address(int32& family, const char* argument, BNetworkAddress& address)
199 if (argument == NULL) {
200 if (family != AF_UNSPEC)
201 address.SetToWildcard(family);
202 return false;
205 status_t status = address.SetTo(family, argument, (uint16)0,
206 B_NO_ADDRESS_RESOLUTION);
207 if (status != B_OK)
208 return false;
210 if (family == AF_UNSPEC) {
211 // Test if we support the resulting address family
212 bool supported = false;
214 for (int32 i = 0; kFamilies[i].family >= 0; i++) {
215 if (kFamilies[i].family == address.Family()) {
216 supported = true;
217 break;
220 if (!supported)
221 return false;
223 // Take over family from address
224 family = address.Family();
227 return true;
231 static int
232 parse_type(const char* string)
234 if (!strcasecmp(string, "stream"))
235 return SOCK_STREAM;
237 return SOCK_DGRAM;
241 static int
242 parse_protocol(const char* string)
244 struct protoent* proto = getprotobyname(string);
245 if (proto == NULL)
246 return IPPROTO_TCP;
248 return proto->p_proto;
252 static int
253 type_for_protocol(int protocol)
255 // default determined by protocol
256 switch (protocol) {
257 case IPPROTO_TCP:
258 return SOCK_STREAM;
260 case IPPROTO_UDP:
261 default:
262 return SOCK_DGRAM;
267 // #pragma mark -
270 status_t
271 InterfaceAddressFamilyConverter::ConvertFromDriverSettings(
272 const driver_parameter& parameter, const char* name, int32 index,
273 uint32 type, BMessage& target)
275 return B_NOT_SUPPORTED;
279 status_t
280 InterfaceAddressFamilyConverter::ConvertToDriverSettings(const BMessage& source,
281 const char* name, int32 index, uint32 type, BString& value)
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;
291 return B_OK;
294 return B_NOT_SUPPORTED;
298 // #pragma mark -
301 BNetworkSettings::BNetworkSettings()
303 _Load();
307 BNetworkSettings::~BNetworkSettings()
312 status_t
313 BNetworkSettings::GetNextInterface(uint32& cookie, BMessage& interface)
315 status_t status = fInterfaces.FindMessage("interface", cookie, &interface);
316 if (status != B_OK)
317 return status;
319 cookie++;
320 return B_OK;
324 status_t
325 BNetworkSettings::GetInterface(const char* name, BMessage& interface) const
327 int32 index;
328 return _GetItem(fInterfaces, "interface", "device", name, index, interface);
332 status_t
333 BNetworkSettings::AddInterface(const BMessage& interface)
335 const char* name = NULL;
336 if (interface.FindString("device", &name) != B_OK)
337 return B_BAD_VALUE;
339 _RemoveItem(fInterfaces, "interface", "device", name);
341 status_t result = fInterfaces.AddMessage("interface", &interface);
342 if (result != B_OK)
343 return result;
345 return _Save(kInterfaceSettingsName);
349 status_t
350 BNetworkSettings::RemoveInterface(const char* name)
352 return _RemoveItem(fInterfaces, "interface", "device", name,
353 kInterfaceSettingsName);
357 BNetworkInterfaceSettings
358 BNetworkSettings::Interface(const char* name)
360 BMessage interface;
361 GetInterface(name, interface);
362 return BNetworkInterfaceSettings(interface);
366 const BNetworkInterfaceSettings
367 BNetworkSettings::Interface(const char* name) const
369 BMessage interface;
370 GetInterface(name, interface);
371 return BNetworkInterfaceSettings(interface);
375 int32
376 BNetworkSettings::CountNetworks() const
378 int32 count = 0;
379 if (fNetworks.GetInfo("network", NULL, &count) != B_OK)
380 return 0;
382 return count;
386 status_t
387 BNetworkSettings::GetNextNetwork(uint32& cookie, BMessage& network) const
389 status_t status = fNetworks.FindMessage("network", cookie, &network);
390 if (status != B_OK)
391 return status;
393 cookie++;
394 return B_OK;
398 status_t
399 BNetworkSettings::GetNetwork(const char* name, BMessage& network) const
401 int32 index;
402 return _GetItem(fNetworks, "network", "name", name, index, network);
406 status_t
407 BNetworkSettings::AddNetwork(const BMessage& network)
409 const char* name = NULL;
410 if (network.FindString("name", &name) != B_OK)
411 return B_BAD_VALUE;
413 _RemoveItem(fNetworks, "network", "name", name);
415 status_t result = fNetworks.AddMessage("network", &network);
416 if (result != B_OK)
417 return result;
419 return _Save(kNetworksSettingsName);
423 status_t
424 BNetworkSettings::RemoveNetwork(const char* name)
426 return _RemoveItem(fNetworks, "network", "name", name,
427 kNetworksSettingsName);
431 const BMessage&
432 BNetworkSettings::Services() const
434 return fServices;
438 status_t
439 BNetworkSettings::GetNextService(uint32& cookie, BMessage& service)
441 status_t status = fServices.FindMessage("service", cookie, &service);
442 if (status != B_OK)
443 return status;
445 cookie++;
446 return B_OK;
450 status_t
451 BNetworkSettings::GetService(const char* name, BMessage& service) const
453 int32 index;
454 return _GetItem(fServices, "service", "name", name, index, service);
458 status_t
459 BNetworkSettings::AddService(const BMessage& service)
461 const char* name = service.GetString("name");
462 if (name == NULL)
463 return B_BAD_VALUE;
465 _RemoveItem(fServices, "service", "name", name);
467 status_t result = fServices.AddMessage("service", &service);
468 if (result != B_OK)
469 return result;
471 return _Save(kServicesSettingsName);
475 status_t
476 BNetworkSettings::RemoveService(const char* name)
478 return _RemoveItem(fServices, "service", "name", name,
479 kServicesSettingsName);
483 BNetworkServiceSettings
484 BNetworkSettings::Service(const char* name)
486 BMessage service;
487 GetService(name, service);
488 return BNetworkServiceSettings(service);
492 const BNetworkServiceSettings
493 BNetworkSettings::Service(const char* name) const
495 BMessage service;
496 GetService(name, service);
497 return BNetworkServiceSettings(service);
501 status_t
502 BNetworkSettings::StartMonitoring(const BMessenger& target)
504 if (_IsWatching(target))
505 return B_OK;
506 if (_IsWatching())
507 StopMonitoring(fListener);
509 fListener = target;
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);
517 return status;
521 status_t
522 BNetworkSettings::StopMonitoring(const BMessenger& target)
524 // TODO: this needs to be changed in case the server will watch
525 // anything else but settings
526 return BPrivate::BPathMonitor::StopWatching(target);
530 status_t
531 BNetworkSettings::Update(BMessage* message)
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;
539 BPath settingsFolderPath;
540 _GetPath(NULL, settingsFolderPath);
541 if (strncmp(pathName, settingsFolderPath.Path(),
542 strlen(settingsFolderPath.Path()))) {
543 return B_NAME_NOT_FOUND;
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;
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;
560 BPath path(pathName);
561 uint32 type;
562 if (_Load(path.Leaf(), &type) == B_OK) {
563 BMessage update(type);
564 fListener.SendMessage(&update);
567 return B_OK;
571 // #pragma mark - private
574 status_t
575 BNetworkSettings::_Load(const char* name, uint32* _type)
577 BPath path;
578 status_t status = _GetPath(NULL, path);
579 if (status != B_OK)
580 return status;
582 DriverSettingsMessageAdapter adapter;
583 status = B_ENTRY_NOT_FOUND;
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;
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);
605 if (_type != NULL)
606 *_type = kMsgNetworkSettingsUpdated;
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;
617 return status;
621 status_t
622 BNetworkSettings::_Save(const char* name)
624 BPath path;
625 status_t status = _GetPath(NULL, path);
626 if (status != B_OK)
627 return status;
629 DriverSettingsMessageAdapter adapter;
630 status = B_ENTRY_NOT_FOUND;
632 if (name == NULL || strcmp(name, kInterfaceSettingsName) == 0) {
633 status = adapter.ConvertToDriverSettings(
634 _Path(path, kInterfaceSettingsName).Path(),
635 kInterfacesTemplate, fInterfaces);
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);
647 status = adapter.ConvertToDriverSettings(
648 _Path(path, kNetworksSettingsName).Path(),
649 kNetworksTemplate, networks);
651 if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
652 status = adapter.ConvertToDriverSettings(
653 _Path(path, kServicesSettingsName).Path(),
654 kServicesTemplate, fServices);
657 return status;
661 BPath
662 BNetworkSettings::_Path(BPath& parent, const char* leaf)
664 return BPath(parent.Path(), leaf);
668 status_t
669 BNetworkSettings::_GetPath(const char* name, BPath& path)
671 if (find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path, true) != B_OK)
672 return B_ERROR;
674 path.Append("network");
675 create_directory(path.Path(), 0755);
677 if (name != NULL)
678 path.Append(name);
679 return B_OK;
683 status_t
684 BNetworkSettings::_StartWatching(const char* name, const BMessenger& target)
686 BPath path;
687 status_t status = _GetPath(name, path);
688 if (status != B_OK)
689 return status;
691 return BPrivate::BPathMonitor::StartWatching(path.Path(), B_WATCH_STAT,
692 target);
696 status_t
697 BNetworkSettings::_ConvertNetworkToSettings(BMessage& message)
699 BNetworkAddress address;
700 status_t result = message.FindFlat("address", &address);
701 if (result == B_OK)
702 message.RemoveName("address");
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;
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));
717 if (macAddress[index] != 0)
718 usable = true;
721 if (usable)
722 message.AddString("mac", formatted);
725 uint32 authentication = 0;
726 result = message.FindUInt32("authentication_mode", &authentication);
727 if (result == B_OK) {
728 message.RemoveName("authentication_mode");
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;
746 if (result == B_OK && authenticationString != NULL)
747 message.AddString("authentication", authenticationString);
750 uint32 cipher = 0;
751 result = message.FindUInt32("cipher", &cipher);
752 if (result == B_OK) {
753 message.RemoveName("cipher");
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");
763 uint32 groupCipher = 0;
764 result = message.FindUInt32("group_cipher", &groupCipher);
765 if (result == B_OK) {
766 message.RemoveName("group_cipher");
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");
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");
787 return B_OK;
791 status_t
792 BNetworkSettings::_ConvertNetworkFromSettings(BMessage& message)
794 message.RemoveName("mac");
795 // TODO: convert into a flat BNetworkAddress "address"
797 const char* authentication = NULL;
798 if (message.FindString("authentication", &authentication) == B_OK) {
799 message.RemoveName("authentication");
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);
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;
828 message.RemoveName("cipher");
829 if (cipher != 0)
830 message.AddUInt32("cipher", cipher);
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;
847 message.RemoveName("group_cipher");
848 if (cipher != 0)
849 message.AddUInt32("group_cipher", cipher);
851 message.AddUInt32("flags", B_NETWORK_IS_PERSISTENT);
853 // TODO: add the other fields
854 message.RemoveName("key");
855 return B_OK;
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
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;
873 index++;
876 return B_ENTRY_NOT_FOUND;
880 status_t
881 BNetworkSettings::_RemoveItem(BMessage& container, const char* itemField,
882 const char* nameField, const char* name, const char* store)
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;
893 return B_ENTRY_NOT_FOUND;
897 // #pragma mark - BNetworkInterfaceAddressSettings
900 BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings()
902 fFamily(AF_UNSPEC),
903 fAutoConfigure(true)
908 BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
909 const BMessage& data)
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;
921 } else
922 fFamily = AF_UNSPEC;
925 fAutoConfigure = data.GetBool("auto_config", false);
927 if (!fAutoConfigure) {
928 if (parse_address(fFamily, data.GetString("address", NULL), fAddress))
929 parse_address(fFamily, data.GetString("mask", NULL), fMask);
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);
938 BNetworkInterfaceAddressSettings::BNetworkInterfaceAddressSettings(
939 const BNetworkInterfaceAddressSettings& other)
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)
952 BNetworkInterfaceAddressSettings::~BNetworkInterfaceAddressSettings()
958 BNetworkInterfaceAddressSettings::Family() const
960 return fFamily;
964 void
965 BNetworkInterfaceAddressSettings::SetFamily(int family)
967 fFamily = family;
971 bool
972 BNetworkInterfaceAddressSettings::IsAutoConfigure() const
974 return fAutoConfigure;
978 void
979 BNetworkInterfaceAddressSettings::SetAutoConfigure(bool configure)
981 fAutoConfigure = configure;
985 const BNetworkAddress&
986 BNetworkInterfaceAddressSettings::Address() const
988 return fAddress;
992 BNetworkAddress&
993 BNetworkInterfaceAddressSettings::Address()
995 return fAddress;
999 const BNetworkAddress&
1000 BNetworkInterfaceAddressSettings::Mask() const
1002 return fMask;
1006 BNetworkAddress&
1007 BNetworkInterfaceAddressSettings::Mask()
1009 return fMask;
1013 const BNetworkAddress&
1014 BNetworkInterfaceAddressSettings::Peer() const
1016 return fPeer;
1020 BNetworkAddress&
1021 BNetworkInterfaceAddressSettings::Peer()
1023 return fPeer;
1027 const BNetworkAddress&
1028 BNetworkInterfaceAddressSettings::Broadcast() const
1030 return fBroadcast;
1034 BNetworkAddress&
1035 BNetworkInterfaceAddressSettings::Broadcast()
1037 return fBroadcast;
1041 const BNetworkAddress&
1042 BNetworkInterfaceAddressSettings::Gateway() const
1044 return fGateway;
1048 BNetworkAddress&
1049 BNetworkInterfaceAddressSettings::Gateway()
1051 return fGateway;
1055 status_t
1056 BNetworkInterfaceAddressSettings::GetMessage(BMessage& data) const
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);
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());
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());
1076 return status;
1080 BNetworkInterfaceAddressSettings&
1081 BNetworkInterfaceAddressSettings::operator=(
1082 const BNetworkInterfaceAddressSettings& other)
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;
1092 return *this;
1096 // #pragma mark - BNetworkInterfaceSettings
1099 BNetworkInterfaceSettings::BNetworkInterfaceSettings()
1101 fFlags(0),
1102 fMTU(0),
1103 fMetric(0)
1108 BNetworkInterfaceSettings::BNetworkInterfaceSettings(const BMessage& message)
1110 fName = message.GetString("device");
1111 fFlags = message.GetInt32("flags", 0);
1112 fMTU = message.GetInt32("mtu", 0);
1113 fMetric = message.GetInt32("metric", 0);
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);
1124 BNetworkInterfaceSettings::~BNetworkInterfaceSettings()
1129 const char*
1130 BNetworkInterfaceSettings::Name() const
1132 return fName;
1136 void
1137 BNetworkInterfaceSettings::SetName(const char* name)
1139 fName = name;
1143 int32
1144 BNetworkInterfaceSettings::Flags() const
1146 return fFlags;
1150 void
1151 BNetworkInterfaceSettings::SetFlags(int32 flags)
1153 fFlags = flags;
1157 int32
1158 BNetworkInterfaceSettings::MTU() const
1160 return fMTU;
1164 void
1165 BNetworkInterfaceSettings::SetMTU(int32 mtu)
1167 fMTU = mtu;
1171 int32
1172 BNetworkInterfaceSettings::Metric() const
1174 return fMetric;
1178 void
1179 BNetworkInterfaceSettings::SetMetric(int32 metric)
1181 fMetric = metric;
1185 int32
1186 BNetworkInterfaceSettings::CountAddresses() const
1188 return fAddresses.size();
1192 const BNetworkInterfaceAddressSettings&
1193 BNetworkInterfaceSettings::AddressAt(int32 index) const
1195 return fAddresses[index];
1199 BNetworkInterfaceAddressSettings&
1200 BNetworkInterfaceSettings::AddressAt(int32 index)
1202 return fAddresses[index];
1206 int32
1207 BNetworkInterfaceSettings::FindFirstAddress(int family) const
1209 for (int32 index = 0; index < CountAddresses(); index++) {
1210 const BNetworkInterfaceAddressSettings address = AddressAt(index);
1211 if (address.Family() == family)
1212 return index;
1214 return -1;
1218 void
1219 BNetworkInterfaceSettings::AddAddress(
1220 const BNetworkInterfaceAddressSettings& address)
1222 fAddresses.push_back(address);
1226 void
1227 BNetworkInterfaceSettings::RemoveAddress(int32 index)
1229 fAddresses.erase(fAddresses.begin() + index);
1233 /*! This is a convenience method that returns the current state of the
1234 interface, not just the one configured.
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.
1240 bool
1241 BNetworkInterfaceSettings::IsAutoConfigure(int family) const
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;
1248 BNetworkInterfaceAddress address;
1249 status_t status = B_ERROR;
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();
1270 return false;
1274 status_t
1275 BNetworkInterfaceSettings::GetMessage(BMessage& data) const
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);
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;
1293 return status;
1297 // #pragma mark - BNetworkServiceAddressSettings
1300 BNetworkServiceAddressSettings::BNetworkServiceAddressSettings()
1305 BNetworkServiceAddressSettings::BNetworkServiceAddressSettings(
1306 const BMessage& data, int serviceFamily, int serviceType,
1307 int serviceProtocol, int servicePort)
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;
1320 } else
1321 fFamily = serviceFamily;
1324 if (!parse_address(fFamily, data.GetString("address"), fAddress))
1325 fAddress.SetToWildcard(fFamily);
1327 const char* string;
1328 if (data.FindString("protocol", &string) == B_OK)
1329 fProtocol = parse_protocol(string);
1330 else
1331 fProtocol = serviceProtocol;
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;
1340 fAddress.SetPort(data.GetInt32("port", servicePort));
1344 BNetworkServiceAddressSettings::~BNetworkServiceAddressSettings()
1350 BNetworkServiceAddressSettings::Family() const
1352 return fFamily;
1356 void
1357 BNetworkServiceAddressSettings::SetFamily(int family)
1359 fFamily = family;
1364 BNetworkServiceAddressSettings::Protocol() const
1366 return fProtocol;
1370 void
1371 BNetworkServiceAddressSettings::SetProtocol(int protocol)
1373 fProtocol = protocol;
1378 BNetworkServiceAddressSettings::Type() const
1380 return fType;
1384 void
1385 BNetworkServiceAddressSettings::SetType(int type)
1387 fType = type;
1391 const BNetworkAddress&
1392 BNetworkServiceAddressSettings::Address() const
1394 return fAddress;
1398 BNetworkAddress&
1399 BNetworkServiceAddressSettings::Address()
1401 return fAddress;
1405 status_t
1406 BNetworkServiceAddressSettings::GetMessage(BMessage& data) const
1408 // TODO!
1409 return B_NOT_SUPPORTED;
1413 bool
1414 BNetworkServiceAddressSettings::operator==(
1415 const BNetworkServiceAddressSettings& other) const
1417 return Family() == other.Family()
1418 && Type() == other.Type()
1419 && Protocol() == other.Protocol()
1420 && Address() == other.Address();
1424 // #pragma mark - BNetworkServiceSettings
1427 BNetworkServiceSettings::BNetworkServiceSettings()
1429 fFamily(AF_UNSPEC),
1430 fType(-1),
1431 fProtocol(-1),
1432 fPort(-1),
1433 fEnabled(true),
1434 fStandAlone(false)
1439 BNetworkServiceSettings::BNetworkServiceSettings(const BMessage& message)
1441 fType(-1),
1442 fProtocol(-1),
1443 fPort(-1),
1444 fEnabled(true),
1445 fStandAlone(false)
1447 // TODO: user/group is currently ignored!
1449 fName = message.GetString("name");
1451 // Default family/port/protocol/type for all addresses
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";
1458 fFamily = get_address_family(string);
1459 if (fFamily == AF_UNSPEC)
1460 fFamily = AF_INET;
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;
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;
1479 if (message.FindString("type", &string) == B_OK)
1480 fType = parse_type(string);
1481 else
1482 fType = type_for_protocol(fProtocol);
1484 fStandAlone = message.GetBool("stand_alone");
1486 const char* argument;
1487 for (int i = 0; message.FindString("launch", i, &argument) == B_OK; i++) {
1488 fArguments.Add(argument);
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);
1499 if (i == 0 && (fFamily < 0 || fPort < 0)) {
1500 // no address specified
1501 printf("service %s has no address specified\n", Name());
1502 return;
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);
1513 fAddresses.push_back(address);
1518 BNetworkServiceSettings::~BNetworkServiceSettings()
1523 status_t
1524 BNetworkServiceSettings::InitCheck() const
1526 if (!fName.IsEmpty() && !fArguments.IsEmpty() && CountAddresses() > 0)
1527 return B_OK;
1529 return B_BAD_VALUE;
1533 const char*
1534 BNetworkServiceSettings::Name() const
1536 return fName.String();
1540 void
1541 BNetworkServiceSettings::SetName(const char* name)
1543 fName = name;
1547 bool
1548 BNetworkServiceSettings::IsStandAlone() const
1550 return fStandAlone;
1554 void
1555 BNetworkServiceSettings::SetStandAlone(bool alone)
1557 fStandAlone = alone;
1561 bool
1562 BNetworkServiceSettings::IsEnabled() const
1564 return InitCheck() == B_OK && fEnabled;
1568 void
1569 BNetworkServiceSettings::SetEnabled(bool enable)
1571 fEnabled = enable;
1576 BNetworkServiceSettings::Family() const
1578 return fFamily;
1582 void
1583 BNetworkServiceSettings::SetFamily(int family)
1585 fFamily = family;
1590 BNetworkServiceSettings::Protocol() const
1592 return fProtocol;
1596 void
1597 BNetworkServiceSettings::SetProtocol(int protocol)
1599 fProtocol = protocol;
1604 BNetworkServiceSettings::Type() const
1606 return fType;
1610 void
1611 BNetworkServiceSettings::SetType(int type)
1613 fType = type;
1618 BNetworkServiceSettings::Port() const
1620 return fPort;
1624 void
1625 BNetworkServiceSettings::SetPort(int port)
1627 fPort = port;
1631 int32
1632 BNetworkServiceSettings::CountArguments() const
1634 return fArguments.CountStrings();
1638 const char*
1639 BNetworkServiceSettings::ArgumentAt(int32 index) const
1641 return fArguments.StringAt(index);
1645 void
1646 BNetworkServiceSettings::AddArgument(const char* argument)
1648 fArguments.Add(argument);
1652 void
1653 BNetworkServiceSettings::RemoveArgument(int32 index)
1655 fArguments.Remove(index);
1659 int32
1660 BNetworkServiceSettings::CountAddresses() const
1662 return fAddresses.size();
1666 const BNetworkServiceAddressSettings&
1667 BNetworkServiceSettings::AddressAt(int32 index) const
1669 return fAddresses[index];
1673 void
1674 BNetworkServiceSettings::AddAddress(
1675 const BNetworkServiceAddressSettings& address)
1677 fAddresses.push_back(address);
1681 void
1682 BNetworkServiceSettings::RemoveAddress(int32 index)
1684 fAddresses.erase(fAddresses.begin() + index);
1688 /*! This is a convenience method that returns the current state of the
1689 service, independent of the current settings.
1691 bool
1692 BNetworkServiceSettings::IsRunning() const
1694 BMessage request(kMsgIsServiceRunning);
1695 request.AddString("name", fName);
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");
1703 return false;
1707 status_t
1708 BNetworkServiceSettings::GetMessage(BMessage& data) const
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);
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);
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;
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;
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;
1750 return status;