#include "yaid.h"
-/*----- Data structures ---------------------------------------------------*/
-
-/*----- Static variables --------------------------------------------------*/
-
/*----- Main code ---------------------------------------------------------*/
/* syntax: addrpat portpat addrpar portpat policy
void free_policy(struct policy *p)
{ free_action(&p->act); }
-static void print_addrpat(int af, const struct addrpat *ap)
+static void print_addrpat(const struct addrops *ao, const struct addrpat *ap)
{
char buf[ADDRLEN];
- if (ap->len == 0) putchar('*');
- else printf("%s/%u", inet_ntop(af, &ap->addr, buf, sizeof(buf)), ap->len);
+ if (ap->len == 0)
+ putchar('*');
+ else {
+ printf("%s/%u",
+ inet_ntop(ao->af, &ap->addr, buf, sizeof(buf)),
+ ap->len);
+ }
}
static void print_portpat(const struct portpat *pp)
else printf("%u-%u", pp->lo, pp->hi);
}
-static void print_sockpat(int af, const struct sockpat *sp)
- { print_addrpat(af, &sp->addr); putchar(' '); print_portpat(&sp->port); }
+static void print_sockpat(const struct addrops *ao, const struct sockpat *sp)
+ { print_addrpat(ao, &sp->addr); putchar(' '); print_portpat(&sp->port); }
static const char *const acttab[] = {
#define DEFACT(tag, name) name,
void print_policy(const struct policy *p)
{
- print_sockpat(p->af, &p->sp[L]); putchar(' ');
- print_sockpat(p->af, &p->sp[R]); putchar(' ');
+ print_sockpat(p->ao, &p->sp[L]); putchar(' ');
+ print_sockpat(p->ao, &p->sp[R]); putchar(' ');
print_action(&p->act); putchar('\n');
}
-static int match_addrpat(int af, const struct addrpat *ap,
- const union addr *a)
-{
- if (!ap->len)
- return (1);
- switch (af) {
- case AF_INET: {
- unsigned mask = htonl((MASK32 << (32 - ap->len)) & MASK32);
- return (((ap->addr.ipv4.s_addr ^ a->ipv4.s_addr) & mask) == 0);
- }
- case AF_INET6: {
- unsigned i, m, n = ap->len;
- for (i = 0; n >= 8; i++, n -= 8) {
- if (ap->addr.ipv6.s6_addr[i] != a->ipv6.s6_addr[i])
- return (0);
- }
- if (!n) return (1);
- m = (MASK8 << (8 - n)) & MASK8;
- return (((ap->addr.ipv6.s6_addr[i] ^ a->ipv6.s6_addr[i]) & m) == 0);
- }
- }
- return (0);
-}
-
static int match_portpat(const struct portpat *pp, unsigned port)
{ return (pp->lo <= port && port <= pp->hi); }
-static int match_sockpat(int af, const struct sockpat *sp,
- const struct socket *s)
+static int match_sockpat(const struct addrops *ao,
+ const struct sockpat *sp, const struct socket *s)
{
- return (match_addrpat(af, &sp->addr, &s->addr) &&
+ return (ao->match_addrpat(&sp->addr, &s->addr) &&
match_portpat(&sp->port, s->port));
}
int match_policy(const struct policy *p, const struct query *q)
{
- return ((!p->af || p->af == q->af) &&
- match_sockpat(p->af, &p->sp[L], &q->s[L]) &&
- match_sockpat(p->af, &p->sp[R], &q->s[R]));
+ return ((!p->ao || p->ao == q->ao) &&
+ match_sockpat(q->ao, &p->sp[L], &q->s[L]) &&
+ match_sockpat(q->ao, &p->sp[R], &q->s[R]));
}
static void nextline(FILE *fp)
return (0);
}
-static int parse_sockpat(FILE *fp, int *afp, struct sockpat *sp)
+static int parse_sockpat(FILE *fp, const struct addrops **aop,
+ struct sockpat *sp)
{
char buf[64];
int t;
- int af;
- int alen;
+ const struct addrops *ao;
long n;
char *delim;
if (strcmp(buf, "*") == 0)
sp->addr.len = 0;
else {
- if (strchr(buf, ':')) {
- af = AF_INET6;
- alen = 128;
- } else {
- af = AF_INET;
- alen = 32;
- }
- if (!*afp) *afp = af;
- else if (*afp != af) return (T_ERROR);
+ if (strchr(buf, ':'))
+ ao = &addroptab[ADDR_IPV6];
+ else
+ ao = &addroptab[ADDR_IPV4];
+ if (!*aop) *aop = ao;
+ else if (*aop != ao) return (T_ERROR);
delim = strchr(buf, '/');
if (delim) *delim++ = 0;
- if (!inet_pton(af, buf, &sp->addr.addr)) return (T_ERROR);
- if (!delim) n = alen;
+ if (!inet_pton(ao->af, buf, &sp->addr.addr)) return (T_ERROR);
+ if (!delim) n = ao->len;
else n = strtol(delim, 0, 10);
- if (n < 0 || n > alen) return (T_ERROR);
+ if (n < 0 || n > ao->len) return (T_ERROR);
sp->addr.len = n;
}
{
int t;
- p->af = 0;
+ p->ao = 0;
free_policy(p);
- if ((t = parse_sockpat(fp, &p->af, &p->sp[L])) != 0) goto fail;
- if ((t = parse_sockpat(fp, &p->af, &p->sp[R])) != 0) goto err;
+ if ((t = parse_sockpat(fp, &p->ao, &p->sp[L])) != 0) goto fail;
+ if ((t = parse_sockpat(fp, &p->ao, &p->sp[R])) != 0) goto err;
if ((t = parse_action(fp, &p->act)) != 0) goto err;
return (0);