yaid.c: Beef up `reply' with an extra token argument.
[yaid] / linux.c
diff --git a/linux.c b/linux.c
index 252b69c..4954cf9 100644 (file)
--- a/linux.c
+++ b/linux.c
 
 /*----- Static variables --------------------------------------------------*/
 
+static FILE *natfp;
+
+/*----- Address-type operations -------------------------------------------*/
+
 struct addrops_sys {
   const char *procfile;
   int (*parseaddr)(char **, union addr *);
 };
 
+#define PROCFILE_IPV4 "/proc/net/tcp"
+
 static int parseaddr_ipv4(char **pp, union addr *a)
   { a->ipv4.s_addr = strtoul(*pp, pp, 16); return (0); }
 
-const struct addrops_sys addrops_sys_ipv4 = {
-  "/proc/net/tcp", parseaddr_ipv4
-};
+#define PROCFILE_IPV6 "/proc/net/tcp6"
 
 static int parseaddr_ipv6(char **pp, union addr *a)
 {
@@ -65,9 +69,12 @@ static int parseaddr_ipv6(char **pp, union addr *a)
   return (0);
 }
 
-const struct addrops_sys addrops_sys_ipv6 = {
-  "/proc/net/tcp6", parseaddr_ipv6
-};
+#define DEFOPSYS(ty, TY)                                               \
+  const struct addrops_sys addrops_sys_##ty = {                                \
+    PROCFILE_##TY, parseaddr_##ty                                      \
+  };
+ADDRTYPES(DEFOPSYS)
+#undef DEFOPSYS
 
 /*----- Main code ---------------------------------------------------------*/
 
@@ -235,27 +242,17 @@ void identify(struct query *q)
   }
 
   if (ferror(fp)) {
-    logmsg(q, LOG_ERR, "failed to read connection table: %s",
-          strerror(errno));
+    logmsg(q, LOG_ERR, "failed to read connection table `%s': %s",
+          q->ao->sys->procfile, strerror(errno));
     goto err_unk;
   }
 
-  if (q->ao->af == AF_INET) {
-    fclose(fp);
-    if ((fp = fopen("/proc/net/ip_conntrack", "r")) == 0) {
-      if (errno == ENOENT)
-       goto err_nouser;
-      else {
-       logmsg(q, LOG_ERR,
-              "failed to open `/proc/net/ip_conntrack' for reading: %s",
-              strerror(errno));
-       goto err_unk;
-      }
-    }
+  if (natfp && q->ao->af == AF_INET) {
+    rewind(natfp);
 
     for (;;) {
       DRESET(&d);
-      if (dstr_putline(&d, fp) == EOF) break;
+      if (dstr_putline(&d, natfp) == EOF) break;
       pp = d.buf;
       NEXTFIELD; if (!*p) break;
       if (strcmp(p, "tcp") != 0) continue;
@@ -316,17 +313,16 @@ void identify(struct query *q)
       goto done;
     }
 
-    if (ferror(fp)) {
+    if (ferror(natfp)) {
       logmsg(q, LOG_ERR, "failed to read `/proc/net/ip_conntrack': %s",
             strerror(errno));
       goto err_unk;
     }
-    logmsg(q, LOG_ERR, "connection not found");
   }
 
 #undef NEXTFIELD
 
-err_nouser:
+  logmsg(q, LOG_NOTICE, "connection not found");
   q->resp = R_ERROR;
   q->u.error = E_NOUSER;
   goto done;
@@ -335,6 +331,16 @@ err_unk:
   q->u.error = E_UNKNOWN;
 done:
   dstr_destroy(&d);
+  if (fp) fclose(fp);
+}
+
+void init_sys(void)
+{
+  if ((natfp = fopen("/proc/net/ip_conntrack", "r")) == 0 &&
+      errno != ENOENT) {
+    die(1, "failed to open `/proc/net/ip_conntrack' for reading: %s",
+       strerror(errno));
+  }
 }
 
 /*----- That's all, folks -------------------------------------------------*/