X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=netlink.c;h=5226ad1166af5517a3586d59523dc8422ae0dc75;hp=ecad16cb73e6d8cb18b724148912648a2482a219;hb=a15faeb2b12e9cc0e3d1352cf4c233fc61c51c1c;hpb=20d324b6d71fdfbbe28479848c934ca3a1f69f16;ds=sidebyside diff --git a/netlink.c b/netlink.c index ecad16c..5226ad1 100644 --- a/netlink.c +++ b/netlink.c @@ -98,6 +98,8 @@ their use. */ #include +#include +#include #include "secnet.h" #include "util.h" #include "ipaddr.h" @@ -121,7 +123,7 @@ their use. #define ICMP_CODE_TTL_EXCEEDED 0 /* Generic IP checksum routine */ -static inline uint16_t ip_csum(uint8_t *iph,uint32_t count) +static inline uint16_t ip_csum(uint8_t *iph,int32_t count) { register uint32_t sum=0; @@ -145,7 +147,7 @@ static inline uint16_t ip_csum(uint8_t *iph,uint32_t count) * By Jorge Cwik , adapted for linux by * Arnt Gulbrandsen. */ -static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl) { +static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl) { uint32_t sum; __asm__ __volatile__( @@ -175,8 +177,9 @@ static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl) { return sum; } #else -static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl) +static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl) { + assert(ihl < INT_MAX/4); return ip_csum(iph,ihl*4); } #endif @@ -262,7 +265,7 @@ static struct icmphdr *netlink_icmp_tmpl(struct netlink *st, /* Fill in the ICMP checksum field correctly */ static void netlink_icmp_csum(struct icmphdr *h) { - uint32_t len; + int32_t len; len=ntohs(h->iph.tot_len)-(4*h->iph.ihl); h->check=0; @@ -384,7 +387,7 @@ static void netlink_icmp_simple(struct netlink *st, struct buffer_if *buf, static bool_t netlink_check(struct netlink *st, struct buffer_if *buf) { struct iphdr *iph=(struct iphdr *)buf->start; - uint32_t len; + int32_t len; if (iph->ihl < 5 || iph->version != 4) return False; if (buf->size < iph->ihl*4) return False; @@ -498,18 +501,19 @@ static void netlink_packet_deliver(struct netlink *st, netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE, ICMP_CODE_NET_PROHIBITED); BUF_FREE(buf); - } - if (best_quality>0) { - /* XXX Fragment if required */ - st->routes[best_match]->deliver( - st->routes[best_match]->dst, buf); - st->routes[best_match]->outcount++; - BUF_ASSERT_FREE(buf); } else { - /* Generate ICMP destination unreachable */ - netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE, - ICMP_CODE_NET_UNREACHABLE); /* client==NULL */ - BUF_FREE(buf); + if (best_quality>0) { + /* XXX Fragment if required */ + st->routes[best_match]->deliver( + st->routes[best_match]->dst, buf); + st->routes[best_match]->outcount++; + BUF_ASSERT_FREE(buf); + } else { + /* Generate ICMP destination unreachable */ + netlink_icmp_simple(st,buf,client,ICMP_TYPE_UNREACHABLE, + ICMP_CODE_NET_UNREACHABLE); /* client==NULL */ + BUF_FREE(buf); + } } } BUF_ASSERT_FREE(buf); @@ -692,7 +696,7 @@ static void netlink_set_quality(void *sst, uint32_t quality) static void netlink_output_subnets(struct netlink *st, uint32_t loglevel, struct subnet_list *snets) { - uint32_t i; + int32_t i; string_t net; for (i=0; ientries; i++) { @@ -721,14 +725,15 @@ static void netlink_dump_routes(struct netlink *st, bool_t requested) for (i=0; in_clients; i++) { netlink_output_subnets(st,c,st->routes[i]->subnets); Message(c,"-> tunnel %s (%s,mtu %d,%s routes,%s," - "quality %d,use %d)\n", + "quality %d,use %d,pri %lu)\n", st->routes[i]->name, st->routes[i]->up?"up":"down", st->routes[i]->mtu, st->routes[i]->options&OPT_SOFTROUTE?"soft":"hard", st->routes[i]->options&OPT_ALLOWROUTE?"free":"restricted", st->routes[i]->link_quality, - st->routes[i]->outcount); + st->routes[i]->outcount, + (unsigned long)st->routes[i]->priority); } net=ipaddr_to_string(st->secnet_address); Message(c,"%s/32 -> netlink \"%s\" (use %d)\n", @@ -759,17 +764,19 @@ static void netlink_phase_hook(void *sst, uint32_t new_phase) { struct netlink *st=sst; struct netlink_client *c; - uint32_t i; + int32_t i; /* All the networks serviced by the various tunnels should now * have been registered. We build a routing table by sorting the * clients by priority. */ - st->routes=safe_malloc(st->n_clients*sizeof(*st->routes), - "netlink_phase_hook"); + st->routes=safe_malloc_ary(sizeof(*st->routes),st->n_clients, + "netlink_phase_hook"); /* Fill the table */ i=0; - for (c=st->clients; c; c=c->next) + for (c=st->clients; c; c=c->next) { + assert(iroutes[i++]=c; + } /* Sort the table in descending order of priority */ qsort(st->routes,st->n_clients,sizeof(*st->routes), netlink_compare_client_priority); @@ -805,7 +812,7 @@ static bool_t netlink_inst_check_config(void *sst, struct buffer_if *buf) return True; } -static void netlink_inst_set_mtu(void *sst, uint32_t new_mtu) +static void netlink_inst_set_mtu(void *sst, int32_t new_mtu) { struct netlink_client *c=sst; @@ -813,8 +820,8 @@ static void netlink_inst_set_mtu(void *sst, uint32_t new_mtu) } static void netlink_inst_reg(void *sst, netlink_deliver_fn *deliver, - void *dst, uint32_t max_start_pad, - uint32_t max_end_pad) + void *dst, int32_t max_start_pad, + int32_t max_end_pad) { struct netlink_client *c=sst; struct netlink *st=c->nst; @@ -841,7 +848,8 @@ static closure_t *netlink_inst_create(struct netlink *st, struct netlink_client *c; string_t name; struct ipset *networks; - uint32_t options,priority,mtu; + uint32_t options,priority; + int32_t mtu; list_t *l; name=dict_read_string(dict, "name", True, st->name, loc); @@ -909,6 +917,7 @@ static closure_t *netlink_inst_create(struct netlink *st, c->kup=False; c->next=st->clients; st->clients=c; + assert(st->n_clients < INT_MAX); st->n_clients++; return &c->cl; @@ -1065,7 +1074,6 @@ static list_t *null_apply(closure_t *self, struct cloc loc, dict_t *context, return new_closure(&st->nl.cl); } -init_module netlink_module; void netlink_module(dict_t *dict) { add_closure(dict,"null-netlink",null_apply);