/* -*-c-*-
*
- * Discover the owner of a connection
+ * Discover the owner of a connection (Linux version)
*
* (c) 2012 Straylight/Edgeware
*/
/*----- 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;
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];
void identify(struct query *q)
{
- const struct addrfamily *af;
FILE *fp = 0;
dstr d = DSTR_INIT;
char *p, *pp;
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;
}
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;
}
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;
}
}
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;
}
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)
{
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);
}
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];