Преглед изворни кода

misc/ipaddr6.h: rewrite ipaddr6_print_addr(), directly without using libraries

ambrop7 пре 13 година
родитељ
комит
0a7aaa0f30

+ 1 - 4
examples/ncdinterfacemonitor_test.c

@@ -129,10 +129,7 @@ void monitor_handler (void *unused, struct NCDInterfaceMonitor_event event)
             const char *type = (event.event == NCDIFMONITOR_EVENT_IPV6_ADDR_ADDED) ? "added" : "removed";
             
             char str[IPADDR6_PRINT_MAX];
-            if (!ipaddr6_print_addr(event.u.ipv6_addr.addr.addr, str)) {
-                DEBUG("ipaddr6_print_addr failed");
-                return;
-            }
+            ipaddr6_print_addr(event.u.ipv6_addr.addr.addr, str);
             
             int dynamic = !!(event.u.ipv6_addr.addr_flags & NCDIFMONITOR_ADDR_FLAG_DYNAMIC);
             

+ 44 - 18
misc/ipaddr6.h

@@ -34,11 +34,9 @@
 #ifndef BADVPN_MISC_IPADDR6_H
 #define BADVPN_MISC_IPADDR6_H
 
-#include <stdint.h>
 #include <string.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
+#include <stdio.h>
+#include <inttypes.h>
 
 #include <misc/debug.h>
 
@@ -54,26 +52,54 @@ struct ipv6_ifaddr {
     int scope;
 };
 
-#define IPADDR6_PRINT_MAX INET6_ADDRSTRLEN
+#define IPADDR6_PRINT_MAX 46
 
-static int ipaddr6_print_addr (const uint8_t *addr, char *out_buf) WARN_UNUSED;
+static void ipaddr6_print_addr (const uint8_t *addr, char *out_buf);
 
-
-int ipaddr6_print_addr (const uint8_t *addr, char *out_buf)
+void ipaddr6_print_addr (const uint8_t *addr, char *out_buf)
 {
-    struct sockaddr_in6 a;
-    memset(&a, 0, sizeof(a));
-    a.sin6_family = AF_INET6;
-    a.sin6_port = 0;
-    a.sin6_flowinfo= 0;
-    memcpy(a.sin6_addr.s6_addr, addr, 16);
-    a.sin6_scope_id = 0;
+    int largest_start = 0;
+    int largest_len = 0;
+    int current_start = 0;
+    int current_len = 0;
     
-    if (getnameinfo((struct sockaddr *)&a, sizeof(a), out_buf, IPADDR6_PRINT_MAX, NULL, 0, NI_NUMERICHOST) < 0) {
-        return 0;
+    for (int i = 0; i < 8; i++) {
+        if (addr[2 * i] == 0 && addr[2 * i + 1] == 0) {
+            current_len++;
+            if (current_len > largest_len) {
+                largest_start = current_start;
+                largest_len = current_len;
+            }
+        } else {
+            current_start = i + 1;
+            current_len = 0;
+        }
     }
     
-    return 1;
+    if (largest_len > 1) {
+        for (int i = 0; i < largest_start; i++) {
+            uint16_t block = ((uint16_t)addr[2 * i] << 8) | addr[2 * i + 1];
+            out_buf += sprintf(out_buf, "%"PRIx16":", block);
+        }
+        if (largest_start == 0) {
+            out_buf += sprintf(out_buf, ":");
+        }
+        
+        for (int i = largest_start + largest_len; i < 8; i++) {
+            uint16_t block = ((uint16_t)addr[2 * i] << 8) | addr[2 * i + 1];
+            out_buf += sprintf(out_buf, ":%"PRIx16, block);
+        }
+        if (largest_start + largest_len == 8) {
+            out_buf += sprintf(out_buf, ":");
+        }
+    } else {
+        const char *prefix = "";
+        for (int i = 0; i < 8; i++) {
+            uint16_t block = ((uint16_t)addr[2 * i] << 8) | addr[2 * i + 1];
+            out_buf += sprintf(out_buf, "%s%"PRIx16, prefix, block);
+            prefix = ":";
+        }
+    }
 }
 
 #endif

+ 1 - 0
ncd/NCDInterfaceMonitor.c

@@ -33,6 +33,7 @@
 
 #include <sys/socket.h>
 #include <net/if.h>
+#include <netinet/in.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <asm/types.h>

+ 1 - 4
ncd/modules/net_ipv6_wait_dynamic_addr.c

@@ -165,10 +165,7 @@ static int func_getvar (void *vo, const char *name, NCDValMem *mem, NCDValRef *o
     
     if (!strcmp(name, "addr")) {
         char str[IPADDR6_PRINT_MAX];
-        if (!ipaddr6_print_addr(o->ifaddr.addr, str)) {
-            ModuleLog(o->i, BLOG_ERROR, "ipaddr6_print_addr failed");
-            return 0;
-        }
+        ipaddr6_print_addr(o->ifaddr.addr, str);
         *out = NCDVal_NewString(mem, str);
         if (NCDVal_IsInvalid(*out)) {
             ModuleLog(o->i, BLOG_ERROR, "NCDVal_NewString failed");