/*----- 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)
{
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 ---------------------------------------------------------*/
}
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;
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;
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 -------------------------------------------------*/