X-Git-Url: https://git.distorted.org.uk/~mdw/yaid/blobdiff_plain/38b211f2a0e292153413e6edb543308f1443d0de..bf4d97617c92530ab67923aaba802333ee258352:/policy.c diff --git a/policy.c b/policy.c index 398cd23..80e2bfd 100644 --- a/policy.c +++ b/policy.c @@ -28,10 +28,6 @@ #include "yaid.h" -/*----- Data structures ---------------------------------------------------*/ - -/*----- Static variables --------------------------------------------------*/ - /*----- Main code ---------------------------------------------------------*/ /* syntax: addrpat portpat addrpar portpat policy @@ -57,12 +53,17 @@ static void free_action(struct action *a) 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) @@ -72,8 +73,8 @@ 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, @@ -101,50 +102,26 @@ static void print_action(const struct action *act) 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) @@ -255,12 +232,12 @@ static int parse_action(FILE *fp, struct action *act) 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; @@ -268,21 +245,18 @@ static int parse_sockpat(FILE *fp, int *afp, struct sockpat *sp) 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; } @@ -311,11 +285,11 @@ int parse_policy(FILE *fp, struct policy *p) { 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);