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

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 11 Aug 2010 15:53:31 +0200 (CEST)

Author: axeld
Date: 2010-08-11 15:53:31 +0200 (Wed, 11 Aug 2010)
New Revision: 38026
Changeset: http://dev.haiku-os.org/changeset/38026

Modified:
   haiku/trunk/headers/os/net/NetworkAddress.h
   haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp
Log:
* Implemented SetToMask(), and added PrefixLength() method, mostly reusing
  code from ifconfig.


Modified: haiku/trunk/headers/os/net/NetworkAddress.h
===================================================================
--- haiku/trunk/headers/os/net/NetworkAddress.h 2010-08-11 13:25:36 UTC (rev 
38025)
+++ haiku/trunk/headers/os/net/NetworkAddress.h 2010-08-11 13:53:31 UTC (rev 
38026)
@@ -82,6 +82,8 @@
                        bool                            IsSiteLocal() const;
                        bool                            IsLocal() const;
                        
+                       ssize_t                         PrefixLength() const;
+
                        uint32                          LinkLevelIndex() const;
                        BString                         LinkLevelInterface() 
const;
                        uint32                          LinkLevelType() const;

Modified: haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp
===================================================================
--- haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp   2010-08-11 
13:25:36 UTC (rev 38025)
+++ haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp   2010-08-11 
13:53:31 UTC (rev 38026)
@@ -423,8 +423,52 @@
 status_t
 BNetworkAddress::SetToMask(int family, uint32 prefixLength)
 {
-       // TODO: implement SetToMask()
-       return B_NOT_SUPPORTED;
+       switch (family) {
+               case AF_INET:
+               {
+                       if (prefixLength > 32)
+                               return B_BAD_VALUE;
+               
+                       sockaddr_in& mask = (sockaddr_in&)fAddress;
+                       memset(&fAddress, 0, sizeof(sockaddr_storage));
+                       mask.sin_family = AF_INET;
+                       mask.sin_len = sizeof(sockaddr_in);
+               
+                       uint32 hostMask = 0;
+                       for (uint8 i = 32; i > 32 - prefixLength; i--)
+                               hostMask |= 1 << (i - 1);
+
+                       mask.sin_addr.s_addr = htonl(hostMask);
+                       break;
+               }
+
+               case AF_INET6:
+               {
+                       if (prefixLength > 128)
+                               return B_BAD_VALUE;
+
+                       sockaddr_in6& mask = (sockaddr_in6&)fAddress;
+                       memset(&fAddress, 0, sizeof(sockaddr_storage));
+                       mask.sin6_family = AF_INET6;
+                       mask.sin6_len = sizeof(sockaddr_in6);
+               
+                       for (uint8 i = 0; i < sizeof(in6_addr); i++, 
prefixLength -= 8) {
+                               if (prefixLength < 8) {
+                                       mask.sin6_addr.s6_addr[i]
+                                               = (uint8)(0xff << (8 - 
prefixLength));
+                                       break;
+                               }
+               
+                               mask.sin6_addr.s6_addr[i] = 0xff;
+                       }
+                       break;
+               }
+
+               default:
+                       return B_NOT_SUPPORTED;
+       }
+
+       return B_OK;
 }
 
 
@@ -709,6 +753,47 @@
 }
 
 
+ssize_t
+BNetworkAddress::PrefixLength() const
+{
+       switch (fAddress.ss_family) {
+               case AF_INET:
+               {
+                       sockaddr_in& mask = (sockaddr_in&)fAddress;
+               
+                       ssize_t result = 0;
+                       uint32 hostMask = ntohl(mask.sin_addr.s_addr);
+                       for (uint8 i = 32; i > 0; i--) {
+                               if ((hostMask & (1 << (i - 1))) == 0)
+                                       break;
+                               result++;
+                       }
+
+                       return result;
+               }
+
+               case AF_INET6:
+               {
+                       sockaddr_in6& mask = (sockaddr_in6&)fAddress;
+
+                       ssize_t result = 0;
+                       for (uint8 i = 0; i < sizeof(in6_addr); i++) {
+                               for (uint8 j = 0; j < 8; j++) {
+                                       if (!(mask.sin6_addr.s6_addr[i] & (1 << 
j)))
+                                               return result;
+                                       result++;
+                               }
+                       }
+               
+                       return 128;
+               }
+
+               default:
+                       return B_NOT_SUPPORTED;
+       }
+}
+
+
 uint32
 BNetworkAddress::LinkLevelIndex() const
 {


Other related posts:

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