1 /* 2 * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <NetworkAddress.h> 8 9 #include <NetworkInterface.h> 10 #include <NetworkRoster.h> 11 12 #include <arpa/inet.h> 13 #include <errno.h> 14 #include <netinet/in.h> 15 #include <stdio.h> 16 #include <sys/sockio.h> 17 18 19 BNetworkAddress::BNetworkAddress(const char* host, uint16 port, uint32 flags) 20 { 21 SetTo(host, port, flags); 22 } 23 24 25 BNetworkAddress::BNetworkAddress(const char* host, const char* service, 26 uint32 flags) 27 { 28 SetTo(host, service, flags); 29 } 30 31 32 BNetworkAddress::BNetworkAddress(int family, const char* host, uint16 port, 33 uint32 flags) 34 { 35 SetTo(family, host, port, flags); 36 } 37 38 39 BNetworkAddress::BNetworkAddress(int family, const char* host, 40 const char* service, uint32 flags) 41 { 42 SetTo(family, host, service, flags); 43 } 44 45 46 BNetworkAddress::BNetworkAddress(const sockaddr& address) 47 { 48 SetTo(address); 49 } 50 51 52 BNetworkAddress::BNetworkAddress(const sockaddr_storage& address) 53 { 54 SetTo(address); 55 } 56 57 58 BNetworkAddress::BNetworkAddress(const sockaddr_in& address) 59 { 60 SetTo(address); 61 } 62 63 64 BNetworkAddress::BNetworkAddress(const sockaddr_in6& address) 65 { 66 SetTo(address); 67 } 68 69 70 BNetworkAddress::BNetworkAddress(const sockaddr_dl& address) 71 { 72 SetTo(address); 73 } 74 75 76 BNetworkAddress::BNetworkAddress(const in_addr_t address) 77 { 78 SetTo(address); 79 } 80 81 82 BNetworkAddress::BNetworkAddress(const in6_addr* address) 83 { 84 SetTo(address); 85 } 86 87 88 BNetworkAddress::BNetworkAddress(const BNetworkAddress& other) 89 : 90 fAddress(other.fAddress), 91 fStatus(other.fStatus) 92 { 93 } 94 95 96 BNetworkAddress::BNetworkAddress(BMessage* archive) 97 { 98 // TODO: implement me 99 fStatus = B_NO_INIT; 100 } 101 102 103 BNetworkAddress::BNetworkAddress() 104 { 105 Unset(); 106 } 107 108 109 BNetworkAddress::~BNetworkAddress() 110 { 111 } 112 113 114 status_t 115 BNetworkAddress::InitCheck() const 116 { 117 return fStatus; 118 } 119 120 121 void 122 BNetworkAddress::Unset() 123 { 124 fAddress.ss_family = AF_UNSPEC; 125 fAddress.ss_len = 2; 126 fStatus = B_OK; 127 } 128 129 130 status_t 131 BNetworkAddress::SetTo(const char* host, uint16 port, uint32 flags) 132 { 133 BNetworkAddressResolver resolver; 134 status_t status = resolver.SetTo(host, port, flags); 135 if (status != B_OK) 136 return status; 137 138 // Prefer IPv6 addresses 139 140 uint32 cookie = 0; 141 status = resolver.GetNextAddress(AF_INET6, &cookie, *this); 142 if (status == B_OK) 143 return B_OK; 144 145 cookie = 0; 146 return resolver.GetNextAddress(&cookie, *this); 147 } 148 149 150 status_t 151 BNetworkAddress::SetTo(const char* host, const char* service, uint32 flags) 152 { 153 BNetworkAddressResolver resolver; 154 status_t status = resolver.SetTo(host, service, flags); 155 if (status != B_OK) 156 return status; 157 158 // Prefer IPv6 addresses 159 160 uint32 cookie = 0; 161 status = resolver.GetNextAddress(AF_INET6, &cookie, *this); 162 if (status == B_OK) 163 return B_OK; 164 165 cookie = 0; 166 return resolver.GetNextAddress(&cookie, *this); 167 } 168 169 170 status_t 171 BNetworkAddress::SetTo(int family, const char* host, uint16 port, uint32 flags) 172 { 173 BNetworkAddressResolver resolver; 174 status_t status = resolver.SetTo(family, host, port, flags); 175 if (status != B_OK) 176 return status; 177 178 uint32 cookie = 0; 179 return resolver.GetNextAddress(&cookie, *this); 180 } 181 182 183 status_t 184 BNetworkAddress::SetTo(int family, const char* host, const char* service, 185 uint32 flags) 186 { 187 BNetworkAddressResolver resolver; 188 status_t status = resolver.SetTo(family, host, service, flags); 189 if (status != B_OK) 190 return status; 191 192 uint32 cookie = 0; 193 return resolver.GetNextAddress(&cookie, *this); 194 } 195 196 197 void 198 BNetworkAddress::SetTo(const sockaddr& address) 199 { 200 if (address.sa_family == AF_UNSPEC) { 201 Unset(); 202 return; 203 } 204 205 size_t length = min_c(sizeof(sockaddr_storage), address.sa_len); 206 switch (address.sa_family) { 207 case AF_INET: 208 length = sizeof(sockaddr_in); 209 break; 210 case AF_INET6: 211 length = sizeof(sockaddr_in6); 212 break; 213 case AF_LINK: 214 { 215 sockaddr_dl& link = (sockaddr_dl&)address; 216 length = sizeof(sockaddr_dl) - sizeof(link.sdl_data) + link.sdl_alen 217 + link.sdl_nlen + link.sdl_slen; 218 break; 219 } 220 } 221 222 SetTo(address, length); 223 } 224 225 226 void 227 BNetworkAddress::SetTo(const sockaddr& address, size_t length) 228 { 229 if (address.sa_family == AF_UNSPEC || length == 0) { 230 Unset(); 231 return; 232 } 233 234 memcpy(&fAddress, &address, length); 235 fAddress.ss_len = length; 236 fStatus = B_OK; 237 } 238 239 240 void 241 BNetworkAddress::SetTo(const sockaddr_storage& address) 242 { 243 SetTo((sockaddr&)address); 244 } 245 246 247 void 248 BNetworkAddress::SetTo(const sockaddr_in& address) 249 { 250 SetTo((sockaddr&)address); 251 } 252 253 254 void 255 BNetworkAddress::SetTo(const sockaddr_in6& address) 256 { 257 SetTo((sockaddr&)address); 258 } 259 260 261 void 262 BNetworkAddress::SetTo(const sockaddr_dl& address) 263 { 264 SetTo((sockaddr&)address); 265 } 266 267 268 void 269 BNetworkAddress::SetTo(const in_addr_t inetAddress) 270 { 271 sockaddr_in& address = (sockaddr_in&)fAddress; 272 memset(&fAddress, 0, sizeof(sockaddr_storage)); 273 274 address.sin_family = AF_INET; 275 address.sin_len = sizeof(sockaddr_in); 276 address.sin_addr.s_addr = inetAddress; 277 fStatus = B_OK; 278 } 279 280 281 void 282 BNetworkAddress::SetTo(const in6_addr* inet6Address) 283 { 284 sockaddr_in6& address = (sockaddr_in6&)fAddress; 285 memset(&fAddress, 0, sizeof(sockaddr_storage)); 286 287 address.sin6_family = AF_INET6; 288 address.sin6_len = sizeof(sockaddr_in6); 289 memcpy(address.sin6_addr.s6_addr, inet6Address, 290 sizeof(address.sin6_addr.s6_addr)); 291 fStatus = B_OK; 292 } 293 294 295 void 296 BNetworkAddress::SetTo(const BNetworkAddress& other) 297 { 298 fAddress = other.fAddress; 299 fStatus = other.fStatus; 300 } 301 302 303 status_t 304 BNetworkAddress::SetToBroadcast(int family, uint16 port) 305 { 306 if (family != AF_INET) 307 return fStatus = B_NOT_SUPPORTED; 308 309 memset(&fAddress, 0, sizeof(sockaddr_storage)); 310 fAddress.ss_family = family; 311 ((sockaddr_in&)fAddress).sin_addr.s_addr = INADDR_BROADCAST; 312 313 SetPort(port); 314 return fStatus = B_OK; 315 } 316 317 318 status_t 319 BNetworkAddress::SetToLocal() 320 { 321 // TODO: choose a local address from the network interfaces 322 return B_NOT_SUPPORTED; 323 } 324 325 326 status_t 327 BNetworkAddress::SetToLoopback() 328 { 329 return SetTo("localhost"); 330 } 331 332 333 status_t 334 BNetworkAddress::SetToMask(int family, uint32 prefixLength) 335 { 336 switch (family) { 337 case AF_INET: 338 { 339 if (prefixLength > 32) 340 return B_BAD_VALUE; 341 342 sockaddr_in& mask = (sockaddr_in&)fAddress; 343 memset(&fAddress, 0, sizeof(sockaddr_storage)); 344 mask.sin_family = AF_INET; 345 mask.sin_len = sizeof(sockaddr_in); 346 347 uint32 hostMask = 0; 348 for (uint8 i = 32; i > 32 - prefixLength; i--) 349 hostMask |= 1 << (i - 1); 350 351 mask.sin_addr.s_addr = htonl(hostMask); 352 break; 353 } 354 355 case AF_INET6: 356 { 357 if (prefixLength > 128) 358 return B_BAD_VALUE; 359 360 sockaddr_in6& mask = (sockaddr_in6&)fAddress; 361 memset(&fAddress, 0, sizeof(sockaddr_storage)); 362 mask.sin6_family = AF_INET6; 363 mask.sin6_len = sizeof(sockaddr_in6); 364 365 for (uint8 i = 0; i < sizeof(in6_addr); i++, prefixLength -= 8) { 366 if (prefixLength < 8) { 367 mask.sin6_addr.s6_addr[i] 368 = (uint8)(0xff << (8 - prefixLength)); 369 break; 370 } 371 372 mask.sin6_addr.s6_addr[i] = 0xff; 373 } 374 break; 375 } 376 377 default: 378 return B_NOT_SUPPORTED; 379 } 380 381 return B_OK; 382 } 383 384 385 status_t 386 BNetworkAddress::SetToWildcard(int family) 387 { 388 return SetTo(family, NULL); 389 } 390 391 392 void 393 BNetworkAddress::SetPort(uint16 port) 394 { 395 switch (fAddress.ss_family) { 396 case AF_INET: 397 ((sockaddr_in&)fAddress).sin_port = htons(port); 398 break; 399 400 case AF_INET6: 401 ((sockaddr_in6&)fAddress).sin6_port = htons(port); 402 break; 403 404 default: 405 break; 406 } 407 } 408 409 410 void 411 BNetworkAddress::SetToLinkLevel(uint8* address, size_t length) 412 { 413 // TODO: implement me! 414 } 415 416 417 void 418 BNetworkAddress::SetToLinkLevel(const char* name) 419 { 420 // TODO: implement me! 421 } 422 423 424 void 425 BNetworkAddress::SetToLinkLevel(uint32 index) 426 { 427 // TODO: implement me! 428 } 429 430 431 void 432 BNetworkAddress::SetLinkLevelIndex(uint32 index) 433 { 434 // TODO: implement me! 435 } 436 437 438 void 439 BNetworkAddress::SetLinkLevelType(uint32 type) 440 { 441 // TODO: implement me! 442 } 443 444 445 void 446 BNetworkAddress::SetLinkLevelFrameType(uint32 frameType) 447 { 448 // TODO: implement me! 449 } 450 451 452 int 453 BNetworkAddress::Family() const 454 { 455 return fAddress.ss_family; 456 } 457 458 459 uint16 460 BNetworkAddress::Port() const 461 { 462 switch (fAddress.ss_family) { 463 case AF_INET: 464 return ntohs(((sockaddr_in&)fAddress).sin_port); 465 466 case AF_INET6: 467 return ntohs(((sockaddr_in6&)fAddress).sin6_port); 468 469 default: 470 return 0; 471 } 472 } 473 474 475 size_t 476 BNetworkAddress::Length() const 477 { 478 return fAddress.ss_len; 479 } 480 481 482 const sockaddr& 483 BNetworkAddress::SockAddr() const 484 { 485 return (const sockaddr&)fAddress; 486 } 487 488 489 bool 490 BNetworkAddress::IsEmpty() const 491 { 492 return fAddress.ss_len == 0 || fAddress.ss_family == AF_UNSPEC; 493 } 494 495 496 bool 497 BNetworkAddress::IsWildcard() const 498 { 499 switch (fAddress.ss_family) { 500 case AF_INET: 501 return ((sockaddr_in&)fAddress).sin_addr.s_addr == INADDR_ANY; 502 503 case AF_INET6: 504 return !memcmp(&((sockaddr_in6&)fAddress).sin6_addr, &in6addr_any, 505 sizeof(in6_addr)); 506 507 default: 508 return false; 509 } 510 } 511 512 513 bool 514 BNetworkAddress::IsBroadcast() const 515 { 516 switch (fAddress.ss_family) { 517 case AF_INET: 518 return ((sockaddr_in&)fAddress).sin_addr.s_addr == INADDR_BROADCAST; 519 520 case AF_INET6: 521 // There is no broadcast in IPv6, only multicast/anycast 522 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr); 523 524 default: 525 return false; 526 } 527 } 528 529 530 bool 531 BNetworkAddress::IsMulticast() const 532 { 533 switch (fAddress.ss_family) { 534 case AF_INET: 535 return IN_MULTICAST(((sockaddr_in&)fAddress).sin_addr.s_addr); 536 537 case AF_INET6: 538 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr); 539 540 default: 541 return false; 542 } 543 } 544 545 546 bool 547 BNetworkAddress::IsMulticastGlobal() const 548 { 549 switch (fAddress.ss_family) { 550 case AF_INET6: 551 return IN6_IS_ADDR_MC_GLOBAL(&((sockaddr_in6&)fAddress).sin6_addr); 552 553 default: 554 return false; 555 } 556 } 557 558 559 bool 560 BNetworkAddress::IsMulticastNodeLocal() const 561 { 562 switch (fAddress.ss_family) { 563 case AF_INET6: 564 return IN6_IS_ADDR_MC_NODELOCAL( 565 &((sockaddr_in6&)fAddress).sin6_addr); 566 567 default: 568 return false; 569 } 570 } 571 572 573 bool 574 BNetworkAddress::IsMulticastLinkLocal() const 575 { 576 switch (fAddress.ss_family) { 577 case AF_INET6: 578 return IN6_IS_ADDR_MC_LINKLOCAL( 579 &((sockaddr_in6&)fAddress).sin6_addr); 580 581 default: 582 return false; 583 } 584 } 585 586 587 bool 588 BNetworkAddress::IsMulticastSiteLocal() const 589 { 590 switch (fAddress.ss_family) { 591 case AF_INET6: 592 return IN6_IS_ADDR_MC_SITELOCAL( 593 &((sockaddr_in6&)fAddress).sin6_addr); 594 595 default: 596 return false; 597 } 598 } 599 600 601 bool 602 BNetworkAddress::IsMulticastOrgLocal() const 603 { 604 switch (fAddress.ss_family) { 605 case AF_INET6: 606 return IN6_IS_ADDR_MC_ORGLOCAL( 607 &((sockaddr_in6&)fAddress).sin6_addr); 608 609 default: 610 return false; 611 } 612 } 613 614 615 bool 616 BNetworkAddress::IsLinkLocal() const 617 { 618 // TODO: ipv4 619 switch (fAddress.ss_family) { 620 case AF_INET6: 621 return IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6&)fAddress).sin6_addr); 622 623 default: 624 return false; 625 } 626 } 627 628 629 bool 630 BNetworkAddress::IsSiteLocal() const 631 { 632 switch (fAddress.ss_family) { 633 case AF_INET6: 634 return IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6&)fAddress).sin6_addr); 635 636 default: 637 return false; 638 } 639 } 640 641 642 bool 643 BNetworkAddress::IsLocal() const 644 { 645 BNetworkRoster& roster = BNetworkRoster::Default(); 646 647 BNetworkInterface interface; 648 uint32 cookie = 0; 649 650 while (roster.GetNextInterface(&cookie, interface) == B_OK) { 651 int32 count = interface.CountAddresses(); 652 for (int32 j = 0; j < count; j++) { 653 BNetworkInterfaceAddress address; 654 if (interface.GetAddressAt(j, address) != B_OK) 655 break; 656 657 if (Equals(address.Address(), false)) 658 return true; 659 } 660 } 661 662 return false; 663 } 664 665 666 ssize_t 667 BNetworkAddress::PrefixLength() const 668 { 669 switch (fAddress.ss_family) { 670 case AF_INET: 671 { 672 sockaddr_in& mask = (sockaddr_in&)fAddress; 673 674 ssize_t result = 0; 675 uint32 hostMask = ntohl(mask.sin_addr.s_addr); 676 for (uint8 i = 32; i > 0; i--) { 677 if ((hostMask & (1 << (i - 1))) == 0) 678 break; 679 result++; 680 } 681 682 return result; 683 } 684 685 case AF_INET6: 686 { 687 sockaddr_in6& mask = (sockaddr_in6&)fAddress; 688 689 ssize_t result = 0; 690 for (uint8 i = 0; i < sizeof(in6_addr); i++) { 691 for (uint8 j = 0; j < 8; j++) { 692 if (!(mask.sin6_addr.s6_addr[i] & (1 << j))) 693 return result; 694 result++; 695 } 696 } 697 698 return 128; 699 } 700 701 default: 702 return B_NOT_SUPPORTED; 703 } 704 } 705 706 707 uint32 708 BNetworkAddress::LinkLevelIndex() const 709 { 710 return ((sockaddr_dl&)fAddress).sdl_index; 711 } 712 713 714 BString 715 BNetworkAddress::LinkLevelInterface() const 716 { 717 sockaddr_dl& address = (sockaddr_dl&)fAddress; 718 if (address.sdl_nlen == 0) 719 return ""; 720 721 BString name; 722 name.SetTo((const char*)address.sdl_data, address.sdl_nlen); 723 724 return name; 725 } 726 727 728 uint32 729 BNetworkAddress::LinkLevelType() const 730 { 731 return ((sockaddr_dl&)fAddress).sdl_type; 732 } 733 734 735 uint32 736 BNetworkAddress::LinkLevelFrameType() const 737 { 738 return ((sockaddr_dl&)fAddress).sdl_e_type; 739 } 740 741 742 uint8* 743 BNetworkAddress::LinkLevelAddress() const 744 { 745 return LLADDR(&(sockaddr_dl&)fAddress); 746 } 747 748 749 size_t 750 BNetworkAddress::LinkLevelAddressLength() const 751 { 752 return ((sockaddr_dl&)fAddress).sdl_alen; 753 } 754 755 756 status_t 757 BNetworkAddress::ResolveForDestination(const BNetworkAddress& destination) 758 { 759 if (!IsWildcard()) 760 return B_OK; 761 if (destination.fAddress.ss_family != fAddress.ss_family) 762 return B_BAD_VALUE; 763 764 char buffer[2048]; 765 memset(buffer, 0, sizeof(buffer)); 766 767 route_entry* route = (route_entry*)buffer; 768 route->destination = (sockaddr*)&destination.fAddress; 769 770 int socket = ::socket(fAddress.ss_family, SOCK_DGRAM, 0); 771 if (socket < 0) 772 return errno; 773 774 if (ioctl(socket, SIOCGETRT, route, sizeof(buffer)) != 0) { 775 close(socket); 776 return errno; 777 } 778 779 uint16 port = Port(); 780 memcpy(&fAddress, route->source, sizeof(sockaddr_storage)); 781 SetPort(port); 782 783 return B_OK; 784 } 785 786 787 status_t 788 BNetworkAddress::ResolveTo(const BNetworkAddress& address) 789 { 790 if (!IsWildcard()) 791 return B_OK; 792 if (address.fAddress.ss_family != fAddress.ss_family) 793 return B_BAD_VALUE; 794 795 uint16 port = Port(); 796 *this = address; 797 SetPort(port); 798 799 return B_OK; 800 } 801 802 803 BString 804 BNetworkAddress::ToString(bool includePort) const 805 { 806 char buffer[512]; 807 808 switch (fAddress.ss_family) { 809 case AF_INET: 810 inet_ntop(AF_INET, &((sockaddr_in&)fAddress).sin_addr, buffer, 811 sizeof(buffer)); 812 break; 813 814 case AF_INET6: 815 inet_ntop(AF_INET6, &((sockaddr_in6&)fAddress).sin6_addr, 816 buffer, sizeof(buffer)); 817 break; 818 819 case AF_LINK: 820 { 821 uint8 *byte = LinkLevelAddress(); 822 char* target = buffer; 823 int bytesLeft = sizeof(buffer); 824 target[0] = '\0'; 825 826 for (size_t i = 0; i < LinkLevelAddressLength(); i++) { 827 if (i != 0 && bytesLeft > 1) { 828 target[0] = ':'; 829 target[1] = '\0'; 830 target++; 831 bytesLeft--; 832 } 833 834 int bytesWritten = snprintf(target, bytesLeft, "%02x", byte[i]); 835 if (bytesWritten >= bytesLeft) 836 break; 837 838 target += bytesWritten; 839 bytesLeft -= bytesWritten; 840 } 841 break; 842 } 843 844 default: 845 return ""; 846 } 847 848 BString address = buffer; 849 if (includePort && Port() != 0) { 850 if (fAddress.ss_family == AF_INET6) { 851 address = "["; 852 address += buffer; 853 address += "]"; 854 } 855 856 snprintf(buffer, sizeof(buffer), ":%u", Port()); 857 address += buffer; 858 } 859 860 return address; 861 } 862 863 864 BString 865 BNetworkAddress::HostName() const 866 { 867 // TODO: implement host name lookup 868 return ToString(false); 869 } 870 871 872 BString 873 BNetworkAddress::ServiceName() const 874 { 875 // TODO: implement service lookup 876 BString portName; 877 portName << Port(); 878 return portName; 879 } 880 881 882 status_t 883 BNetworkAddress::Archive(BMessage* into, bool deep) const 884 { 885 // TODO: implement me! 886 return B_ERROR; 887 } 888 889 890 /*static*/ BArchivable* 891 BNetworkAddress::Instantiate(BMessage* archive) 892 { 893 if (archive != NULL) 894 return new BNetworkAddress(archive); 895 896 return NULL; 897 } 898 899 900 bool 901 BNetworkAddress::Equals(const BNetworkAddress& other, bool includePort) const 902 { 903 if (IsEmpty() && other.IsEmpty()) 904 return true; 905 906 if (Family() != other.Family() 907 || (includePort && Port() != other.Port())) 908 return false; 909 910 switch (fAddress.ss_family) { 911 case AF_INET: 912 { 913 sockaddr_in& address = (sockaddr_in&)fAddress; 914 sockaddr_in& otherAddress = (sockaddr_in&)other.fAddress; 915 return memcmp(&address.sin_addr, &otherAddress.sin_addr, 916 sizeof(address.sin_addr)) == 0; 917 } 918 919 case AF_INET6: 920 { 921 sockaddr_in6& address = (sockaddr_in6&)fAddress; 922 sockaddr_in6& otherAddress = (sockaddr_in6&)other.fAddress; 923 return memcmp(&address.sin6_addr, &otherAddress.sin6_addr, 924 sizeof(address.sin6_addr)) == 0; 925 } 926 927 default: 928 if (fAddress.ss_len != other.fAddress.ss_len) 929 return false; 930 931 return memcmp(&fAddress, &other.fAddress, fAddress.ss_len); 932 } 933 } 934 935 936 BNetworkAddress& 937 BNetworkAddress::operator=(const BNetworkAddress& other) 938 { 939 memcpy(&fAddress, &other.fAddress, other.fAddress.ss_len); 940 fStatus = other.fStatus; 941 942 return *this; 943 } 944 945 946 bool 947 BNetworkAddress::operator==(const BNetworkAddress& other) const 948 { 949 return Equals(other); 950 } 951 952 953 bool 954 BNetworkAddress::operator!=(const BNetworkAddress& other) const 955 { 956 return !Equals(other); 957 } 958 959 960 bool 961 BNetworkAddress::operator<(const BNetworkAddress& other) const 962 { 963 if (Family() < other.Family()) 964 return true; 965 if (Family() > other.Family()) 966 return false; 967 968 int compare; 969 970 switch (fAddress.ss_family) { 971 default: 972 case AF_INET: 973 { 974 sockaddr_in& address = (sockaddr_in&)fAddress; 975 sockaddr_in& otherAddress = (sockaddr_in&)other.fAddress; 976 compare = memcmp(&address.sin_addr, &otherAddress.sin_addr, 977 sizeof(address.sin_addr)); 978 break; 979 } 980 981 case AF_INET6: 982 { 983 sockaddr_in6& address = (sockaddr_in6&)fAddress; 984 sockaddr_in6& otherAddress = (sockaddr_in6&)other.fAddress; 985 compare = memcmp(&address.sin6_addr, &otherAddress.sin6_addr, 986 sizeof(address.sin6_addr)); 987 break; 988 } 989 } 990 991 if (compare < 0) 992 return true; 993 if (compare > 0) 994 return false; 995 996 return Port() < other.Port(); 997 } 998 999 1000 BNetworkAddress::operator const sockaddr*() const 1001 { 1002 return (const sockaddr*)&fAddress; 1003 } 1004 1005 1006 BNetworkAddress::operator const sockaddr&() const 1007 { 1008 return (const sockaddr&)fAddress; 1009 } 1010