diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2007-03-04 20:05:12 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2007-03-04 20:05:12 +0000 |
commit | df71ee7c5de462c2ee97ffa6a1acacb2ed7db20f (patch) | |
tree | e5228ba3e6dcaaeed1b73e5136be7791a785ad6d /usr.sbin/bgpctl | |
parent | b92139fa0b17068e588e0c97165b00e004cdce29 (diff) |
store prefixes in binary format. we'll need that for aggregation.
discussed with pyr
Diffstat (limited to 'usr.sbin/bgpctl')
-rw-r--r-- | usr.sbin/bgpctl/irr_output.c | 38 | ||||
-rw-r--r-- | usr.sbin/bgpctl/irr_prefix.c | 59 | ||||
-rw-r--r-- | usr.sbin/bgpctl/irrfilter.h | 13 |
3 files changed, 86 insertions, 24 deletions
diff --git a/usr.sbin/bgpctl/irr_output.c b/usr.sbin/bgpctl/irr_output.c index 558c0170373..4c94f48a43a 100644 --- a/usr.sbin/bgpctl/irr_output.c +++ b/usr.sbin/bgpctl/irr_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: irr_output.c,v 1.7 2007/03/04 18:40:08 henning Exp $ */ +/* $OpenBSD: irr_output.c,v 1.8 2007/03/04 20:05:11 henning Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> +#include <sys/socket.h> #include <err.h> #include <stdio.h> #include <stdlib.h> @@ -26,6 +27,9 @@ #include <unistd.h> #include <fcntl.h> #include <ctype.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include "irrfilter.h" @@ -33,7 +37,7 @@ int process_policies(FILE *, struct policy_head *); void policy_prettyprint(FILE *, struct policy_item *); void policy_torule(FILE *, struct policy_item *); char *action_torule(char *); -void print_rule(FILE *, struct policy_item *, char *, char *); +void print_rule(FILE *, struct policy_item *, char *, struct prefix *); #define allowed_in_address(x) \ (isalnum(x) || x == '.' || x == ':' || x == '-') @@ -190,14 +194,16 @@ action_torule(char *s) } void -print_rule(FILE *fh, struct policy_item *pi, char *sourceas, char *prefix) +print_rule(FILE *fh, struct policy_item *pi, char *sourceas, + struct prefix *prefix) { - char *fmt = "allow quick %s %s%s%s%s%s%s\n"; - char *peer = "any"; - char *action = ""; - char *dir; - char *pfx[2] = { "", "" }; - char *srcas[2] = { "", "" }; + char *fmt = "allow quick %s %s%s%s%s%s\n"; + char *peer = "any"; + char *action = ""; + char *dir; + char *srcas[2] = { "", "" }; + char pbuf[8 + NI_MAXHOST + 4]; + size_t offset; if (pi->dir == IMPORT) dir = "from"; @@ -211,13 +217,21 @@ print_rule(FILE *fh, struct policy_item *pi, char *sourceas, char *prefix) action = action_torule(pi->action); if (prefix != NULL) { - pfx[0] = " prefix "; - pfx[1] = prefix; + strlcpy(pbuf, " prefix ", sizeof(pbuf)); + offset = strlen(pbuf); + if (inet_ntop(prefix->af, &prefix->addr, pbuf + offset, + sizeof(pbuf) - offset) == NULL) + err(1, "print_rule inet_ntop"); + offset = strlen(pbuf); + if (snprintf(pbuf + offset, sizeof(pbuf) - offset, + "/%u", prefix->len) == -1) + err(1, "print_rule snprintf"); + if (pi->dir == IMPORT) { srcas[0] = " source-as "; srcas[1] = sourceas; } } - fprintf(fh, fmt, dir, peer, srcas[0], srcas[1], pfx[0], pfx[1], action); + fprintf(fh, fmt, dir, peer, srcas[0], srcas[1], pbuf, action); } diff --git a/usr.sbin/bgpctl/irr_prefix.c b/usr.sbin/bgpctl/irr_prefix.c index d694ae09cf7..8bb0bc45fd5 100644 --- a/usr.sbin/bgpctl/irr_prefix.c +++ b/usr.sbin/bgpctl/irr_prefix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: irr_prefix.c,v 1.1 2007/03/03 11:45:30 henning Exp $ */ +/* $OpenBSD: irr_prefix.c,v 1.2 2007/03/04 20:05:11 henning Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -18,14 +18,18 @@ #include <sys/types.h> #include <sys/param.h> +#include <sys/socket.h> #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include "irrfilter.h" +int prefix_compare(void *, void *); int prefix_set_compare(struct prefix_set *, struct prefix_set *); struct prefix_set *prefix_set_find(char *); @@ -63,27 +67,62 @@ prefixset_get(char *as) int prefixset_addmember(char *s) { - void *p; - u_int i; + void *p; + u_int i; + struct prefix *pfx; + int len; + + if (strchr(s, '/') == NULL) + errx(1, "prefix %s does not have the len specified", s); + + if ((pfx = calloc(1, sizeof(*pfx))) == NULL) + err(1, "prefixset_addmember calloc"); + + if ((len = inet_net_pton(AF_INET, s, &pfx->addr.in, + sizeof(pfx->addr.in))) == -1) + err(1, "inet_net_pton %s", s); + + pfx->af = AF_INET; + pfx->len = len; /* yes, there are dupes... e. g. from multiple sources */ for (i = 0; i < curpfxs->prefixcnt; i++) - if (!strcmp(curpfxs->prefix[i], s)) + if (prefix_compare(curpfxs->prefix[i], pfx) == 0) { + free(pfx); return (0); + } if ((p = realloc(curpfxs->prefix, - (curpfxs->prefixcnt + 1) * sizeof(char *))) == NULL) - err(1, "prefixset_addmember strdup"); + (curpfxs->prefixcnt + 1) * sizeof(void *))) == NULL) + err(1, "prefixset_addmember realloc"); curpfxs->prefix = p; curpfxs->prefixcnt++; - - if ((curpfxs->prefix[curpfxs->prefixcnt - 1] = - strdup(s)) == NULL) - err(1, "prefixset_addmember strdup"); + curpfxs->prefix[curpfxs->prefixcnt - 1] = pfx; return (1); } +int +prefix_compare(void *a, void *b) +{ + struct prefix *pa = a; + struct prefix *pb = b; + int r; + + if ((r = pa->af - pb->af) != 0) + return (r); + if (pa->af == AF_INET) { + if ((r = ntohl(pa->addr.in.s_addr) - + ntohl(pb->addr.in.s_addr)) != 0) + return (r); + } else + errx(1, "prefixcmp unknown af %u", pa->af); + + if ((r = pa->len - pb->len) != 0) + return (r); + + return (0); +} /* RB helpers */ int diff --git a/usr.sbin/bgpctl/irrfilter.h b/usr.sbin/bgpctl/irrfilter.h index ca15a25d6d5..efc509383de 100644 --- a/usr.sbin/bgpctl/irrfilter.h +++ b/usr.sbin/bgpctl/irrfilter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: irrfilter.h,v 1.2 2007/03/04 18:13:13 henning Exp $ */ +/* $OpenBSD: irrfilter.h,v 1.3 2007/03/04 20:05:11 henning Exp $ */ /* * Copyright (c) 2007 Henning Brauer <henning@openbsd.org> @@ -18,6 +18,7 @@ #include <sys/queue.h> #include <sys/tree.h> +#include <netinet/in.h> #define F_IMPORTONLY 0x01 /* skip export: items */ @@ -67,10 +68,18 @@ struct as_set { u_int n_as; }; +struct prefix { + union { + struct in_addr in; + } addr; + sa_family_t af; + u_int8_t len; +}; + struct prefix_set { RB_ENTRY(prefix_set) entry; char *as; - char **prefix; + struct prefix **prefix; u_int prefixcnt; }; |