[haiku-commits] r37988 - in haiku/trunk: headers/os/net src/kits/network/libnetapi

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 9 Aug 2010 18:31:40 +0200 (CEST)

Author: axeld
Date: 2010-08-09 18:31:40 +0200 (Mon, 09 Aug 2010)
New Revision: 37988
Changeset: http://dev.haiku-os.org/changeset/37988

Modified:
   haiku/trunk/headers/os/net/NetworkAddress.h
   haiku/trunk/headers/os/net/NetworkInterface.h
   haiku/trunk/headers/os/net/NetworkRoster.h
   haiku/trunk/src/kits/network/libnetapi/Jamfile
   haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp
   haiku/trunk/src/kits/network/libnetapi/NetworkInterface.cpp
   haiku/trunk/src/kits/network/libnetapi/NetworkRoster.cpp
Log:
* Adapted API as needed, and implemented most of the C++ API - it's completely
  untested at this point, though.
* Will port ifconfig, NetworkStatus, and the Network preferences application
  later in order to test the API.


Modified: haiku/trunk/headers/os/net/NetworkAddress.h
===================================================================
--- haiku/trunk/headers/os/net/NetworkAddress.h 2010-08-09 16:30:28 UTC (rev 
37987)
+++ haiku/trunk/headers/os/net/NetworkAddress.h 2010-08-09 16:31:40 UTC (rev 
37988)
@@ -12,6 +12,7 @@
 #include <sys/socket.h>
 
 #include <Archivable.h>
+#include <String.h>
 
 
 class BNetworkAddress : public BArchivable {
@@ -21,10 +22,12 @@
                                                                        const 
char* address, uint16 port = 0);
                                                                
BNetworkAddress(const char* address,
                                                                        uint16 
port = 0);
-                                                               
BNetworkAddress(const sockaddr* address);
-                                                               
BNetworkAddress(const sockaddr_in* address);
-                                                               
BNetworkAddress(const sockaddr_in6* address);
-                                                               
BNetworkAddress(const sockaddr_dl* address);
+                                                               
BNetworkAddress(const sockaddr& address);
+                                                               BNetworkAddress(
+                                                                       const 
sockaddr_storage& address);
+                                                               
BNetworkAddress(const sockaddr_in& address);
+                                                               
BNetworkAddress(const sockaddr_in6& address);
+                                                               
BNetworkAddress(const sockaddr_dl& address);
                                                                
BNetworkAddress(const in_addr_t address);
                                                                
BNetworkAddress(const in6_addr* address);
                                                                
BNetworkAddress(const BNetworkAddress& other);
@@ -38,10 +41,11 @@
                        status_t                        SetTo(int family, const 
char* address,
                                                                        uint16 
port = 0);
                        status_t                        SetTo(const char* 
address, uint16 port = 0);
-                       void                            SetTo(const sockaddr* 
address);
-                       void                            SetTo(const 
sockaddr_in* address);
-                       void                            SetTo(const 
sockaddr_in6* address);
-                       void                            SetTo(const 
sockaddr_dl* address);
+                       void                            SetTo(const sockaddr& 
address);
+                       void                            SetTo(const 
sockaddr_storage& address);
+                       void                            SetTo(const 
sockaddr_in& address);
+                       void                            SetTo(const 
sockaddr_in6& address);
+                       void                            SetTo(const 
sockaddr_dl& address);
                        void                            SetTo(const in_addr_t 
address);
                        void                            SetTo(const in6_addr* 
address);
                        void                            SetTo(const 
BNetworkAddress& other);
@@ -63,6 +67,7 @@
                        int                                     Family() const;
                        uint16                          Port() const;
                        size_t                          Length() const;
+                       const sockaddr&         SockAddr() const;
 
                        bool                            IsEmpty() const;
                        bool                            IsWildcard() const;
@@ -84,17 +89,20 @@
                        uint8*                          LinkLevelAddress() 
const;
                        size_t                          
LinkLevelAddressLength() const;
 
-                       BNetworkAddress         ResolvedForDestination(
-                                                                       const 
BNetworkAddress& destination) const;
-                       void                            ResolveTo(const 
BNetworkAddress& address);
+                       status_t                        ResolveForDestination(
+                                                                       const 
BNetworkAddress& destination);
+                       status_t                        ResolveTo(const 
BNetworkAddress& address);
 
-                       BString                         ToString() const;
+                       BString                         ToString(bool 
includePort = true) const;
                        BString                         HostName() const;
                        BString                         PortName() const;
 
        virtual status_t                        Archive(BMessage* into, bool 
deep = true) const;
        static  BArchivable*            Instantiate(BMessage* archive);
 
+                       bool                            Equals(const 
BNetworkAddress& other,
+                                                                       bool 
includePort = true) const;
+
                        BNetworkAddress&        operator=(const 
BNetworkAddress& other);
 
                        bool                            operator==(const 
BNetworkAddress& other) const;

Modified: haiku/trunk/headers/os/net/NetworkInterface.h
===================================================================
--- haiku/trunk/headers/os/net/NetworkInterface.h       2010-08-09 16:30:28 UTC 
(rev 37987)
+++ haiku/trunk/headers/os/net/NetworkInterface.h       2010-08-09 16:31:40 UTC 
(rev 37988)
@@ -21,9 +21,12 @@
                                                                
BNetworkInterfaceAddress();
                                                                
~BNetworkInterfaceAddress();
 
+                       status_t                        
SetTo(BNetworkInterface& interface,
+                                                                       int32 
index);
+
                        void                            
SetAddress(BNetworkAddress& address);
                        void                            
SetMask(BNetworkAddress& mask);
-                       void                            
SetBroadcast(BNetworkAddress& mask);
+                       void                            
SetBroadcast(BNetworkAddress& broadcast);
 
                        BNetworkAddress&        Address() { return fAddress; }
                        BNetworkAddress&        Mask() { return fMask; }
@@ -36,9 +39,10 @@
                        void                            SetFlags(uint32 flags);
                        uint32                          Flags() const { return 
fFlags; }
 
+                       int32                           Index() const { return 
fIndex; }
+
 private:
-                       BNetworkInterface*      fInterface;
-                       uint32                          fIndex;
+                       int32                           fIndex;
                        BNetworkAddress         fAddress;
                        BNetworkAddress         fMask;
                        BNetworkAddress         fBroadcast;
@@ -53,9 +57,14 @@
                                                                
BNetworkInterface(uint32 index);
                                                                
~BNetworkInterface();
 
+                       void                            Unset();
+                       void                            SetTo(const char* name);
+                       status_t                        SetTo(uint32 index);
+
                        bool                            Exists() const;
 
                        const char*                     Name() const;
+                       uint32                          Index() const;
                        uint32                          Flags() const;
                        uint32                          MTU() const;
                        uint32                          Type() const;
@@ -66,10 +75,13 @@
                        status_t                        SetMTU(uint32 mtu);
 
                        int32                           CountAddresses() const;
-                       BNetworkInterfaceAddress* AddressAt(int32 index);
+                       status_t                        GetAddressAt(int32 
index,
+                                                                       
BNetworkInterfaceAddress& address);
 
                        status_t                        AddAddress(
                                                                        const 
BNetworkInterfaceAddress& address);
+                       status_t                        SetAddress(
+                                                                       const 
BNetworkInterfaceAddress& address);
                        status_t                        RemoveAddress(
                                                                        const 
BNetworkInterfaceAddress& address);
                        status_t                        RemoveAddressAt(int32 
index);
@@ -78,7 +90,6 @@
 
 private:
                        char                            fName[IF_NAMESIZE];
-                       uint32                          fIndex;
                        BList                           fAddresses;
 };
 

Modified: haiku/trunk/headers/os/net/NetworkRoster.h
===================================================================
--- haiku/trunk/headers/os/net/NetworkRoster.h  2010-08-09 16:30:28 UTC (rev 
37987)
+++ haiku/trunk/headers/os/net/NetworkRoster.h  2010-08-09 16:31:40 UTC (rev 
37988)
@@ -6,7 +6,7 @@
 #define _NETWORK_ROSTER_H
 
 
-#include <SupportDefs.h>
+#include <Locker.h>
 
 
 class BMessenger;
@@ -17,14 +17,14 @@
 public:
        static  BNetworkRoster&         Default();
 
-                       int32                           CountInterfaces();
-                       BNetworkInterface*      InterfaceAt(int32 index);
+                       size_t                          CountInterfaces() const;
+                       status_t                        
GetNextInterface(uint32* cookie,
+                                                                       
BNetworkInterface& interface) const;
 
                        status_t                        AddInterface(
                                                                        const 
BNetworkInterface& interface);
                        status_t                        RemoveInterface(
                                                                        const 
BNetworkInterface& interface);
-                       status_t                        RemoveInterfaceAt(int32 
index);
 
                        status_t                        StartWatching(const 
BMessenger& target,
                                                                        uint32 
eventMask);
@@ -33,6 +33,9 @@
 private:
                                                                
BNetworkRoster();
                                                                
~BNetworkRoster();
+
+private:
+       static  BNetworkRoster          sDefault;
 };
 
 

Modified: haiku/trunk/src/kits/network/libnetapi/Jamfile
===================================================================
--- haiku/trunk/src/kits/network/libnetapi/Jamfile      2010-08-09 16:30:28 UTC 
(rev 37987)
+++ haiku/trunk/src/kits/network/libnetapi/Jamfile      2010-08-09 16:31:40 UTC 
(rev 37988)
@@ -1,6 +1,6 @@
 SubDir HAIKU_TOP src kits network libnetapi ;
 
-UsePrivateHeaders net ;
+UsePrivateHeaders net shared ;
 
 SharedLibrary libbnetapi.so :
        init.cpp

Modified: haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp
===================================================================
--- haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp   2010-08-09 
16:30:28 UTC (rev 37987)
+++ haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp   2010-08-09 
16:31:40 UTC (rev 37988)
@@ -6,3 +6,972 @@
 
 #include <NetworkAddress.h>
 
+#include <ByteOrder.h>
+#include <NetworkInterface.h>
+#include <NetworkRoster.h>
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+
+
+static bool
+strip_port(BString& host, BString& port)
+{
+       int32 separator = host.FindFirst(':');
+       if (separator != -1) {
+               // looks like there is a port
+               host.CopyInto(port, separator + 1, -1);
+               host.Truncate(separator);
+
+               return true;
+       }
+
+       return false;
+}
+
+
+static status_t
+resolve_address(int family, const char* host, const char* port,
+       int type, sockaddr_storage& address)
+{
+       addrinfo hint = {0};
+       hint.ai_family = family;
+       hint.ai_socktype = type;
+       hint.ai_protocol = 0;
+
+       if (host == NULL && port == NULL) {
+               port = "0";
+               hint.ai_flags = AI_PASSIVE;
+       }
+
+       addrinfo* info;
+       int status = getaddrinfo(host, port, &hint, &info);
+       if (status != 0) {
+               // TODO: improve error reporting
+               return B_ERROR;
+       }
+
+       bool foundAddress = false;
+
+       if (family == AF_UNSPEC) {
+               // Prefer IPv6 addresses over IPv4 addresses
+
+               for (const addrinfo* next = info; next != NULL; next = 
next->ai_next) {
+                       if (next->ai_family == AF_INET6) {
+                               memcpy(&address, next->ai_addr, 
next->ai_addrlen);
+                               foundAddress = true;
+                               break;
+                       }
+               }
+       }
+
+       if (!foundAddress) {
+               // No preferred, or no IPv6 address found, just take the first 
one
+               // that works
+               memcpy(&address, info->ai_addr, info->ai_addrlen);
+       }
+
+       freeaddrinfo(info);
+       return B_OK;
+}
+
+
+// #pragma mark -
+
+
+BNetworkAddress::BNetworkAddress(int family, const char* host, uint16 port)
+{
+       SetTo(family, host, port);
+}
+
+
+BNetworkAddress::BNetworkAddress(const char* host, uint16 port)
+{
+       SetTo(host, port);
+}
+
+
+BNetworkAddress::BNetworkAddress(const sockaddr& address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const sockaddr_storage& address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const sockaddr_in& address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const sockaddr_in6& address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const sockaddr_dl& address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const in_addr_t address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const in6_addr* address)
+{
+       SetTo(address);
+}
+
+
+BNetworkAddress::BNetworkAddress(const BNetworkAddress& other)
+       :
+       fAddress(other.fAddress),
+       fStatus(other.fStatus)
+{
+}
+
+
+BNetworkAddress::BNetworkAddress(BMessage* archive)
+{
+       // TODO: implement me
+       fStatus = B_NO_INIT;
+}
+
+
+BNetworkAddress::BNetworkAddress()
+{
+       Unset();
+}
+
+
+BNetworkAddress::~BNetworkAddress()
+{
+}
+
+
+status_t
+BNetworkAddress::InitCheck() const
+{
+       return fStatus;
+}
+
+
+void
+BNetworkAddress::Unset()
+{
+       fAddress.ss_family = AF_UNSPEC;
+       fAddress.ss_len = 2;
+       fStatus = B_OK;
+}
+
+
+status_t
+BNetworkAddress::SetTo(int family, const char* host, uint16 port)
+{
+       // Check if the address contains a port
+
+       BString hostAddress(host);
+
+       BString portString;
+       if (strip_port(hostAddress, portString) && port == 0)
+               port = strtoul(portString.String(), NULL, 0);
+
+       // Resolve address
+
+       memset(&fAddress, 0, sizeof(sockaddr_storage));
+       fAddress.ss_family = family;
+
+       if (host != NULL) {
+               switch (family) {
+                       case AF_INET:
+                       {
+                               hostent* server = 
gethostbyname(hostAddress.String());
+                               if (server == NULL)
+                                       return errno;
+
+                               struct sockaddr_in& address = 
(sockaddr_in&)fAddress;
+                               address.sin_port = htons(port);
+                               address.sin_addr.s_addr = 
*(in_addr_t*)server->h_addr_list[0];
+                               break;
+                       }
+                       
+                       default:
+                       {
+                               fStatus = resolve_address(family, host, "0", 0, 
fAddress);
+                               if (fStatus != B_OK)
+                                       return fStatus;
+
+                               if (family == AF_INET6) {
+                                       struct sockaddr_in6& address = 
(sockaddr_in6&)fAddress;
+                                       address.sin6_port = htons(port);
+                               }
+                               break;
+                       }
+               }
+       } else {
+               switch (fAddress.ss_family) {
+                       case AF_INET:
+                       {
+                               struct sockaddr_in& address = 
(sockaddr_in&)fAddress;
+                               address.sin_port = htons(port);
+                               address.sin_addr.s_addr = INADDR_ANY;
+                               break;
+                       }
+
+                       case AF_INET6:
+                       {
+                               struct sockaddr_in6& address = 
(sockaddr_in6&)fAddress;
+                               address.sin6_port = htons(port);
+                               address.sin6_addr = in6addr_any;
+                               break;
+                       }
+
+                       default:
+                               return B_NOT_SUPPORTED;
+               }
+       }
+
+       return fStatus = B_OK;
+}
+
+
+status_t
+BNetworkAddress::SetTo(const char* host, uint16 port)
+{
+       // Check if the address contains a port
+
+       BString hostAddress(host);
+
+       BString portString;
+       strip_port(hostAddress, portString);
+
+       // Resolve address
+
+       memset(&fAddress, 0, sizeof(sockaddr_storage));
+
+       fStatus = resolve_address(AF_UNSPEC,
+               host != NULL ? hostAddress.String() : NULL,
+               portString.Length() == 0 ? NULL : portString.String(), 0, 
fAddress);
+       if (fStatus != B_OK)
+               return fStatus;
+
+       // Set port if specified separately
+
+       switch (fAddress.ss_family) {
+               case AF_INET:
+               {
+                       struct sockaddr_in& address = (sockaddr_in&)fAddress;
+                       if (address.sin_port == 0)
+                               address.sin_port = htons(port);
+                       break;
+               }
+
+               case AF_INET6:
+               {
+                       struct sockaddr_in6& address = (sockaddr_in6&)fAddress;
+                       if (address.sin6_port == 0)
+                               address.sin6_port = htons(port);
+                       break;
+               }
+
+               default:
+                       break;
+       }
+
+       return B_OK;
+}
+
+
+void
+BNetworkAddress::SetTo(const sockaddr& address)
+{
+       if (address.sa_family == AF_UNSPEC) {
+               Unset();
+               return;
+       }
+
+       size_t length = min_c(sizeof(sockaddr_storage), address.sa_len);
+       switch (address.sa_family) {
+               case AF_INET:
+                       length = sizeof(sockaddr_in);
+                       break;
+               case AF_INET6:
+                       length = sizeof(sockaddr_in6);
+                       break;
+               case AF_LINK:
+                       length = sizeof(sockaddr_dl);
+                       break;
+       }
+
+       memcpy(&fAddress, &address, length);
+       fAddress.ss_len = length;
+       fStatus = B_OK;
+}
+
+
+void
+BNetworkAddress::SetTo(const sockaddr_storage& address)
+{
+       SetTo((sockaddr&)address);
+}
+
+
+void
+BNetworkAddress::SetTo(const sockaddr_in& address)
+{
+       SetTo((sockaddr&)address);
+}
+
+
+void
+BNetworkAddress::SetTo(const sockaddr_in6& address)
+{
+       SetTo((sockaddr&)address);
+}
+
+
+void
+BNetworkAddress::SetTo(const sockaddr_dl& address)
+{
+       SetTo((sockaddr&)address);
+}
+
+
+void
+BNetworkAddress::SetTo(const in_addr_t inetAddress)
+{
+       sockaddr_in& address = (sockaddr_in&)fAddress;
+       memset(&fAddress, 0, sizeof(sockaddr_storage));
+
+       address.sin_family = AF_INET;
+       address.sin_len = sizeof(sockaddr_in);
+       address.sin_addr.s_addr = inetAddress;
+       fStatus = B_OK;
+}
+
+
+void
+BNetworkAddress::SetTo(const in6_addr* inet6Address)
+{
+       sockaddr_in6& address = (sockaddr_in6&)fAddress;
+       memset(&fAddress, 0, sizeof(sockaddr_storage));
+
+       address.sin6_family = AF_INET6;
+       address.sin6_len = sizeof(sockaddr_in6);
+       memcpy(address.sin6_addr.s6_addr, inet6Address,
+               sizeof(address.sin6_addr.s6_addr));
+       fStatus = B_OK;
+}
+
+
+void
+BNetworkAddress::SetTo(const BNetworkAddress& other)
+{
+       fAddress = other.fAddress;
+       fStatus = other.fStatus;
+}
+
+
+status_t
+BNetworkAddress::SetToBroadcast(int family, uint16 port)
+{
+       if (family != AF_INET)
+               return fStatus = B_NOT_SUPPORTED;
+
+       memset(&fAddress, 0, sizeof(sockaddr_storage));
+       fAddress.ss_family = family;
+       ((sockaddr_in&)fAddress).sin_addr.s_addr = INADDR_BROADCAST;
+
+       SetPort(port);
+       return fStatus = B_OK;
+}
+
+
+status_t
+BNetworkAddress::SetToLocal()
+{
+       // TODO: choose a local address from the network interfaces
+       return B_NOT_SUPPORTED;
+}
+
+
+status_t
+BNetworkAddress::SetToLoopback()
+{
+       return SetTo("localhost");
+}
+
+
+status_t
+BNetworkAddress::SetToMask(int family, uint32 prefixLength)
+{
+       // TODO: implement SetToMask()
+       return B_NOT_SUPPORTED;
+}
+
+
+status_t
+BNetworkAddress::SetToWildcard(int family)
+{
+       return SetTo(family, NULL);
+}
+
+
+void
+BNetworkAddress::SetPort(uint16 port)
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+                       ((sockaddr_in&)fAddress).sin_port = htons(port);
+                       break;
+
+               case AF_INET6:
+                       ((sockaddr_in6&)fAddress).sin6_port = htons(port);
+                       break;
+
+               default:
+                       break;
+       }
+}
+
+
+void
+BNetworkAddress::SetToLinkLevel(uint8* address, size_t length)
+{
+       // TODO: implement me!
+}
+
+
+void
+BNetworkAddress::SetToLinkLevel(const char* name)
+{
+       // TODO: implement me!
+}
+
+
+void
+BNetworkAddress::SetToLinkLevel(uint32 index)
+{
+       // TODO: implement me!
+}
+
+
+void
+BNetworkAddress::SetLinkLevelIndex(uint32 index)
+{
+       // TODO: implement me!
+}
+
+
+void
+BNetworkAddress::SetLinkLevelType(uint32 type)
+{
+       // TODO: implement me!
+}
+
+
+void
+BNetworkAddress::SetLinkLevelFrameType(uint32 frameType)
+{
+       // TODO: implement me!
+}
+
+
+int
+BNetworkAddress::Family() const
+{
+       return fAddress.ss_family;
+}
+
+
+uint16
+BNetworkAddress::Port() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+                       return ntohs(((sockaddr_in&)fAddress).sin_port);
+
+               case AF_INET6:
+                       return ntohs(((sockaddr_in6&)fAddress).sin6_port);
+
+               default:
+                       return 0;
+       }
+}
+
+
+size_t
+BNetworkAddress::Length() const
+{
+       return fAddress.ss_len;
+}
+
+
+const sockaddr&
+BNetworkAddress::SockAddr() const
+{
+       return (const sockaddr&)fAddress;
+}
+
+
+bool
+BNetworkAddress::IsEmpty() const
+{
+       return fAddress.ss_len == 0 || fAddress.ss_family == AF_UNSPEC;
+}
+
+
+bool
+BNetworkAddress::IsWildcard() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+                       return ((sockaddr_in&)fAddress).sin_addr.s_addr == 
INADDR_ANY;
+
+               case AF_INET6:
+                       return !memcmp(&((sockaddr_in6&)fAddress).sin6_addr, 
&in6addr_any,
+                               sizeof(in6_addr));
+
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsBroadcast() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+                       return ((sockaddr_in&)fAddress).sin_addr.s_addr == 
INADDR_BROADCAST;
+
+               case AF_INET6:
+                       // There is no broadcast in IPv6, only multicast/anycast
+                       return 
IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr);
+
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticast() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+                       return 
IN_MULTICAST(((sockaddr_in&)fAddress).sin_addr.s_addr);
+
+               case AF_INET6:
+                       return 
IN6_IS_ADDR_MULTICAST(&((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticastGlobal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return 
IN6_IS_ADDR_MC_GLOBAL(&((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticastNodeLocal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return IN6_IS_ADDR_MC_NODELOCAL(
+                               &((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticastLinkLocal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return IN6_IS_ADDR_MC_LINKLOCAL(
+                               &((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticastSiteLocal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return IN6_IS_ADDR_MC_SITELOCAL(
+                               &((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsMulticastOrgLocal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return IN6_IS_ADDR_MC_ORGLOCAL(
+                               &((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsLinkLocal() const
+{
+       // TODO: ipv4
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return 
IN6_IS_ADDR_LINKLOCAL(&((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsSiteLocal() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET6:
+                       return 
IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6&)fAddress).sin6_addr);
+               
+               default:
+                       return false;
+       }
+}
+
+
+bool
+BNetworkAddress::IsLocal() const
+{
+       BNetworkRoster& roster = BNetworkRoster::Default();
+
+       BNetworkInterface interface;
+       uint32 cookie = 0;
+
+       while (roster.GetNextInterface(&cookie, interface) == B_OK) {
+               int32 count = interface.CountAddresses();
+               for (int32 j = 0; j < count; j++) {
+                       BNetworkInterfaceAddress address;
+                       if (interface.GetAddressAt(j, address) != B_OK)
+                               break;
+
+                       if (Equals(address.Address(), false))
+                               return true;
+               }
+       }
+
+       return false;
+}
+
+
+uint32
+BNetworkAddress::LinkLevelIndex() const
+{
+       return ((sockaddr_dl&)fAddress).sdl_index;
+}
+
+
+BString
+BNetworkAddress::LinkLevelInterface() const
+{
+       sockaddr_dl& address = (sockaddr_dl&)fAddress;
+       if (address.sdl_nlen == 0)
+               return "";
+
+       BString name;
+       name.SetTo((const char*)address.sdl_data, address.sdl_nlen);
+
+       return name;
+}
+
+
+uint32
+BNetworkAddress::LinkLevelType() const
+{
+       return ((sockaddr_dl&)fAddress).sdl_type;
+}
+
+
+uint32
+BNetworkAddress::LinkLevelFrameType() const
+{
+       return ((sockaddr_dl&)fAddress).sdl_e_type;
+}
+
+
+uint8*
+BNetworkAddress::LinkLevelAddress() const
+{
+       return LLADDR(&(sockaddr_dl&)fAddress);
+}
+
+
+size_t
+BNetworkAddress::LinkLevelAddressLength() const
+{
+       return ((sockaddr_dl&)fAddress).sdl_alen;
+}
+
+
+status_t
+BNetworkAddress::ResolveForDestination(const BNetworkAddress& destination)
+{
+       if (!IsWildcard())
+               return B_OK;
+       if (destination.fAddress.ss_family != fAddress.ss_family)
+               return B_BAD_VALUE;
+
+       char buffer[2048];
+       memset(buffer, 0, sizeof(buffer));
+
+       route_entry* route = (route_entry*)buffer;
+       route->destination = (sockaddr*)&destination.fAddress;
+
+       int socket = ::socket(fAddress.ss_family, SOCK_DGRAM, 0);
+       if (socket < 0)
+               return errno;
+
+       if (ioctl(socket, SIOCGETRT, route, sizeof(buffer)) != 0) {
+               close(socket);
+               return errno;
+       }
+
+       uint16 port = Port();
+       memcpy(&fAddress, route->source, sizeof(sockaddr_storage));
+       SetPort(port);
+
+       return B_OK;
+}
+
+
+status_t
+BNetworkAddress::ResolveTo(const BNetworkAddress& address)
+{
+       if (!IsWildcard())
+               return B_OK;

[... truncated: 664 lines follow ...]

Other related posts:

  • » [haiku-commits] r37988 - in haiku/trunk: headers/os/net src/kits/network/libnetapi - axeld