1/* 2 * Copyright 2010-2011, 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 <ctype.h> 14#include <errno.h> 15#include <netinet/in.h> 16#include <stdio.h> 17#include <sys/sockio.h> 18 19 20/* The GCC builtin below only exists in > GCC 3.4 21 * Benefits include faster execution time as the builtin 22 * uses a bitcounting cpu instruction if it exists 23 */ 24#if __GNUC__ > 3 25# define addr_bitcount(bitfield) __builtin_popcount(bitfield) 26#else 27static ssize_t 28addr_bitcount(uint32 bitfield) 29{ 30 ssize_t result = 0; 31 for (uint8 i = 32; i > 0; i--) { 32 if ((bitfield & (1 << (i - 1))) == 0) 33 break; 34 result++; 35 } 36 return result; 37} 38#endif 39 40 41static uint8 42from_hex(char hex) 43{ 44 if (isdigit(hex)) 45 return hex - '0'; 46 47 return tolower(hex) - 'a' + 10; 48} 49 50 51// #pragma mark - 52 53 54BNetworkAddress::BNetworkAddress() 55{ 56 Unset(); 57} 58 59 60BNetworkAddress::BNetworkAddress(const char* host, uint16 port, uint32 flags) 61{ 62 SetTo(host, port, flags); 63} 64 65 66BNetworkAddress::BNetworkAddress(const char* host, const char* service, 67 uint32 flags) 68{ 69 SetTo(host, service, flags); 70} 71 72 73BNetworkAddress::BNetworkAddress(int family, const char* host, uint16 port, 74 uint32 flags) 75{ 76 SetTo(family, host, port, flags); 77} 78 79 80BNetworkAddress::BNetworkAddress(int family, const char* host, 81 const char* service, uint32 flags) 82{ 83 SetTo(family, host, service, flags); 84} 85 86 87BNetworkAddress::BNetworkAddress(const sockaddr& address) 88{ 89 SetTo(address); 90} 91 92 93BNetworkAddress::BNetworkAddress(const sockaddr_storage& address) 94{ 95 SetTo(address); 96} 97 98 99BNetworkAddress::BNetworkAddress(const sockaddr_in& address) 100{ 101 SetTo(address); 102} 103 104 105BNetworkAddress::BNetworkAddress(const sockaddr_in6& address) 106{ 107 SetTo(address); 108} 109 110 111BNetworkAddress::BNetworkAddress(const sockaddr_dl& address) 112{ 113 SetTo(address); 114} 115 116 117BNetworkAddress::BNetworkAddress(in_addr_t address, uint16 port) 118{ 119 SetTo(address, port); 120} 121 122 123BNetworkAddress::BNetworkAddress(const in6_addr& address, uint16 port) 124{ 125 SetTo(address, port); 126} 127 128 129BNetworkAddress::BNetworkAddress(const BNetworkAddress& other) 130 : 131 fAddress(other.fAddress), 132 fStatus(other.fStatus) 133{ 134} 135 136 137BNetworkAddress::~BNetworkAddress() 138{ 139} 140 141 142status_t 143BNetworkAddress::InitCheck() const 144{ 145 return fStatus; 146} 147 148 149void 150BNetworkAddress::Unset() 151{ 152 fAddress.ss_family = AF_UNSPEC; 153 fAddress.ss_len = 2; 154 fStatus = B_OK; 155} 156 157 158status_t 159BNetworkAddress::SetTo(const char* host, uint16 port, uint32 flags) 160{ 161 BNetworkAddressResolver resolver; 162 status_t status = resolver.SetTo(host, port, flags); 163 if (status != B_OK) 164 return status; 165 166 // Prefer IPv6 addresses 167 168 uint32 cookie = 0; 169 status = resolver.GetNextAddress(AF_INET6, &cookie, *this); 170 if (status == B_OK) 171 return B_OK; 172 173 cookie = 0; 174 return resolver.GetNextAddress(&cookie, *this); 175} 176 177 178status_t 179BNetworkAddress::SetTo(const char* host, const char* service, uint32 flags) 180{ 181 BNetworkAddressResolver resolver; 182 status_t status = resolver.SetTo(host, service, flags); 183 if (status != B_OK) 184 return status; 185 186 // Prefer IPv6 addresses 187 188 uint32 cookie = 0; 189 status = resolver.GetNextAddress(AF_INET6, &cookie, *this); 190 if (status == B_OK) 191 return B_OK; 192 193 cookie = 0; 194 return resolver.GetNextAddress(&cookie, *this); 195} 196 197 198status_t 199BNetworkAddress::SetTo(int family, const char* host, uint16 port, uint32 flags) 200{ 201 if (family == AF_LINK) { 202 if (port != 0) 203 return B_BAD_VALUE; 204 return _ParseLinkAddress(host); 205 } 206 207 BNetworkAddressResolver resolver; 208 status_t status = resolver.SetTo(family, host, port, flags); 209 if (status != B_OK) 210 return status; 211 212 uint32 cookie = 0; 213 return resolver.GetNextAddress(&cookie, *this); 214} 215 216 217status_t 218BNetworkAddress::SetTo(int family, const char* host, const char* service, 219 uint32 flags) 220{ 221 if (family == AF_LINK) { 222 if (service != NULL) 223 return B_BAD_VALUE; 224 return _ParseLinkAddress(host); 225 } 226 227 BNetworkAddressResolver resolver; 228 status_t status = resolver.SetTo(family, host, service, flags); 229 if (status != B_OK) 230 return status; 231 232 uint32 cookie = 0; 233 return resolver.GetNextAddress(&cookie, *this); 234} 235 236 237void 238BNetworkAddress::SetTo(const sockaddr& address) 239{ 240 if (address.sa_family == AF_UNSPEC) { 241 Unset(); 242 return; 243 } 244 245 size_t length = min_c(sizeof(sockaddr_storage), address.sa_len); 246 switch (address.sa_family) { 247 case AF_INET: 248 length = sizeof(sockaddr_in); 249 break; 250 case AF_INET6: 251 length = sizeof(sockaddr_in6); 252 break; 253 case AF_LINK: 254 { 255 sockaddr_dl& link = (sockaddr_dl&)address; 256 length = sizeof(sockaddr_dl) - sizeof(link.sdl_data) + link.sdl_alen 257 + link.sdl_nlen + link.sdl_slen; 258 break; 259 } 260 } 261 262 SetTo(address, length); 263} 264 265 266void 267BNetworkAddress::SetTo(const sockaddr& address, size_t length) 268{ 269 if (address.sa_family == AF_UNSPEC || length == 0) { 270 Unset(); 271 return; 272 } 273 274 memcpy(&fAddress, &address, length); 275 fAddress.ss_len = length; 276 fStatus = B_OK; 277} 278 279 280void 281BNetworkAddress::SetTo(const sockaddr_storage& address) 282{ 283 SetTo((sockaddr&)address); 284} 285 286 287void 288BNetworkAddress::SetTo(const sockaddr_in& address) 289{ 290 SetTo((sockaddr&)address); 291} 292 293 294void 295BNetworkAddress::SetTo(const sockaddr_in6& address) 296{ 297 SetTo((sockaddr&)address); 298} 299 300 301void 302BNetworkAddress::SetTo(const sockaddr_dl& address) 303{ 304 SetTo((sockaddr&)address); 305} 306 307 308void 309BNetworkAddress::SetTo(in_addr_t inetAddress, uint16 port) 310{ 311 memset(&fAddress, 0, sizeof(sockaddr_storage)); 312 313 fAddress.ss_family = AF_INET; 314 fAddress.ss_len = sizeof(sockaddr_in); 315 SetAddress(inetAddress); 316 SetPort(port); 317 318 fStatus = B_OK; 319} 320 321 322void 323BNetworkAddress::SetTo(const in6_addr& inet6Address, uint16 port) 324{ 325 memset(&fAddress, 0, sizeof(sockaddr_storage)); 326 327 fAddress.ss_family = AF_INET6; 328 fAddress.ss_len = sizeof(sockaddr_in6); 329 SetAddress(inet6Address); 330 SetPort(port); 331 332 fStatus = B_OK; 333} 334 335 336void 337BNetworkAddress::SetTo(const BNetworkAddress& other) 338{ 339 fAddress = other.fAddress; 340 fStatus = other.fStatus; 341} 342 343 344status_t 345BNetworkAddress::SetToBroadcast(int family, uint16 port) 346{ 347 if (family != AF_INET) 348 return fStatus = B_NOT_SUPPORTED; 349 350 SetTo(INADDR_BROADCAST, port); 351 return B_OK; 352} 353 354 355status_t 356BNetworkAddress::SetToLocal(int family, uint16 port) 357{ 358 // TODO: choose a local address from the network interfaces 359 return fStatus = B_NOT_SUPPORTED; 360} 361 362 363status_t 364BNetworkAddress::SetToLoopback(int family, uint16 port) 365{ 366 switch (family) { 367 // TODO: choose family depending on availability of IPv6 368 case AF_UNSPEC: 369 case AF_INET: 370 SetTo(htonl(INADDR_LOOPBACK), port); 371 break; 372 373 case AF_INET6: 374 SetTo(in6addr_loopback, port); 375 break; 376 377 default: 378 return fStatus = B_NOT_SUPPORTED; 379 } 380 381 return B_OK; 382} 383 384 385status_t 386BNetworkAddress::SetToMask(int family, uint32 prefixLength) 387{ 388 switch (family) { 389 case AF_INET: 390 { 391 if (prefixLength > 32) 392 return B_BAD_VALUE; 393 394 sockaddr_in& mask = (sockaddr_in&)fAddress; 395 memset(&fAddress, 0, sizeof(sockaddr_storage)); 396 mask.sin_family = AF_INET; 397 mask.sin_len = sizeof(sockaddr_in); 398 399 uint32 hostMask = 0; 400 for (uint8 i = 32; i > 32 - prefixLength; i--) 401 hostMask |= 1 << (i - 1); 402 403 mask.sin_addr.s_addr = htonl(hostMask); 404 break; 405 } 406 407 case AF_INET6: 408 { 409 if (prefixLength > 128) 410 return B_BAD_VALUE; 411 412 sockaddr_in6& mask = (sockaddr_in6&)fAddress; 413 memset(&fAddress, 0, sizeof(sockaddr_storage)); 414 mask.sin6_family = AF_INET6; 415 mask.sin6_len = sizeof(sockaddr_in6); 416 417 for (uint8 i = 0; i < sizeof(in6_addr); i++, prefixLength -= 8) { 418 if (prefixLength < 8) { 419 mask.sin6_addr.s6_addr[i] 420 = (uint8)(0xff << (8 - prefixLength)); 421 break; 422 } 423 424 mask.sin6_addr.s6_addr[i] = 0xff; 425 } 426 break; 427 } 428 429 default: 430 return fStatus = B_NOT_SUPPORTED; 431 } 432 433 return fStatus = B_OK; 434} 435 436 437status_t 438BNetworkAddress::SetToWildcard(int family, uint16 port) 439{ 440 switch (family) { 441 case AF_INET: 442 SetTo(INADDR_ANY, port); 443 break; 444 445 case AF_INET6: 446 SetTo(in6addr_any, port); 447 break; 448 449 default: 450 return fStatus = B_NOT_SUPPORTED; 451 } 452 453 return B_OK; 454} 455 456 457status_t 458BNetworkAddress::SetAddress(in_addr_t inetAddress) 459{ 460 if (Family() != AF_INET) 461 return B_BAD_VALUE; 462 463 sockaddr_in& address = (sockaddr_in&)fAddress; 464 address.sin_addr.s_addr = inetAddress; 465 return B_OK; 466} 467 468 469status_t 470BNetworkAddress::SetAddress(const in6_addr& inet6Address) 471{ 472 if (Family() != AF_INET6) 473 return B_BAD_VALUE; 474 475 sockaddr_in6& address = (sockaddr_in6&)fAddress; 476 memcpy(address.sin6_addr.s6_addr, &inet6Address, 477 sizeof(address.sin6_addr.s6_addr)); 478 return B_OK; 479} 480 481 482void 483BNetworkAddress::SetPort(uint16 port) 484{ 485 switch (fAddress.ss_family) { 486 case AF_INET: 487 ((sockaddr_in&)fAddress).sin_port = htons(port); 488 break; 489 490 case AF_INET6: 491 ((sockaddr_in6&)fAddress).sin6_port = htons(port); 492 break; 493 494 default: 495 break; 496 } 497} 498 499 500void 501BNetworkAddress::SetToLinkLevel(uint8* address, size_t length) 502{ 503 sockaddr_dl& link = (sockaddr_dl&)fAddress; 504 memset(&link, 0, sizeof(sockaddr_dl)); 505 506 link.sdl_family = AF_LINK; 507 link.sdl_alen = length; 508 memcpy(LLADDR(&link), address, length); 509 510 link.sdl_len = sizeof(sockaddr_dl); 511 if (length > sizeof(link.sdl_data)) 512 link.sdl_len += length - sizeof(link.sdl_data); 513} 514 515 516void 517BNetworkAddress::SetToLinkLevel(const char* name) 518{ 519 sockaddr_dl& link = (sockaddr_dl&)fAddress; 520 memset(&link, 0, sizeof(sockaddr_dl)); 521 522 size_t length = strlen(name); 523 if (length > sizeof(fAddress) - sizeof(sockaddr_dl) + sizeof(link.sdl_data)) 524 length = sizeof(fAddress) - sizeof(sockaddr_dl) + sizeof(link.sdl_data); 525 526 link.sdl_family = AF_LINK; 527 link.sdl_nlen = length; 528 529 memcpy(link.sdl_data, name, link.sdl_nlen); 530 531 link.sdl_len = sizeof(sockaddr_dl); 532 if (link.sdl_nlen > sizeof(link.sdl_data)) 533 link.sdl_len += link.sdl_nlen - sizeof(link.sdl_data); 534} 535 536 537void 538BNetworkAddress::SetToLinkLevel(uint32 index) 539{ 540 sockaddr_dl& link = (sockaddr_dl&)fAddress; 541 memset(&link, 0, sizeof(sockaddr_dl)); 542 543 link.sdl_family = AF_LINK; 544 link.sdl_len = sizeof(sockaddr_dl); 545 link.sdl_index = index; 546} 547 548 549void 550BNetworkAddress::SetLinkLevelIndex(uint32 index) 551{ 552 sockaddr_dl& link = (sockaddr_dl&)fAddress; 553 link.sdl_index = index; 554} 555 556 557void 558BNetworkAddress::SetLinkLevelType(uint8 type) 559{ 560 sockaddr_dl& link = (sockaddr_dl&)fAddress; 561 link.sdl_type = type; 562} 563 564 565void 566BNetworkAddress::SetLinkLevelFrameType(uint16 frameType) 567{ 568 sockaddr_dl& link = (sockaddr_dl&)fAddress; 569 link.sdl_e_type = htons(frameType); 570} 571 572 573int 574BNetworkAddress::Family() const 575{ 576 return fAddress.ss_family; 577} 578 579 580uint16 581BNetworkAddress::Port() const 582{ 583 switch (fAddress.ss_family) { 584 case AF_INET: 585 return ntohs(((sockaddr_in&)fAddress).sin_port); 586 587 case AF_INET6: 588 return ntohs(((sockaddr_in6&)fAddress).sin6_port); 589 590 default: 591 return 0; 592 } 593} 594 595 596size_t 597BNetworkAddress::Length() const 598{ 599 return fAddress.ss_len; 600} 601 602 603const sockaddr& 604BNetworkAddress::SockAddr() const 605{ 606 return (const sockaddr&)fAddress; 607} 608 609 610sockaddr& 611BNetworkAddress::SockAddr() 612{ 613 return (sockaddr&)fAddress; 614} 615 616 617bool 618BNetworkAddress::IsEmpty() const 619{ 620 return fAddress.ss_len == 0 || fAddress.ss_family == AF_UNSPEC; 621} 622 623 624bool 625BNetworkAddress::IsWildcard() const 626{ 627 switch (fAddress.ss_family) { 628 case AF_INET: 629 return ((sockaddr_in&)fAddress).sin_addr.s_addr == INADDR_ANY; 630 631 case AF_INET6: 632 return !memcmp(&((sockaddr_in6&)fAddress).sin6_addr, &in6addr_any, 633 sizeof(in6_addr)); 634 635 default: 636 return false; 637 } 638} 639 640 641bool 642BNetworkAddress::IsBroadcast() const 643{ 644 switch (fAddress.ss_family) { 645 case AF_INET: 646 return ((sockaddr_in&)fAddress).sin_addr.s_addr == INADDR_BROADCAST; 647 648 case AF_INET6: 649 // There is no broadcast in IPv6, only multicast/anycast 650 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr); 651 652 default: 653 return false; 654 } 655} 656 657 658bool 659BNetworkAddress::IsMulticast() const 660{ 661 switch (fAddress.ss_family) { 662 case AF_INET: 663 return IN_MULTICAST(((sockaddr_in&)fAddress).sin_addr.s_addr); 664 665 case AF_INET6: 666 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr); 667 668 default: 669 return false; 670 } 671} 672 673 674bool 675BNetworkAddress::IsMulticastGlobal() const 676{ 677 switch (fAddress.ss_family) { 678 case AF_INET6: 679 return IN6_IS_ADDR_MC_GLOBAL(&((sockaddr_in6&)fAddress).sin6_addr); 680 681 default: 682 return false; 683 } 684} 685 686 687bool 688BNetworkAddress::IsMulticastNodeLocal() const 689{ 690 switch (fAddress.ss_family) { 691 case AF_INET6: 692 return IN6_IS_ADDR_MC_NODELOCAL( 693 &((sockaddr_in6&)fAddress).sin6_addr); 694 695 default: 696 return false; 697 } 698} 699 700 701bool 702BNetworkAddress::IsMulticastLinkLocal() const 703{ 704 switch (fAddress.ss_family) { 705 case AF_INET6: 706 return IN6_IS_ADDR_MC_LINKLOCAL( 707 &((sockaddr_in6&)fAddress).sin6_addr); 708 709 default: 710 return false; 711 } 712} 713 714 715bool 716BNetworkAddress::IsMulticastSiteLocal() const 717{ 718 switch (fAddress.ss_family) { 719 case AF_INET6: 720 return IN6_IS_ADDR_MC_SITELOCAL( 721 &((sockaddr_in6&)fAddress).sin6_addr); 722 723 default: 724 return false; 725 } 726} 727 728 729bool 730BNetworkAddress::IsMulticastOrgLocal() const 731{ 732 switch (fAddress.ss_family) { 733 case AF_INET6: 734 return IN6_IS_ADDR_MC_ORGLOCAL( 735 &((sockaddr_in6&)fAddress).sin6_addr); 736 737 default: 738 return false; 739 } 740} 741 742 743bool 744BNetworkAddress::IsLinkLocal() const 745{ 746 // TODO: ipv4 747 switch (fAddress.ss_family) { 748 case AF_INET6: 749 return IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6&)fAddress).sin6_addr); 750 751 default: 752 return false; 753 } 754} 755 756 757bool 758BNetworkAddress::IsSiteLocal() const 759{ 760 switch (fAddress.ss_family) { 761 case AF_INET6: 762 return IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6&)fAddress).sin6_addr); 763 764 default: 765 return false; 766 } 767} 768 769 770bool 771BNetworkAddress::IsLocal() const 772{ 773 BNetworkRoster& roster = BNetworkRoster::Default(); 774 775 BNetworkInterface interface; 776 uint32 cookie = 0; 777 778 while (roster.GetNextInterface(&cookie, interface) == B_OK) { 779 int32 count = interface.CountAddresses(); 780 for (int32 j = 0; j < count; j++) { 781 BNetworkInterfaceAddress address; 782 if (interface.GetAddressAt(j, address) != B_OK) 783 break; 784 785 if (Equals(address.Address(), false)) 786 return true; 787 } 788 } 789 790 return false; 791} 792 793 794ssize_t 795BNetworkAddress::PrefixLength() const 796{ 797 switch (fAddress.ss_family) { 798 case AF_INET: 799 { 800 sockaddr_in& mask = (sockaddr_in&)fAddress; 801 802 uint32 hostMask = ntohl(mask.sin_addr.s_addr); 803 return addr_bitcount(hostMask); 804 } 805 806 case AF_INET6: 807 { 808 sockaddr_in6& mask = (sockaddr_in6&)fAddress; 809 810 // TODO : see if we can use the optimized addr_bitcount for this 811 ssize_t result = 0; 812 for (uint8 i = 0; i < sizeof(in6_addr); i++) { 813 for (uint8 j = 0; j < 8; j++) { 814 if (!(mask.sin6_addr.s6_addr[i] & (1 << j))) 815 return result; 816 result++; 817 } 818 } 819 820 return 128; 821 } 822 823 default: 824 return B_NOT_SUPPORTED; 825 } 826} 827 828 829uint32 830BNetworkAddress::LinkLevelIndex() const 831{ 832 return ((sockaddr_dl&)fAddress).sdl_index; 833} 834 835 836BString 837BNetworkAddress::LinkLevelInterface() const 838{ 839 sockaddr_dl& address = (sockaddr_dl&)fAddress; 840 if (address.sdl_nlen == 0) 841 return ""; 842 843 BString name; 844 name.SetTo((const char*)address.sdl_data, address.sdl_nlen); 845 846 return name; 847} 848 849 850uint8 851BNetworkAddress::LinkLevelType() const 852{ 853 return ((sockaddr_dl&)fAddress).sdl_type; 854} 855 856 857uint16 858BNetworkAddress::LinkLevelFrameType() const 859{ 860 return ntohs(((sockaddr_dl&)fAddress).sdl_e_type); 861} 862 863 864uint8* 865BNetworkAddress::LinkLevelAddress() const 866{ 867 return LLADDR(&(sockaddr_dl&)fAddress); 868} 869 870 871size_t 872BNetworkAddress::LinkLevelAddressLength() const 873{ 874 return ((sockaddr_dl&)fAddress).sdl_alen; 875} 876 877 878status_t 879BNetworkAddress::ResolveForDestination(const BNetworkAddress& destination) 880{ 881 if (!IsWildcard()) 882 return B_OK; 883 if (destination.fAddress.ss_family != fAddress.ss_family) 884 return B_BAD_VALUE; 885 886 char buffer[2048]; 887 memset(buffer, 0, sizeof(buffer)); 888 889 route_entry* route = (route_entry*)buffer; 890 route->destination = (sockaddr*)&destination.fAddress; 891 892 int socket = ::socket(fAddress.ss_family, SOCK_DGRAM, 0); 893 if (socket < 0) 894 return errno; 895 896 if (ioctl(socket, SIOCGETRT, route, sizeof(buffer)) != 0) { 897 close(socket); 898 return errno; 899 } 900 901 uint16 port = Port(); 902 memcpy(&fAddress, route->source, sizeof(sockaddr_storage)); 903 SetPort(port); 904 905 return B_OK; 906} 907 908 909status_t 910BNetworkAddress::ResolveTo(const BNetworkAddress& address) 911{ 912 if (!IsWildcard()) 913 return B_OK; 914 if (address.fAddress.ss_family != fAddress.ss_family) 915 return B_BAD_VALUE; 916 917 uint16 port = Port(); 918 *this = address; 919 SetPort(port); 920 921 return B_OK; 922} 923 924 925BString 926BNetworkAddress::ToString(bool includePort) const 927{ 928 char buffer[512]; 929 930 switch (fAddress.ss_family) { 931 case AF_INET: 932 inet_ntop(AF_INET, &((sockaddr_in&)fAddress).sin_addr, buffer, 933 sizeof(buffer)); 934 break; 935 936 case AF_INET6: 937 inet_ntop(AF_INET6, &((sockaddr_in6&)fAddress).sin6_addr, 938 buffer, sizeof(buffer)); 939 break; 940 941 case AF_LINK: 942 { 943 uint8 *byte = LinkLevelAddress(); 944 char* target = buffer; 945 int bytesLeft = sizeof(buffer); 946 target[0] = '\0'; 947 948 for (size_t i = 0; i < LinkLevelAddressLength(); i++) { 949 if (i != 0 && bytesLeft > 1) { 950 target[0] = ':'; 951 target[1] = '\0'; 952 target++; 953 bytesLeft--; 954 } 955 956 int bytesWritten = snprintf(target, bytesLeft, "%02x", byte[i]); 957 if (bytesWritten >= bytesLeft) 958 break; 959 960 target += bytesWritten; 961 bytesLeft -= bytesWritten; 962 } 963 break; 964 } 965 966 default: 967 return ""; 968 } 969 970 BString address = buffer; 971 if (includePort && Port() != 0) { 972 if (fAddress.ss_family == AF_INET6) { 973 address = "["; 974 address += buffer; 975 address += "]"; 976 } 977 978 snprintf(buffer, sizeof(buffer), ":%u", Port()); 979 address += buffer; 980 } 981 982 return address; 983} 984 985 986BString 987BNetworkAddress::HostName() const 988{ 989 // TODO: implement host name lookup 990 return ToString(false); 991} 992 993 994BString 995BNetworkAddress::ServiceName() const 996{ 997 // TODO: implement service lookup 998 BString portName; 999 portName << Port(); 1000 return portName; 1001} 1002 1003 1004bool 1005BNetworkAddress::Equals(const BNetworkAddress& other, bool includePort) const 1006{ 1007 if (IsEmpty() && other.IsEmpty()) 1008 return true; 1009 1010 if (Family() != other.Family() 1011 || (includePort && Port() != other.Port())) 1012 return false; 1013 1014 switch (fAddress.ss_family) { 1015 case AF_INET: 1016 { 1017 sockaddr_in& address = (sockaddr_in&)fAddress; 1018 sockaddr_in& otherAddress = (sockaddr_in&)other.fAddress; 1019 return memcmp(&address.sin_addr, &otherAddress.sin_addr, 1020 sizeof(address.sin_addr)) == 0; 1021 } 1022 1023 case AF_INET6: 1024 { 1025 sockaddr_in6& address = (sockaddr_in6&)fAddress; 1026 sockaddr_in6& otherAddress = (sockaddr_in6&)other.fAddress; 1027 return memcmp(&address.sin6_addr, &otherAddress.sin6_addr, 1028 sizeof(address.sin6_addr)) == 0; 1029 } 1030 1031 default: 1032 if (fAddress.ss_len != other.fAddress.ss_len) 1033 return false; 1034 1035 return memcmp(&fAddress, &other.fAddress, fAddress.ss_len); 1036 } 1037} 1038 1039 1040// #pragma mark - BFlattenable implementation 1041 1042 1043bool 1044BNetworkAddress::IsFixedSize() const 1045{ 1046 return false; 1047} 1048 1049 1050type_code 1051BNetworkAddress::TypeCode() const 1052{ 1053 return B_NETWORK_ADDRESS_TYPE; 1054} 1055 1056 1057ssize_t 1058BNetworkAddress::FlattenedSize() const 1059{ 1060 return Length(); 1061} 1062 1063 1064status_t 1065BNetworkAddress::Flatten(void* buffer, ssize_t size) const 1066{ 1067 if (buffer == NULL || size < FlattenedSize()) 1068 return B_BAD_VALUE; 1069 1070 memcpy(buffer, &fAddress, Length()); 1071 return B_OK; 1072} 1073 1074 1075status_t 1076BNetworkAddress::Unflatten(type_code code, const void* buffer, ssize_t size) 1077{ 1078 // 2 bytes minimum for family, and length 1079 if (buffer == NULL || size < 2) 1080 return fStatus = B_BAD_VALUE; 1081 if (!AllowsTypeCode(code)) 1082 return fStatus = B_BAD_TYPE; 1083 1084 memcpy(&fAddress, buffer, min_c(size, (ssize_t)sizeof(fAddress))); 1085 1086 // check if this can contain a valid address 1087 if (fAddress.ss_family != AF_UNSPEC && size < (ssize_t)sizeof(sockaddr)) 1088 return fStatus = B_BAD_VALUE; 1089 1090 return fStatus = B_OK; 1091} 1092 1093 1094// #pragma mark - operators 1095 1096 1097BNetworkAddress& 1098BNetworkAddress::operator=(const BNetworkAddress& other) 1099{ 1100 memcpy(&fAddress, &other.fAddress, other.fAddress.ss_len); 1101 fStatus = other.fStatus; 1102 1103 return *this; 1104} 1105 1106 1107bool 1108BNetworkAddress::operator==(const BNetworkAddress& other) const 1109{ 1110 return Equals(other); 1111} 1112 1113 1114bool 1115BNetworkAddress::operator!=(const BNetworkAddress& other) const 1116{ 1117 return !Equals(other); 1118} 1119 1120 1121bool 1122BNetworkAddress::operator<(const BNetworkAddress& other) const 1123{ 1124 if (Family() < other.Family()) 1125 return true; 1126 if (Family() > other.Family()) 1127 return false; 1128 1129 int compare; 1130 1131 switch (fAddress.ss_family) { 1132 default: 1133 case AF_INET: 1134 { 1135 sockaddr_in& address = (sockaddr_in&)fAddress; 1136 sockaddr_in& otherAddress = (sockaddr_in&)other.fAddress; 1137 compare = memcmp(&address.sin_addr, &otherAddress.sin_addr, 1138 sizeof(address.sin_addr)); 1139 break; 1140 } 1141 1142 case AF_INET6: 1143 { 1144 sockaddr_in6& address = (sockaddr_in6&)fAddress; 1145 sockaddr_in6& otherAddress = (sockaddr_in6&)other.fAddress; 1146 compare = memcmp(&address.sin6_addr, &otherAddress.sin6_addr, 1147 sizeof(address.sin6_addr)); 1148 break; 1149 } 1150 1151 case AF_LINK: 1152 if (LinkLevelAddressLength() < other.LinkLevelAddressLength()) 1153 return true; 1154 if (LinkLevelAddressLength() > other.LinkLevelAddressLength()) 1155 return true; 1156 1157 // TODO: could compare index, and name, too 1158 compare = memcmp(LinkLevelAddress(), other.LinkLevelAddress(), 1159 LinkLevelAddressLength()); 1160 break; 1161 } 1162 1163 if (compare < 0) 1164 return true; 1165 if (compare > 0) 1166 return false; 1167 1168 return Port() < other.Port(); 1169} 1170 1171 1172BNetworkAddress::operator const sockaddr*() const 1173{ 1174 return (const sockaddr*)&fAddress; 1175} 1176 1177 1178BNetworkAddress::operator const sockaddr&() const 1179{ 1180 return (const sockaddr&)fAddress; 1181} 1182 1183 1184BNetworkAddress::operator sockaddr*() 1185{ 1186 return (sockaddr*)&fAddress; 1187} 1188 1189 1190BNetworkAddress::operator const sockaddr*() 1191{ 1192 return (sockaddr*)&fAddress; 1193} 1194 1195 1196BNetworkAddress::operator sockaddr&() 1197{ 1198 return (sockaddr&)fAddress; 1199} 1200 1201 1202BNetworkAddress::operator const sockaddr&() 1203{ 1204 return (sockaddr&)fAddress; 1205} 1206 1207 1208// #pragma mark - private 1209 1210 1211status_t 1212BNetworkAddress::_ParseLinkAddress(const char* address) 1213{ 1214 uint8 linkAddress[128]; 1215 uint32 length = 0; 1216 while (length < sizeof(linkAddress)) { 1217 if (!isxdigit(address[0]) || !isxdigit(address[1])) 1218 return B_BAD_VALUE; 1219 1220 linkAddress[length++] = (from_hex(address[0]) << 4) 1221 | from_hex(address[1]); 1222 1223 if (address[2] == '\0') 1224 break; 1225 if (address[2] != ':') 1226 return B_BAD_VALUE; 1227 1228 address += 3; 1229 } 1230 1231 SetToLinkLevel(linkAddress, length); 1232 return B_OK; 1233} 1234