2 * Copyright 2010-2015, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include <NetworkAddress.h>
9 #include <NetworkInterface.h>
10 #include <NetworkRoster.h>
12 #include <arpa/inet.h>
15 #include <netinet/in.h>
17 #include <sys/sockio.h>
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
25 # define addr_bitcount(bitfield) __builtin_popcount(bitfield)
28 addr_bitcount(uint32 bitfield
)
31 for (uint8 i
= 32; i
> 0; i
--) {
32 if ((bitfield
& (1 << (i
- 1))) == 0)
47 return tolower(hex
) - 'a' + 10;
54 BNetworkAddress::BNetworkAddress()
60 BNetworkAddress::BNetworkAddress(const char* host
, uint16 port
, uint32 flags
)
62 fStatus
= SetTo(host
, port
, flags
);
66 BNetworkAddress::BNetworkAddress(const char* host
, const char* service
,
69 fStatus
= SetTo(host
, service
, flags
);
73 BNetworkAddress::BNetworkAddress(int family
, const char* host
, uint16 port
,
76 fStatus
= SetTo(family
, host
, port
, flags
);
80 BNetworkAddress::BNetworkAddress(int family
, const char* host
,
81 const char* service
, uint32 flags
)
83 fStatus
= SetTo(family
, host
, service
, flags
);
87 BNetworkAddress::BNetworkAddress(const sockaddr
& address
)
93 BNetworkAddress::BNetworkAddress(const sockaddr_storage
& address
)
99 BNetworkAddress::BNetworkAddress(const sockaddr_in
& address
)
105 BNetworkAddress::BNetworkAddress(const sockaddr_in6
& address
)
111 BNetworkAddress::BNetworkAddress(const sockaddr_dl
& address
)
117 BNetworkAddress::BNetworkAddress(in_addr_t address
, uint16 port
)
119 SetTo(address
, port
);
123 BNetworkAddress::BNetworkAddress(const in6_addr
& address
, uint16 port
)
125 SetTo(address
, port
);
129 BNetworkAddress::BNetworkAddress(const BNetworkAddress
& other
)
131 fAddress(other
.fAddress
),
132 fStatus(other
.fStatus
),
133 fHostName(other
.fHostName
)
138 BNetworkAddress::~BNetworkAddress()
144 BNetworkAddress::InitCheck() const
151 BNetworkAddress::Unset()
153 fAddress
.ss_family
= AF_UNSPEC
;
161 BNetworkAddress::SetTo(const char* host
, uint16 port
, uint32 flags
)
163 BReference
<const BNetworkAddressResolver
> resolver
164 = BNetworkAddressResolver::Resolve(host
, port
, flags
);
165 if (resolver
.Get() == NULL
)
167 status_t status
= resolver
->InitCheck();
171 // Prefer IPv6 addresses
174 status
= resolver
->GetNextAddress(AF_INET6
, &cookie
, *this);
175 if (status
!= B_OK
) {
177 status
= resolver
->GetNextAddress(&cookie
, *this);
188 BNetworkAddress::SetTo(const char* host
, const char* service
, uint32 flags
)
190 BReference
<const BNetworkAddressResolver
> resolver
191 = BNetworkAddressResolver::Resolve(host
, service
, flags
);
192 if (resolver
.Get() == NULL
)
194 status_t status
= resolver
->InitCheck();
198 // Prefer IPv6 addresses
201 status
= resolver
->GetNextAddress(AF_INET6
, &cookie
, *this);
202 if (status
!= B_OK
) {
204 status
= resolver
->GetNextAddress(&cookie
, *this);
215 BNetworkAddress::SetTo(int family
, const char* host
, uint16 port
, uint32 flags
)
217 if (family
== AF_LINK
) {
220 return _ParseLinkAddress(host
);
221 // SetToLinkAddress takes care of setting fStatus
224 BReference
<const BNetworkAddressResolver
> resolver
225 = BNetworkAddressResolver::Resolve(family
, host
, port
, flags
);
226 if (resolver
.Get() == NULL
)
228 status_t status
= resolver
->InitCheck();
233 status
= resolver
->GetNextAddress(&cookie
, *this);
243 BNetworkAddress::SetTo(int family
, const char* host
, const char* service
,
246 if (family
== AF_LINK
) {
249 return _ParseLinkAddress(host
);
250 // SetToLinkAddress takes care of setting fStatus
253 BReference
<const BNetworkAddressResolver
> resolver
254 = BNetworkAddressResolver::Resolve(family
, host
, service
, flags
);
255 if (resolver
.Get() == NULL
)
257 status_t status
= resolver
->InitCheck();
262 status
= resolver
->GetNextAddress(&cookie
, *this);
272 BNetworkAddress::SetTo(const sockaddr
& address
)
274 if (address
.sa_family
== AF_UNSPEC
) {
279 size_t length
= min_c(sizeof(sockaddr_storage
), address
.sa_len
);
280 switch (address
.sa_family
) {
282 length
= sizeof(sockaddr_in
);
285 length
= sizeof(sockaddr_in6
);
289 sockaddr_dl
& link
= (sockaddr_dl
&)address
;
290 length
= sizeof(sockaddr_dl
) - sizeof(link
.sdl_data
) + link
.sdl_alen
291 + link
.sdl_nlen
+ link
.sdl_slen
;
296 SetTo(address
, length
);
301 BNetworkAddress::SetTo(const sockaddr
& address
, size_t length
)
303 if (address
.sa_family
== AF_UNSPEC
|| length
== 0) {
308 memcpy(&fAddress
, &address
, length
);
309 fAddress
.ss_len
= length
;
315 BNetworkAddress::SetTo(const sockaddr_storage
& address
)
317 SetTo((sockaddr
&)address
);
322 BNetworkAddress::SetTo(const sockaddr_in
& address
)
324 SetTo((sockaddr
&)address
);
329 BNetworkAddress::SetTo(const sockaddr_in6
& address
)
331 SetTo((sockaddr
&)address
);
336 BNetworkAddress::SetTo(const sockaddr_dl
& address
)
338 SetTo((sockaddr
&)address
);
343 BNetworkAddress::SetTo(in_addr_t inetAddress
, uint16 port
)
345 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
347 fAddress
.ss_family
= AF_INET
;
348 fAddress
.ss_len
= sizeof(sockaddr_in
);
349 SetAddress(inetAddress
);
357 BNetworkAddress::SetTo(const in6_addr
& inet6Address
, uint16 port
)
359 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
361 fAddress
.ss_family
= AF_INET6
;
362 fAddress
.ss_len
= sizeof(sockaddr_in6
);
363 SetAddress(inet6Address
);
371 BNetworkAddress::SetTo(const BNetworkAddress
& other
)
373 fAddress
= other
.fAddress
;
374 fStatus
= other
.fStatus
;
375 fHostName
= other
.fHostName
;
380 BNetworkAddress::SetToBroadcast(int family
, uint16 port
)
382 if (family
!= AF_INET
)
383 return fStatus
= B_NOT_SUPPORTED
;
385 SetTo(INADDR_BROADCAST
, port
);
391 BNetworkAddress::SetToLocal(int family
, uint16 port
)
393 // TODO: choose a local address from the network interfaces
394 return fStatus
= B_NOT_SUPPORTED
;
399 BNetworkAddress::SetToLoopback(int family
, uint16 port
)
402 // TODO: choose family depending on availability of IPv6
405 SetTo(htonl(INADDR_LOOPBACK
), port
);
409 SetTo(in6addr_loopback
, port
);
413 return fStatus
= B_NOT_SUPPORTED
;
421 BNetworkAddress::SetToMask(int family
, uint32 prefixLength
)
426 if (prefixLength
> 32)
429 sockaddr_in
& mask
= (sockaddr_in
&)fAddress
;
430 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
431 mask
.sin_family
= AF_INET
;
432 mask
.sin_len
= sizeof(sockaddr_in
);
435 for (uint8 i
= 32; i
> 32 - prefixLength
; i
--)
436 hostMask
|= 1 << (i
- 1);
438 mask
.sin_addr
.s_addr
= htonl(hostMask
);
444 if (prefixLength
> 128)
447 sockaddr_in6
& mask
= (sockaddr_in6
&)fAddress
;
448 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
449 mask
.sin6_family
= AF_INET6
;
450 mask
.sin6_len
= sizeof(sockaddr_in6
);
452 for (uint8 i
= 0; i
< sizeof(in6_addr
); i
++, prefixLength
-= 8) {
453 if (prefixLength
< 8) {
454 mask
.sin6_addr
.s6_addr
[i
]
455 = (uint8
)(0xff << (8 - prefixLength
));
459 mask
.sin6_addr
.s6_addr
[i
] = 0xff;
465 return B_NOT_SUPPORTED
;
468 return fStatus
= B_OK
;
473 BNetworkAddress::SetToWildcard(int family
, uint16 port
)
477 SetTo(INADDR_ANY
, port
);
481 SetTo(in6addr_any
, port
);
485 return B_NOT_SUPPORTED
;
493 BNetworkAddress::SetAddress(in_addr_t inetAddress
)
495 if (Family() != AF_INET
)
498 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
499 address
.sin_addr
.s_addr
= inetAddress
;
505 BNetworkAddress::SetAddress(const in6_addr
& inet6Address
)
507 if (Family() != AF_INET6
)
510 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
511 memcpy(address
.sin6_addr
.s6_addr
, &inet6Address
,
512 sizeof(address
.sin6_addr
.s6_addr
));
518 BNetworkAddress::SetPort(uint16 port
)
520 switch (fAddress
.ss_family
) {
522 ((sockaddr_in
&)fAddress
).sin_port
= htons(port
);
526 ((sockaddr_in6
&)fAddress
).sin6_port
= htons(port
);
536 BNetworkAddress::SetToLinkLevel(uint8
* address
, size_t length
)
538 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
539 memset(&link
, 0, sizeof(sockaddr_dl
));
541 link
.sdl_family
= AF_LINK
;
542 link
.sdl_alen
= length
;
543 memcpy(LLADDR(&link
), address
, length
);
545 link
.sdl_len
= sizeof(sockaddr_dl
);
546 if (length
> sizeof(link
.sdl_data
))
547 link
.sdl_len
+= length
- sizeof(link
.sdl_data
);
554 BNetworkAddress::SetToLinkLevel(const char* name
)
556 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
557 memset(&link
, 0, sizeof(sockaddr_dl
));
559 size_t length
= strlen(name
);
560 if (length
> sizeof(fAddress
) - sizeof(sockaddr_dl
) + sizeof(link
.sdl_data
))
561 length
= sizeof(fAddress
) - sizeof(sockaddr_dl
) + sizeof(link
.sdl_data
);
563 link
.sdl_family
= AF_LINK
;
564 link
.sdl_nlen
= length
;
566 memcpy(link
.sdl_data
, name
, link
.sdl_nlen
);
568 link
.sdl_len
= sizeof(sockaddr_dl
);
569 if (link
.sdl_nlen
> sizeof(link
.sdl_data
))
570 link
.sdl_len
+= link
.sdl_nlen
- sizeof(link
.sdl_data
);
577 BNetworkAddress::SetToLinkLevel(uint32 index
)
579 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
580 memset(&link
, 0, sizeof(sockaddr_dl
));
582 link
.sdl_family
= AF_LINK
;
583 link
.sdl_len
= sizeof(sockaddr_dl
);
584 link
.sdl_index
= index
;
591 BNetworkAddress::SetLinkLevelIndex(uint32 index
)
593 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
594 link
.sdl_index
= index
;
599 BNetworkAddress::SetLinkLevelType(uint8 type
)
601 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
602 link
.sdl_type
= type
;
607 BNetworkAddress::SetLinkLevelFrameType(uint16 frameType
)
609 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
610 link
.sdl_e_type
= htons(frameType
);
615 BNetworkAddress::Family() const
617 return fAddress
.ss_family
;
622 BNetworkAddress::Port() const
624 switch (fAddress
.ss_family
) {
626 return ntohs(((sockaddr_in
&)fAddress
).sin_port
);
629 return ntohs(((sockaddr_in6
&)fAddress
).sin6_port
);
638 BNetworkAddress::Length() const
640 return fAddress
.ss_len
;
645 BNetworkAddress::SockAddr() const
647 return (const sockaddr
&)fAddress
;
652 BNetworkAddress::SockAddr()
654 return (sockaddr
&)fAddress
;
659 BNetworkAddress::IsEmpty() const
661 if (fAddress
.ss_len
== 0)
664 switch (fAddress
.ss_family
) {
669 sockaddr_in
& sin
= (sockaddr_in
&)fAddress
;
670 return sin
.sin_addr
.s_addr
== INADDR_ANY
&& sin
.sin_port
== 0;
674 sockaddr_in6
& sin6
= (sockaddr_in6
&)fAddress
;
675 return IN6_IS_ADDR_UNSPECIFIED(&sin6
.sin6_addr
)
676 && sin6
.sin6_port
== 0;
686 BNetworkAddress::IsWildcard() const
688 switch (fAddress
.ss_family
) {
690 return ((sockaddr_in
&)fAddress
).sin_addr
.s_addr
== INADDR_ANY
;
693 return !memcmp(&((sockaddr_in6
&)fAddress
).sin6_addr
, &in6addr_any
,
703 BNetworkAddress::IsBroadcast() const
705 switch (fAddress
.ss_family
) {
707 return ((sockaddr_in
&)fAddress
).sin_addr
.s_addr
== INADDR_BROADCAST
;
710 // There is no broadcast in IPv6, only multicast/anycast
711 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6
&)fAddress
).sin6_addr
);
720 BNetworkAddress::IsMulticast() const
722 switch (fAddress
.ss_family
) {
724 return IN_MULTICAST(((sockaddr_in
&)fAddress
).sin_addr
.s_addr
);
727 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6
&)fAddress
).sin6_addr
);
736 BNetworkAddress::IsMulticastGlobal() const
738 switch (fAddress
.ss_family
) {
740 return IN6_IS_ADDR_MC_GLOBAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
749 BNetworkAddress::IsMulticastNodeLocal() const
751 switch (fAddress
.ss_family
) {
753 return IN6_IS_ADDR_MC_NODELOCAL(
754 &((sockaddr_in6
&)fAddress
).sin6_addr
);
763 BNetworkAddress::IsMulticastLinkLocal() const
765 switch (fAddress
.ss_family
) {
767 return IN6_IS_ADDR_MC_LINKLOCAL(
768 &((sockaddr_in6
&)fAddress
).sin6_addr
);
777 BNetworkAddress::IsMulticastSiteLocal() const
779 switch (fAddress
.ss_family
) {
781 return IN6_IS_ADDR_MC_SITELOCAL(
782 &((sockaddr_in6
&)fAddress
).sin6_addr
);
791 BNetworkAddress::IsMulticastOrgLocal() const
793 switch (fAddress
.ss_family
) {
795 return IN6_IS_ADDR_MC_ORGLOCAL(
796 &((sockaddr_in6
&)fAddress
).sin6_addr
);
805 BNetworkAddress::IsLinkLocal() const
808 switch (fAddress
.ss_family
) {
810 return IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
819 BNetworkAddress::IsSiteLocal() const
821 switch (fAddress
.ss_family
) {
823 return IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
832 BNetworkAddress::IsLocal() const
834 BNetworkRoster
& roster
= BNetworkRoster::Default();
836 BNetworkInterface interface
;
839 while (roster
.GetNextInterface(&cookie
, interface
) == B_OK
) {
840 int32 count
= interface
.CountAddresses();
841 for (int32 j
= 0; j
< count
; j
++) {
842 BNetworkInterfaceAddress address
;
843 if (interface
.GetAddressAt(j
, address
) != B_OK
)
846 if (Equals(address
.Address(), false))
856 BNetworkAddress::PrefixLength() const
858 switch (fAddress
.ss_family
) {
861 sockaddr_in
& mask
= (sockaddr_in
&)fAddress
;
863 uint32 hostMask
= ntohl(mask
.sin_addr
.s_addr
);
864 return addr_bitcount(hostMask
);
869 sockaddr_in6
& mask
= (sockaddr_in6
&)fAddress
;
871 // TODO : see if we can use the optimized addr_bitcount for this
873 for (uint8 i
= 0; i
< sizeof(in6_addr
); i
++) {
874 for (uint8 j
= 0; j
< 8; j
++) {
875 if (!(mask
.sin6_addr
.s6_addr
[i
] & (1 << j
)))
885 return B_NOT_SUPPORTED
;
891 BNetworkAddress::LinkLevelIndex() const
893 return ((sockaddr_dl
&)fAddress
).sdl_index
;
898 BNetworkAddress::LinkLevelInterface() const
900 sockaddr_dl
& address
= (sockaddr_dl
&)fAddress
;
901 if (address
.sdl_nlen
== 0)
905 name
.SetTo((const char*)address
.sdl_data
, address
.sdl_nlen
);
912 BNetworkAddress::LinkLevelType() const
914 return ((sockaddr_dl
&)fAddress
).sdl_type
;
919 BNetworkAddress::LinkLevelFrameType() const
921 return ntohs(((sockaddr_dl
&)fAddress
).sdl_e_type
);
926 BNetworkAddress::LinkLevelAddress() const
928 return LLADDR(&(sockaddr_dl
&)fAddress
);
933 BNetworkAddress::LinkLevelAddressLength() const
935 return ((sockaddr_dl
&)fAddress
).sdl_alen
;
940 BNetworkAddress::ResolveForDestination(const BNetworkAddress
& destination
)
944 if (destination
.fAddress
.ss_family
!= fAddress
.ss_family
)
948 memset(buffer
, 0, sizeof(buffer
));
950 route_entry
* route
= (route_entry
*)buffer
;
951 route
->destination
= (sockaddr
*)&destination
.fAddress
;
953 int socket
= ::socket(fAddress
.ss_family
, SOCK_DGRAM
, 0);
957 if (ioctl(socket
, SIOCGETRT
, route
, sizeof(buffer
)) != 0) {
962 uint16 port
= Port();
963 memcpy(&fAddress
, route
->source
, sizeof(sockaddr_storage
));
972 BNetworkAddress::ResolveTo(const BNetworkAddress
& address
)
976 if (address
.fAddress
.ss_family
!= fAddress
.ss_family
)
979 uint16 port
= Port();
988 BNetworkAddress::ToString(bool includePort
) const
992 switch (fAddress
.ss_family
) {
994 inet_ntop(AF_INET
, &((sockaddr_in
&)fAddress
).sin_addr
, buffer
,
999 inet_ntop(AF_INET6
, &((sockaddr_in6
&)fAddress
).sin6_addr
,
1000 buffer
, sizeof(buffer
));
1005 uint8
*byte
= LinkLevelAddress();
1006 char* target
= buffer
;
1007 int bytesLeft
= sizeof(buffer
);
1010 for (size_t i
= 0; i
< LinkLevelAddressLength(); i
++) {
1011 if (i
!= 0 && bytesLeft
> 1) {
1018 int bytesWritten
= snprintf(target
, bytesLeft
, "%02x", byte
[i
]);
1019 if (bytesWritten
>= bytesLeft
)
1022 target
+= bytesWritten
;
1023 bytesLeft
-= bytesWritten
;
1032 BString address
= buffer
;
1033 if (includePort
&& Port() != 0) {
1034 if (fAddress
.ss_family
== AF_INET6
) {
1040 snprintf(buffer
, sizeof(buffer
), ":%u", Port());
1049 BNetworkAddress::HostName() const
1051 // TODO: implement host name lookup
1057 BNetworkAddress::ServiceName() const
1059 // TODO: implement service lookup
1067 BNetworkAddress::Equals(const BNetworkAddress
& other
, bool includePort
) const
1069 if (IsEmpty() && other
.IsEmpty())
1072 if (Family() != other
.Family()
1073 || (includePort
&& Port() != other
.Port())) {
1077 switch (fAddress
.ss_family
) {
1080 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
1081 sockaddr_in
& otherAddress
= (sockaddr_in
&)other
.fAddress
;
1082 return memcmp(&address
.sin_addr
, &otherAddress
.sin_addr
,
1083 sizeof(address
.sin_addr
)) == 0;
1088 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
1089 sockaddr_in6
& otherAddress
= (sockaddr_in6
&)other
.fAddress
;
1090 return memcmp(&address
.sin6_addr
, &otherAddress
.sin6_addr
,
1091 sizeof(address
.sin6_addr
)) == 0;
1095 if (fAddress
.ss_len
!= other
.fAddress
.ss_len
)
1098 return memcmp(&fAddress
, &other
.fAddress
, fAddress
.ss_len
);
1103 // #pragma mark - BFlattenable implementation
1107 BNetworkAddress::IsFixedSize() const
1114 BNetworkAddress::TypeCode() const
1116 return B_NETWORK_ADDRESS_TYPE
;
1121 BNetworkAddress::FlattenedSize() const
1128 BNetworkAddress::Flatten(void* buffer
, ssize_t size
) const
1130 if (buffer
== NULL
|| size
< FlattenedSize())
1133 memcpy(buffer
, &fAddress
, Length());
1139 BNetworkAddress::Unflatten(type_code code
, const void* buffer
, ssize_t size
)
1141 // 2 bytes minimum for family, and length
1142 if (buffer
== NULL
|| size
< 2)
1143 return fStatus
= B_BAD_VALUE
;
1144 if (!AllowsTypeCode(code
))
1145 return fStatus
= B_BAD_TYPE
;
1147 memcpy(&fAddress
, buffer
, min_c(size
, (ssize_t
)sizeof(fAddress
)));
1149 // check if this can contain a valid address
1150 if (fAddress
.ss_family
!= AF_UNSPEC
&& size
< (ssize_t
)sizeof(sockaddr
))
1151 return fStatus
= B_BAD_VALUE
;
1153 return fStatus
= B_OK
;
1157 // #pragma mark - operators
1161 BNetworkAddress::operator=(const BNetworkAddress
& other
)
1163 memcpy(&fAddress
, &other
.fAddress
, other
.fAddress
.ss_len
);
1164 fHostName
= other
.fHostName
;
1165 fStatus
= other
.fStatus
;
1172 BNetworkAddress::operator==(const BNetworkAddress
& other
) const
1174 return Equals(other
);
1179 BNetworkAddress::operator!=(const BNetworkAddress
& other
) const
1181 return !Equals(other
);
1186 BNetworkAddress::operator<(const BNetworkAddress
& other
) const
1188 if (Family() < other
.Family())
1190 if (Family() > other
.Family())
1195 switch (fAddress
.ss_family
) {
1199 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
1200 sockaddr_in
& otherAddress
= (sockaddr_in
&)other
.fAddress
;
1201 compare
= memcmp(&address
.sin_addr
, &otherAddress
.sin_addr
,
1202 sizeof(address
.sin_addr
));
1208 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
1209 sockaddr_in6
& otherAddress
= (sockaddr_in6
&)other
.fAddress
;
1210 compare
= memcmp(&address
.sin6_addr
, &otherAddress
.sin6_addr
,
1211 sizeof(address
.sin6_addr
));
1216 if (LinkLevelAddressLength() < other
.LinkLevelAddressLength())
1218 if (LinkLevelAddressLength() > other
.LinkLevelAddressLength())
1221 // TODO: could compare index, and name, too
1222 compare
= memcmp(LinkLevelAddress(), other
.LinkLevelAddress(),
1223 LinkLevelAddressLength());
1232 return Port() < other
.Port();
1236 BNetworkAddress::operator const sockaddr
*() const
1238 return (const sockaddr
*)&fAddress
;
1242 BNetworkAddress::operator const sockaddr
&() const
1244 return (const sockaddr
&)fAddress
;
1248 BNetworkAddress::operator sockaddr
*()
1250 return (sockaddr
*)&fAddress
;
1254 BNetworkAddress::operator const sockaddr
*()
1256 return (sockaddr
*)&fAddress
;
1260 BNetworkAddress::operator sockaddr
&()
1262 return (sockaddr
&)fAddress
;
1266 BNetworkAddress::operator const sockaddr
&()
1268 return (sockaddr
&)fAddress
;
1272 // #pragma mark - private
1276 BNetworkAddress::_ParseLinkAddress(const char* address
)
1278 if (address
== NULL
)
1281 uint8 linkAddress
[128];
1283 while (length
< sizeof(linkAddress
)) {
1284 if (!isxdigit(address
[0]) || !isxdigit(address
[1]))
1287 linkAddress
[length
++] = (from_hex(address
[0]) << 4)
1288 | from_hex(address
[1]);
1290 if (address
[2] == '\0')
1292 if (address
[2] != ':')
1298 fHostName
= address
;
1300 SetToLinkLevel(linkAddress
, length
);