linux.c: Do NAT detection using address-independent machinery.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 20 Oct 2012 14:28:55 +0000 (15:28 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 21 Oct 2012 15:08:58 +0000 (16:08 +0100)
linux.c

diff --git a/linux.c b/linux.c
index b0db5f1..87da9fa 100644 (file)
--- a/linux.c
+++ b/linux.c
@@ -36,15 +36,18 @@ static FILE *natfp;
 
 struct addrops_sys {
   const char *procfile;
+  const char *nfl3name;
   int (*parseaddr)(char **, union addr *);
 };
 
 #define PROCFILE_IPV4 "/proc/net/tcp"
+#define NFL3NAME_IPV4 "ipv4"
 
 static int parseaddr_ipv4(char **pp, union addr *a)
   { a->ipv4.s_addr = strtoul(*pp, pp, 16); return (0); }
 
 #define PROCFILE_IPV6 "/proc/net/tcp6"
+#define NFL3NAME_IPV6 "ipv6"
 
 static int parseaddr_ipv6(char **pp, union addr *a)
 {
@@ -71,7 +74,7 @@ static int parseaddr_ipv6(char **pp, union addr *a)
 
 #define DEFOPSYS(ty, TY)                                               \
   const struct addrops_sys addrops_sys_##ty = {                                \
-    PROCFILE_##TY, parseaddr_##ty                                      \
+    PROCFILE_##TY, NFL3NAME_##TY, parseaddr_##ty                       \
   };
 ADDRTYPES(DEFOPSYS)
 #undef DEFOPSYS
@@ -247,13 +250,17 @@ void identify(struct query *q)
     goto err_unk;
   }
 
-  if (natfp && q->ao->af == AF_INET) {
+  if (natfp) {
     rewind(natfp);
 
     for (;;) {
       DRESET(&d);
       if (dstr_putline(&d, natfp) == EOF) break;
       pp = d.buf;
+
+      NEXTFIELD; if (!*p) break;
+      if (strcmp(p, q->ao->sys->nfl3name)) continue;
+      NEXTFIELD; if (!*p) break;
       NEXTFIELD; if (!*p) break;
       if (strcmp(p, "tcp") != 0) continue;
       i = 0;
@@ -263,10 +270,10 @@ void identify(struct query *q)
        if (strcmp(p, "ESTABLISHED") == 0)
          fl |= F_ESTAB;
        else if (strncmp(p, "src=", 4) == 0) {
-         inet_pton(AF_INET, p + 4, &s[i].addr);
+         inet_pton(q->ao->af, p + 4, &s[i].addr);
          fl |= F_SADDR;
        } else if (strncmp(p, "dst=", 4) == 0) {
-         inet_pton(AF_INET, p + 4, &s[i + 1].addr);
+         inet_pton(q->ao->af, p + 4, &s[i + 1].addr);
          fl |= F_DADDR;
        } else if (strncmp(p, "sport=", 6) == 0) {
          s[i].port = atoi(p + 6);
@@ -313,8 +320,9 @@ void identify(struct query *q)
       goto done;
     }
 
+    /* Reached the end of the NAT file. */
     if (ferror(natfp)) {
-      logmsg(q, LOG_ERR, "failed to read `/proc/net/ip_conntrack': %s",
+      logmsg(q, LOG_ERR, "failed to read `/proc/net/nf_conntrack': %s",
             strerror(errno));
       goto err_unk;
     }
@@ -336,9 +344,9 @@ done:
 
 void init_sys(void)
 {
-  if ((natfp = fopen("/proc/net/ip_conntrack", "r")) == 0 &&
+  if ((natfp = fopen("/proc/net/nf_conntrack", "r")) == 0 &&
       errno != ENOENT) {
-    die(1, "failed to open `/proc/net/ip_conntrack' for reading: %s",
+    die(1, "failed to open `/proc/net/nf_conntrack' for reading: %s",
        strerror(errno));
   }
 }