chiark / gitweb /
shared: in-addr-utils - add default_subnet_mask and default_prefixlen methods
authorTom Gundersen <teg@jklm.no>
Mon, 27 Oct 2014 16:38:03 +0000 (17:38 +0100)
committerTom Gundersen <teg@jklm.no>
Mon, 27 Oct 2014 16:40:24 +0000 (17:40 +0100)
These use the (deprecated) IPv4 address classes to deduce the corresponding subnet masks. This is useful when addresses
without subnet masks and prefix lengths are given.

Make use of these new functions from sd-dhcp-lease.

src/libsystemd-network/sd-dhcp-lease.c
src/shared/in-addr-util.c
src/shared/in-addr-util.h

index 6680d06736242f7db332495b2f5c03a0d82d3f27..4fb01c07299b2cab631134ca79a13e64cda9a65c 100644 (file)
@@ -30,6 +30,7 @@
 #include "list.h"
 #include "mkdir.h"
 #include "fileio.h"
+#include "in-addr-util.h"
 
 #include "dhcp-protocol.h"
 #include "dhcp-internal.h"
@@ -803,27 +804,20 @@ int dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) {
 }
 
 int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
-        uint32_t address;
+        struct in_addr address;
+        struct in_addr mask;
+        int r;
 
         assert(lease);
-        assert(lease->address != INADDR_ANY);
 
-        address = be32toh(lease->address);
+        address.s_addr = lease->address;
 
         /* fall back to the default subnet masks based on address class */
+        r = in_addr_default_subnet_mask(&address, &mask);
+        if (r < 0)
+                return r;
 
-        if ((address >> 31) == 0x0)
-                /* class A, leading bits: 0 */
-                lease->subnet_mask = htobe32(0xff000000);
-        else if ((address >> 30) == 0x2)
-                /* class B, leading bits 10 */
-                lease->subnet_mask = htobe32(0xffff0000);
-        else if ((address >> 29) == 0x6)
-                /* class C, leading bits 110 */
-                lease->subnet_mask = htobe32(0xffffff00);
-        else
-                /* class D or E, no default mask. give up */
-                return -ERANGE;
+        lease->subnet_mask = mask.s_addr;
 
         return 0;
 }
index 457eedd6d81825f519984f06884cc0c91ab4c6c0..5fbee6caf2fcbf0562c6b35b83eba3cb92f7ec3b 100644 (file)
@@ -248,3 +248,46 @@ unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr) {
 
         return 32 - u32ctz(be32toh(addr->s_addr));
 }
+
+int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) {
+        uint32_t address;
+
+        assert(addr);
+        assert(addr->s_addr != INADDR_ANY);
+        assert(prefixlen);
+
+        address = be32toh(addr->s_addr);
+
+        if ((address >> 31) == 0x0)
+                /* class A, leading bits: 0 */
+                *prefixlen = 8;
+        else if ((address >> 30) == 0x2)
+                /* class B, leading bits 10 */
+                *prefixlen = 16;
+        else if ((address >> 29) == 0x6)
+                /* class C, leading bits 110 */
+                *prefixlen = 24;
+        else
+                /* class D or E, no default prefixlen */
+                return -ERANGE;
+
+        return 0;
+}
+
+int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) {
+        unsigned char prefixlen;
+        int r;
+
+        assert(addr);
+        assert(mask);
+
+        r = in_addr_default_prefixlen(addr, &prefixlen);
+        if (r < 0)
+                return r;
+
+        assert(prefixlen > 0 && prefixlen < 32);
+
+        mask->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff);
+
+        return 0;
+}
index 0036acee225df770769c7bd270ebccf8b0d2f280..8da030ceb66b5f5129e746eecd423a373c18819b 100644 (file)
@@ -40,6 +40,8 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
 int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
 int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret);
 unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr);
+int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
+int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask);
 
 static inline size_t FAMILY_ADDRESS_SIZE(int family) {
         assert(family == AF_INET || family == AF_INET6);