X-Git-Url: https://git.distorted.org.uk/~mdw/yaid/blobdiff_plain/38b211f2a0e292153413e6edb543308f1443d0de..bf4d97617c92530ab67923aaba802333ee258352:/linux.c diff --git a/linux.c b/linux.c index 91c03aa..252b69c 100644 --- a/linux.c +++ b/linux.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * Discover the owner of a connection + * Discover the owner of a connection (Linux version) * * (c) 2012 Straylight/Edgeware */ @@ -30,19 +30,19 @@ /*----- Static variables --------------------------------------------------*/ -const char *const errtok[] = { -#define DEFTOK(err, tok) tok, - ERROR(DEFTOK) -#undef DEFTOK +struct addrops_sys { + const char *procfile; + int (*parseaddr)(char **, union addr *); }; -static int parseaddr4(char **pp, union addr *a) +static int parseaddr_ipv4(char **pp, union addr *a) { a->ipv4.s_addr = strtoul(*pp, pp, 16); return (0); } -static int addreq4(const union addr *a, const union addr *aa) - { return a->ipv4.s_addr == aa->ipv4.s_addr; } +const struct addrops_sys addrops_sys_ipv4 = { + "/proc/net/tcp", parseaddr_ipv4 +}; -static int parseaddr6(char **pp, union addr *a) +static int parseaddr_ipv6(char **pp, union addr *a) { int i, j; unsigned long y; @@ -65,27 +65,13 @@ static int parseaddr6(char **pp, union addr *a) return (0); } -static int addreq6(const union addr *a, const union addr *b) - { return !memcmp(a->ipv6.s6_addr, b->ipv6.s6_addr, 16); } - -static const struct addrfamily { - int af; - const char *procfile; - int (*parseaddr)(char **pp, union addr *a); - int (*addreq)(const union addr *a, const union addr *aa); -} addrfamilytab[] = { - { AF_INET, "/proc/net/tcp", parseaddr4, addreq4 }, - { AF_INET6, "/proc/net/tcp6", parseaddr6, addreq6 }, - { -1 } +const struct addrops_sys addrops_sys_ipv6 = { + "/proc/net/tcp6", parseaddr_ipv6 }; /*----- Main code ---------------------------------------------------------*/ -static int sockeq(const struct addrfamily *af, - const struct socket *sa, const struct socket *sb) - { return (af->addreq(&sa->addr, &sb->addr) && sa->port == sb->port); } - -static int get_default_gw(int af, union addr *a) +int get_default_gw(int af, union addr *a) { int fd; char buf[32768]; @@ -152,7 +138,6 @@ done: void identify(struct query *q) { - const struct addrfamily *af; FILE *fp = 0; dstr d = DSTR_INIT; char *p, *pp; @@ -170,19 +155,13 @@ void identify(struct query *q) enum { LOC, REM, ST, UID, NFIELD }; int f, ff[NFIELD]; - for (af = addrfamilytab; af->af >= 0; af++) - if (af->af == q->af) goto found_af; - logmsg(q, LOG_ERR, "unexpected address family `%d'", q->af); - goto err_unk; -found_af:; - - if (get_default_gw(q->af, &s[0].addr) && - af->addreq(&s[0].addr, &q->s[R].addr)) + if (get_default_gw(q->ao->af, &s[0].addr) && + q->ao->addreq(&s[0].addr, &q->s[R].addr)) gwp = 1; - if ((fp = fopen(af->procfile, "r")) == 0) { + if ((fp = fopen(q->ao->sys->procfile, "r")) == 0) { logmsg(q, LOG_ERR, "failed to open `%s' for reading: %s", - af->procfile, strerror(errno)); + q->ao->sys->procfile, strerror(errno)); goto err_unk; } @@ -194,7 +173,8 @@ found_af:; if (dstr_putline(&d, fp) == EOF) { logmsg(q, LOG_ERR, "failed to read header line from `%s': %s", - af->procfile, ferror(fp) ? strerror(errno) : "unexpected EOF"); + q->ao->sys->procfile, + ferror(fp) ? strerror(errno) : "unexpected EOF"); goto err_unk; } @@ -218,7 +198,7 @@ found_af:; for (i = 0; i < NFIELD; i++) { if (ff[i] < 0) { logmsg(q, LOG_ERR, "failed to find required fields in `%s'", - af->procfile); + q->ao->sys->procfile); goto err_unk; } } @@ -239,10 +219,10 @@ found_af:; continue; compare: - if (af->parseaddr(&p, &s[0].addr)) goto next_row; + if (q->ao->sys->parseaddr(&p, &s[0].addr)) goto next_row; if (*p != ':') break; p++; s[0].port = strtoul(p, 0, 16); - if (!sockeq(af, &q->s[i], &s[0]) && + if (!sockeq(q->ao, &q->s[i], &s[0]) && (i != R || !gwp || q->s[R].port != s[0].port)) goto next_row; } @@ -260,7 +240,7 @@ found_af:; goto err_unk; } - if (q->af == AF_INET) { + if (q->ao->af == AF_INET) { fclose(fp); if ((fp = fopen("/proc/net/ip_conntrack", "r")) == 0) { if (errno == ENOENT) @@ -309,13 +289,13 @@ found_af:; { dstr dd = DSTR_INIT; dstr_putf(&dd, "%sestab ", (fl & F_ESTAB) ? " " : "!"); - dputsock(&dd, af->af, &s[0]); + dputsock(&dd, q->ao, &s[0]); dstr_puts(&dd, "<->"); - dputsock(&dd, af->af, &s[1]); + dputsock(&dd, q->ao, &s[1]); dstr_puts(&dd, " | "); - dputsock(&dd, af->af, &s[2]); + dputsock(&dd, q->ao, &s[2]); dstr_puts(&dd, "<->"); - dputsock(&dd, af->af, &s[3]); + dputsock(&dd, q->ao, &s[3]); printf("parsed: %s\n", dd.buf); dstr_destroy(&dd); } @@ -324,12 +304,12 @@ found_af:; if (!(fl & F_ESTAB)) continue; for (i = 0; i < 4; i++) - if (sockeq(af, &s[i], &q->s[L])) goto found_local; + if (sockeq(q->ao, &s[i], &q->s[L])) goto found_local; continue; putchar('.'); found_local: - if (!sockeq(af, &s[i^1], &s[i^2]) || - !sockeq(af, &s[i^1], &q->s[R])) + if (!sockeq(q->ao, &s[i^1], &s[i^2]) || + !sockeq(q->ao, &s[i^1], &q->s[R])) continue; q->resp = R_NAT; q->u.nat = s[i^3];