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