[gupnp] linux-cm: Fix Netmask calculation



commit cb60bfbb01581f138a68cd8129f1c5371d289986
Author: Jens Georg <mail jensge org>
Date:   Sun Nov 4 17:19:54 2018 +0100

    linux-cm: Fix Netmask calculation

 libgupnp/gupnp-linux-context-manager.c | 36 +++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)
---
diff --git a/libgupnp/gupnp-linux-context-manager.c b/libgupnp/gupnp-linux-context-manager.c
index 5b4b580..c32080c 100644
--- a/libgupnp/gupnp-linux-context-manager.c
+++ b/libgupnp/gupnp-linux-context-manager.c
@@ -116,9 +116,9 @@ dump_rta_attr (sa_family_t family, struct rtattr *rt_attr)
                         rt_attr->rta_type == IFA_BROADCAST ||
                         rt_attr->rta_type == IFA_ANYCAST) {
                 data = inet_ntop (family,
-                                RTA_DATA (rt_attr),
-                                buf,
-                                sizeof (buf));
+                                  RTA_DATA (rt_attr),
+                                  buf,
+                                  sizeof (buf));
         } else if (rt_attr->rta_type == IFA_LABEL) {
                 data = (const char *) RTA_DATA (rt_attr);
         } else {
@@ -452,15 +452,33 @@ extract_info (struct nlmsghdr *header,
                         }
 
                         if (mask != NULL) {
-                                struct in_addr addr, *data;
-                                guint32 bitmask;
+                                struct in6_addr addr = { 0 }, *data;
+                                int i = 0, bits = prefixlen;
+                                guint8 *outbuf = (guint8 *)&addr.s6_addr;
+                                guint8 *inbuf;
 
-                                bitmask = htonl(G_MAXUINT32 << (32 - prefixlen));
                                 data = RTA_DATA (rt_attr);
+                                inbuf = (guint8 *)&data->s6_addr;
+
+                                for (i = 0; i < (family == AF_INET ? 4 : 16); i++) {
+                                        if (bits > 8) {
+                                                bits -= 8;
+                                                outbuf[i] = inbuf[i] & 0xff;
+                                        } else {
+                                                static const guint8 bits_a[] =
+                                                { 0x00, 0x08, 0x0C, 0x0E, 0x0F };
+
+                                                if (bits >= 4) {
+                                                        outbuf[i] = inbuf[i] & 0xf0;
+                                                        bits -= 4;
+                                                }
+                                                outbuf[i] = outbuf[i] |
+                                                            (inbuf[i] & bits_a[bits]);
+                                                break;
+                                        }
+                                }
 
-                                addr.s_addr = data->s_addr & bitmask;
-
-                                inet_ntop (AF_INET,
+                                inet_ntop (family,
                                            &addr,
                                            buf,
                                            sizeof (buf));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]