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
)
137 BNetworkAddress::~BNetworkAddress()
143 BNetworkAddress::InitCheck() const
150 BNetworkAddress::Unset()
152 fAddress
.ss_family
= AF_UNSPEC
;
159 BNetworkAddress::SetTo(const char* host
, uint16 port
, uint32 flags
)
161 BReference
<const BNetworkAddressResolver
> resolver
162 = BNetworkAddressResolver::Resolve(host
, port
, flags
);
163 if (resolver
.Get() == NULL
)
165 status_t status
= resolver
->InitCheck();
169 // Prefer IPv6 addresses
172 status
= resolver
->GetNextAddress(AF_INET6
, &cookie
, *this);
173 if (status
== B_OK
) {
179 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
) {
208 status
= resolver
->GetNextAddress(&cookie
, *this);
217 BNetworkAddress::SetTo(int family
, const char* host
, uint16 port
, uint32 flags
)
219 if (family
== AF_LINK
) {
222 return _ParseLinkAddress(host
);
223 // SetToLinkAddress takes care of setting fStatus
226 BReference
<const BNetworkAddressResolver
> resolver
227 = BNetworkAddressResolver::Resolve(family
, host
, port
, flags
);
228 if (resolver
.Get() == NULL
)
230 status_t status
= resolver
->InitCheck();
235 status
= resolver
->GetNextAddress(&cookie
, *this);
244 BNetworkAddress::SetTo(int family
, const char* host
, const char* service
,
247 if (family
== AF_LINK
) {
250 return _ParseLinkAddress(host
);
251 // SetToLinkAddress takes care of setting fStatus
254 BReference
<const BNetworkAddressResolver
> resolver
255 = BNetworkAddressResolver::Resolve(family
, host
, service
, flags
);
256 if (resolver
.Get() == NULL
)
258 status_t status
= resolver
->InitCheck();
263 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
;
379 BNetworkAddress::SetToBroadcast(int family
, uint16 port
)
381 if (family
!= AF_INET
)
382 return fStatus
= B_NOT_SUPPORTED
;
384 SetTo(INADDR_BROADCAST
, port
);
390 BNetworkAddress::SetToLocal(int family
, uint16 port
)
392 // TODO: choose a local address from the network interfaces
393 return fStatus
= B_NOT_SUPPORTED
;
398 BNetworkAddress::SetToLoopback(int family
, uint16 port
)
401 // TODO: choose family depending on availability of IPv6
404 SetTo(htonl(INADDR_LOOPBACK
), port
);
408 SetTo(in6addr_loopback
, port
);
412 return fStatus
= B_NOT_SUPPORTED
;
420 BNetworkAddress::SetToMask(int family
, uint32 prefixLength
)
425 if (prefixLength
> 32)
428 sockaddr_in
& mask
= (sockaddr_in
&)fAddress
;
429 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
430 mask
.sin_family
= AF_INET
;
431 mask
.sin_len
= sizeof(sockaddr_in
);
434 for (uint8 i
= 32; i
> 32 - prefixLength
; i
--)
435 hostMask
|= 1 << (i
- 1);
437 mask
.sin_addr
.s_addr
= htonl(hostMask
);
443 if (prefixLength
> 128)
446 sockaddr_in6
& mask
= (sockaddr_in6
&)fAddress
;
447 memset(&fAddress
, 0, sizeof(sockaddr_storage
));
448 mask
.sin6_family
= AF_INET6
;
449 mask
.sin6_len
= sizeof(sockaddr_in6
);
451 for (uint8 i
= 0; i
< sizeof(in6_addr
); i
++, prefixLength
-= 8) {
452 if (prefixLength
< 8) {
453 mask
.sin6_addr
.s6_addr
[i
]
454 = (uint8
)(0xff << (8 - prefixLength
));
458 mask
.sin6_addr
.s6_addr
[i
] = 0xff;
464 return B_NOT_SUPPORTED
;
467 return fStatus
= B_OK
;
472 BNetworkAddress::SetToWildcard(int family
, uint16 port
)
476 SetTo(INADDR_ANY
, port
);
480 SetTo(in6addr_any
, port
);
484 return B_NOT_SUPPORTED
;
492 BNetworkAddress::SetAddress(in_addr_t inetAddress
)
494 if (Family() != AF_INET
)
497 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
498 address
.sin_addr
.s_addr
= inetAddress
;
504 BNetworkAddress::SetAddress(const in6_addr
& inet6Address
)
506 if (Family() != AF_INET6
)
509 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
510 memcpy(address
.sin6_addr
.s6_addr
, &inet6Address
,
511 sizeof(address
.sin6_addr
.s6_addr
));
517 BNetworkAddress::SetPort(uint16 port
)
519 switch (fAddress
.ss_family
) {
521 ((sockaddr_in
&)fAddress
).sin_port
= htons(port
);
525 ((sockaddr_in6
&)fAddress
).sin6_port
= htons(port
);
535 BNetworkAddress::SetToLinkLevel(uint8
* address
, size_t length
)
537 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
538 memset(&link
, 0, sizeof(sockaddr_dl
));
540 link
.sdl_family
= AF_LINK
;
541 link
.sdl_alen
= length
;
542 memcpy(LLADDR(&link
), address
, length
);
544 link
.sdl_len
= sizeof(sockaddr_dl
);
545 if (length
> sizeof(link
.sdl_data
))
546 link
.sdl_len
+= length
- sizeof(link
.sdl_data
);
553 BNetworkAddress::SetToLinkLevel(const char* name
)
555 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
556 memset(&link
, 0, sizeof(sockaddr_dl
));
558 size_t length
= strlen(name
);
559 if (length
> sizeof(fAddress
) - sizeof(sockaddr_dl
) + sizeof(link
.sdl_data
))
560 length
= sizeof(fAddress
) - sizeof(sockaddr_dl
) + sizeof(link
.sdl_data
);
562 link
.sdl_family
= AF_LINK
;
563 link
.sdl_nlen
= length
;
565 memcpy(link
.sdl_data
, name
, link
.sdl_nlen
);
567 link
.sdl_len
= sizeof(sockaddr_dl
);
568 if (link
.sdl_nlen
> sizeof(link
.sdl_data
))
569 link
.sdl_len
+= link
.sdl_nlen
- sizeof(link
.sdl_data
);
576 BNetworkAddress::SetToLinkLevel(uint32 index
)
578 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
579 memset(&link
, 0, sizeof(sockaddr_dl
));
581 link
.sdl_family
= AF_LINK
;
582 link
.sdl_len
= sizeof(sockaddr_dl
);
583 link
.sdl_index
= index
;
590 BNetworkAddress::SetLinkLevelIndex(uint32 index
)
592 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
593 link
.sdl_index
= index
;
598 BNetworkAddress::SetLinkLevelType(uint8 type
)
600 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
601 link
.sdl_type
= type
;
606 BNetworkAddress::SetLinkLevelFrameType(uint16 frameType
)
608 sockaddr_dl
& link
= (sockaddr_dl
&)fAddress
;
609 link
.sdl_e_type
= htons(frameType
);
614 BNetworkAddress::Family() const
616 return fAddress
.ss_family
;
621 BNetworkAddress::Port() const
623 switch (fAddress
.ss_family
) {
625 return ntohs(((sockaddr_in
&)fAddress
).sin_port
);
628 return ntohs(((sockaddr_in6
&)fAddress
).sin6_port
);
637 BNetworkAddress::Length() const
639 return fAddress
.ss_len
;
644 BNetworkAddress::SockAddr() const
646 return (const sockaddr
&)fAddress
;
651 BNetworkAddress::SockAddr()
653 return (sockaddr
&)fAddress
;
658 BNetworkAddress::IsEmpty() const
660 if (fAddress
.ss_len
== 0)
663 switch (fAddress
.ss_family
) {
668 sockaddr_in
& sin
= (sockaddr_in
&)fAddress
;
669 return sin
.sin_addr
.s_addr
== INADDR_ANY
&& sin
.sin_port
== 0;
673 sockaddr_in6
& sin6
= (sockaddr_in6
&)fAddress
;
674 return IN6_IS_ADDR_UNSPECIFIED(&sin6
.sin6_addr
)
675 && sin6
.sin6_port
== 0;
685 BNetworkAddress::IsWildcard() const
687 switch (fAddress
.ss_family
) {
689 return ((sockaddr_in
&)fAddress
).sin_addr
.s_addr
== INADDR_ANY
;
692 return !memcmp(&((sockaddr_in6
&)fAddress
).sin6_addr
, &in6addr_any
,
702 BNetworkAddress::IsBroadcast() const
704 switch (fAddress
.ss_family
) {
706 return ((sockaddr_in
&)fAddress
).sin_addr
.s_addr
== INADDR_BROADCAST
;
709 // There is no broadcast in IPv6, only multicast/anycast
710 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6
&)fAddress
).sin6_addr
);
719 BNetworkAddress::IsMulticast() const
721 switch (fAddress
.ss_family
) {
723 return IN_MULTICAST(((sockaddr_in
&)fAddress
).sin_addr
.s_addr
);
726 return IN6_IS_ADDR_MULTICAST(&((sockaddr_in6
&)fAddress
).sin6_addr
);
735 BNetworkAddress::IsMulticastGlobal() const
737 switch (fAddress
.ss_family
) {
739 return IN6_IS_ADDR_MC_GLOBAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
748 BNetworkAddress::IsMulticastNodeLocal() const
750 switch (fAddress
.ss_family
) {
752 return IN6_IS_ADDR_MC_NODELOCAL(
753 &((sockaddr_in6
&)fAddress
).sin6_addr
);
762 BNetworkAddress::IsMulticastLinkLocal() const
764 switch (fAddress
.ss_family
) {
766 return IN6_IS_ADDR_MC_LINKLOCAL(
767 &((sockaddr_in6
&)fAddress
).sin6_addr
);
776 BNetworkAddress::IsMulticastSiteLocal() const
778 switch (fAddress
.ss_family
) {
780 return IN6_IS_ADDR_MC_SITELOCAL(
781 &((sockaddr_in6
&)fAddress
).sin6_addr
);
790 BNetworkAddress::IsMulticastOrgLocal() const
792 switch (fAddress
.ss_family
) {
794 return IN6_IS_ADDR_MC_ORGLOCAL(
795 &((sockaddr_in6
&)fAddress
).sin6_addr
);
804 BNetworkAddress::IsLinkLocal() const
807 switch (fAddress
.ss_family
) {
809 return IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
818 BNetworkAddress::IsSiteLocal() const
820 switch (fAddress
.ss_family
) {
822 return IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6
&)fAddress
).sin6_addr
);
831 BNetworkAddress::IsLocal() const
833 BNetworkRoster
& roster
= BNetworkRoster::Default();
835 BNetworkInterface interface
;
838 while (roster
.GetNextInterface(&cookie
, interface
) == B_OK
) {
839 int32 count
= interface
.CountAddresses();
840 for (int32 j
= 0; j
< count
; j
++) {
841 BNetworkInterfaceAddress address
;
842 if (interface
.GetAddressAt(j
, address
) != B_OK
)
845 if (Equals(address
.Address(), false))
855 BNetworkAddress::PrefixLength() const
857 switch (fAddress
.ss_family
) {
860 sockaddr_in
& mask
= (sockaddr_in
&)fAddress
;
862 uint32 hostMask
= ntohl(mask
.sin_addr
.s_addr
);
863 return addr_bitcount(hostMask
);
868 sockaddr_in6
& mask
= (sockaddr_in6
&)fAddress
;
870 // TODO : see if we can use the optimized addr_bitcount for this
872 for (uint8 i
= 0; i
< sizeof(in6_addr
); i
++) {
873 for (uint8 j
= 0; j
< 8; j
++) {
874 if (!(mask
.sin6_addr
.s6_addr
[i
] & (1 << j
)))
884 return B_NOT_SUPPORTED
;
890 BNetworkAddress::LinkLevelIndex() const
892 return ((sockaddr_dl
&)fAddress
).sdl_index
;
897 BNetworkAddress::LinkLevelInterface() const
899 sockaddr_dl
& address
= (sockaddr_dl
&)fAddress
;
900 if (address
.sdl_nlen
== 0)
904 name
.SetTo((const char*)address
.sdl_data
, address
.sdl_nlen
);
911 BNetworkAddress::LinkLevelType() const
913 return ((sockaddr_dl
&)fAddress
).sdl_type
;
918 BNetworkAddress::LinkLevelFrameType() const
920 return ntohs(((sockaddr_dl
&)fAddress
).sdl_e_type
);
925 BNetworkAddress::LinkLevelAddress() const
927 return LLADDR(&(sockaddr_dl
&)fAddress
);
932 BNetworkAddress::LinkLevelAddressLength() const
934 return ((sockaddr_dl
&)fAddress
).sdl_alen
;
939 BNetworkAddress::ResolveForDestination(const BNetworkAddress
& destination
)
943 if (destination
.fAddress
.ss_family
!= fAddress
.ss_family
)
947 memset(buffer
, 0, sizeof(buffer
));
949 route_entry
* route
= (route_entry
*)buffer
;
950 route
->destination
= (sockaddr
*)&destination
.fAddress
;
952 int socket
= ::socket(fAddress
.ss_family
, SOCK_DGRAM
, 0);
956 if (ioctl(socket
, SIOCGETRT
, route
, sizeof(buffer
)) != 0) {
961 uint16 port
= Port();
962 memcpy(&fAddress
, route
->source
, sizeof(sockaddr_storage
));
970 BNetworkAddress::ResolveTo(const BNetworkAddress
& address
)
974 if (address
.fAddress
.ss_family
!= fAddress
.ss_family
)
977 uint16 port
= Port();
986 BNetworkAddress::ToString(bool includePort
) const
990 switch (fAddress
.ss_family
) {
992 inet_ntop(AF_INET
, &((sockaddr_in
&)fAddress
).sin_addr
, buffer
,
997 inet_ntop(AF_INET6
, &((sockaddr_in6
&)fAddress
).sin6_addr
,
998 buffer
, sizeof(buffer
));
1003 uint8
*byte
= LinkLevelAddress();
1004 char* target
= buffer
;
1005 int bytesLeft
= sizeof(buffer
);
1008 for (size_t i
= 0; i
< LinkLevelAddressLength(); i
++) {
1009 if (i
!= 0 && bytesLeft
> 1) {
1016 int bytesWritten
= snprintf(target
, bytesLeft
, "%02x", byte
[i
]);
1017 if (bytesWritten
>= bytesLeft
)
1020 target
+= bytesWritten
;
1021 bytesLeft
-= bytesWritten
;
1030 BString address
= buffer
;
1031 if (includePort
&& Port() != 0) {
1032 if (fAddress
.ss_family
== AF_INET6
) {
1038 snprintf(buffer
, sizeof(buffer
), ":%u", Port());
1047 BNetworkAddress::HostName() const
1049 // TODO: implement host name lookup
1050 return ToString(false);
1055 BNetworkAddress::ServiceName() const
1057 // TODO: implement service lookup
1065 BNetworkAddress::Equals(const BNetworkAddress
& other
, bool includePort
) const
1067 if (IsEmpty() && other
.IsEmpty())
1070 if (Family() != other
.Family()
1071 || (includePort
&& Port() != other
.Port())) {
1075 switch (fAddress
.ss_family
) {
1078 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
1079 sockaddr_in
& otherAddress
= (sockaddr_in
&)other
.fAddress
;
1080 return memcmp(&address
.sin_addr
, &otherAddress
.sin_addr
,
1081 sizeof(address
.sin_addr
)) == 0;
1086 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
1087 sockaddr_in6
& otherAddress
= (sockaddr_in6
&)other
.fAddress
;
1088 return memcmp(&address
.sin6_addr
, &otherAddress
.sin6_addr
,
1089 sizeof(address
.sin6_addr
)) == 0;
1093 if (fAddress
.ss_len
!= other
.fAddress
.ss_len
)
1096 return memcmp(&fAddress
, &other
.fAddress
, fAddress
.ss_len
);
1101 // #pragma mark - BFlattenable implementation
1105 BNetworkAddress::IsFixedSize() const
1112 BNetworkAddress::TypeCode() const
1114 return B_NETWORK_ADDRESS_TYPE
;
1119 BNetworkAddress::FlattenedSize() const
1126 BNetworkAddress::Flatten(void* buffer
, ssize_t size
) const
1128 if (buffer
== NULL
|| size
< FlattenedSize())
1131 memcpy(buffer
, &fAddress
, Length());
1137 BNetworkAddress::Unflatten(type_code code
, const void* buffer
, ssize_t size
)
1139 // 2 bytes minimum for family, and length
1140 if (buffer
== NULL
|| size
< 2)
1141 return fStatus
= B_BAD_VALUE
;
1142 if (!AllowsTypeCode(code
))
1143 return fStatus
= B_BAD_TYPE
;
1145 memcpy(&fAddress
, buffer
, min_c(size
, (ssize_t
)sizeof(fAddress
)));
1147 // check if this can contain a valid address
1148 if (fAddress
.ss_family
!= AF_UNSPEC
&& size
< (ssize_t
)sizeof(sockaddr
))
1149 return fStatus
= B_BAD_VALUE
;
1151 return fStatus
= B_OK
;
1155 // #pragma mark - operators
1159 BNetworkAddress::operator=(const BNetworkAddress
& other
)
1161 memcpy(&fAddress
, &other
.fAddress
, other
.fAddress
.ss_len
);
1162 fStatus
= other
.fStatus
;
1169 BNetworkAddress::operator==(const BNetworkAddress
& other
) const
1171 return Equals(other
);
1176 BNetworkAddress::operator!=(const BNetworkAddress
& other
) const
1178 return !Equals(other
);
1183 BNetworkAddress::operator<(const BNetworkAddress
& other
) const
1185 if (Family() < other
.Family())
1187 if (Family() > other
.Family())
1192 switch (fAddress
.ss_family
) {
1196 sockaddr_in
& address
= (sockaddr_in
&)fAddress
;
1197 sockaddr_in
& otherAddress
= (sockaddr_in
&)other
.fAddress
;
1198 compare
= memcmp(&address
.sin_addr
, &otherAddress
.sin_addr
,
1199 sizeof(address
.sin_addr
));
1205 sockaddr_in6
& address
= (sockaddr_in6
&)fAddress
;
1206 sockaddr_in6
& otherAddress
= (sockaddr_in6
&)other
.fAddress
;
1207 compare
= memcmp(&address
.sin6_addr
, &otherAddress
.sin6_addr
,
1208 sizeof(address
.sin6_addr
));
1213 if (LinkLevelAddressLength() < other
.LinkLevelAddressLength())
1215 if (LinkLevelAddressLength() > other
.LinkLevelAddressLength())
1218 // TODO: could compare index, and name, too
1219 compare
= memcmp(LinkLevelAddress(), other
.LinkLevelAddress(),
1220 LinkLevelAddressLength());
1229 return Port() < other
.Port();
1233 BNetworkAddress::operator const sockaddr
*() const
1235 return (const sockaddr
*)&fAddress
;
1239 BNetworkAddress::operator const sockaddr
&() const
1241 return (const sockaddr
&)fAddress
;
1245 BNetworkAddress::operator sockaddr
*()
1247 return (sockaddr
*)&fAddress
;
1251 BNetworkAddress::operator const sockaddr
*()
1253 return (sockaddr
*)&fAddress
;
1257 BNetworkAddress::operator sockaddr
&()
1259 return (sockaddr
&)fAddress
;
1263 BNetworkAddress::operator const sockaddr
&()
1265 return (sockaddr
&)fAddress
;
1269 // #pragma mark - private
1273 BNetworkAddress::_ParseLinkAddress(const char* address
)
1275 if (address
== NULL
)
1278 uint8 linkAddress
[128];
1280 while (length
< sizeof(linkAddress
)) {
1281 if (!isxdigit(address
[0]) || !isxdigit(address
[1]))
1284 linkAddress
[length
++] = (from_hex(address
[0]) << 4)
1285 | from_hex(address
[1]);
1287 if (address
[2] == '\0')
1289 if (address
[2] != ':')
1295 SetToLinkLevel(linkAddress
, length
);