X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=netlink.c;h=af6434feb9002c12a938a2d2923d2f92ea8b9c53;hp=4151e33688dbb91033dc9c90903c3e7202c83cec;hb=975820aa67cb8f5f89eb968ec5397305e3b77bcf;hpb=d714da29de327460f40d996e9cf69b71ccdcaa31 diff --git a/netlink.c b/netlink.c index 4151e33..af6434f 100644 --- a/netlink.c +++ b/netlink.c @@ -106,9 +106,6 @@ their use. #include "netlink.h" #include "process.h" -#define OPT_SOFTROUTE 1 -#define OPT_ALLOWROUTE 2 - #define ICMP_TYPE_ECHO_REPLY 0 #define ICMP_TYPE_UNREACHABLE 3 @@ -241,7 +238,7 @@ static struct icmphdr *netlink_icmp_tmpl(struct netlink *st, struct icmphdr *h; BUF_ALLOC(&st->icmp,"netlink_icmp_tmpl"); - buffer_init(&st->icmp,st->max_start_pad); + buffer_init(&st->icmp,calculate_max_start_pad()); h=buf_append(&st->icmp,sizeof(*h)); h->iph.version=4; @@ -296,6 +293,7 @@ static bool_t netlink_icmp_may_reply(struct buffer_if *buf) struct icmphdr *icmph; uint32_t source; + if (buf->size < (int)sizeof(struct icmphdr)) return False; iph=(struct iphdr *)buf->start; icmph=(struct icmphdr *)buf->start; if (iph->protocol==1) { @@ -341,6 +339,7 @@ static bool_t netlink_icmp_may_reply(struct buffer_if *buf) */ static uint16_t netlink_icmp_reply_len(struct buffer_if *buf) { + if (buf->size < (int)sizeof(struct iphdr)) return 0; struct iphdr *iph=(struct iphdr *)buf->start; uint16_t hlen,plen; @@ -357,11 +356,11 @@ static void netlink_icmp_simple(struct netlink *st, struct buffer_if *buf, struct netlink_client *client, uint8_t type, uint8_t code) { - struct iphdr *iph=(struct iphdr *)buf->start; struct icmphdr *h; uint16_t len; if (netlink_icmp_may_reply(buf)) { + struct iphdr *iph=(struct iphdr *)buf->start; len=netlink_icmp_reply_len(buf); h=netlink_icmp_tmpl(st,ntohl(iph->saddr),len); h->type=type; h->code=code; @@ -392,6 +391,7 @@ static bool_t netlink_check(struct netlink *st, struct buffer_if *buf, return False; \ }while(0) + if (buf->size < (int)sizeof(struct iphdr)) BAD("len %"PRIu32"",buf->size); struct iphdr *iph=(struct iphdr *)buf->start; int32_t len; @@ -416,6 +416,13 @@ static void netlink_packet_deliver(struct netlink *st, struct netlink_client *client, struct buffer_if *buf) { + if (buf->size < (int)sizeof(struct iphdr)) { + Message(M_ERR,"%s: trying to deliver a too-short packet" + " from %s!\n",st->name, client?client->name:"(local)"); + BUF_FREE(buf); + return; + } + struct iphdr *iph=(struct iphdr *)buf->start; uint32_t dest=ntohl(iph->daddr); uint32_t source=ntohl(iph->saddr); @@ -533,6 +540,7 @@ static void netlink_packet_forward(struct netlink *st, struct netlink_client *client, struct buffer_if *buf) { + if (buf->size < (int)sizeof(struct iphdr)) return; struct iphdr *iph=(struct iphdr *)buf->start; BUF_ASSERT_USED(buf); @@ -562,6 +570,12 @@ static void netlink_packet_local(struct netlink *st, st->localcount++; + if (buf->size < (int)sizeof(struct icmphdr)) { + Message(M_WARNING,"%s: short packet addressed to secnet; " + "ignoring it\n",st->name); + BUF_FREE(buf); + return; + } h=(struct icmphdr *)buf->start; if ((ntohs(h->iph.frag_off)&0xbfff)!=0) { @@ -606,15 +620,18 @@ static void netlink_incoming(struct netlink *st, struct netlink_client *client, uint32_t source,dest; struct iphdr *iph; char errmsgbuf[50]; + const char *sourcedesc=client?client->name:"host"; BUF_ASSERT_USED(buf); + if (!netlink_check(st,buf,errmsgbuf,sizeof(errmsgbuf))) { Message(M_WARNING,"%s: bad IP packet from %s: %s\n", - st->name,client?client->name:"host", + st->name,sourcedesc, errmsgbuf); BUF_FREE(buf); return; } + assert(buf->size >= (int)sizeof(struct icmphdr)); iph=(struct iphdr *)buf->start; source=ntohl(iph->saddr); @@ -803,27 +820,6 @@ static void netlink_signal_handler(void *sst, int signum) netlink_dump_routes(st,True); } -static void netlink_inst_output_config(void *sst, struct buffer_if *buf) -{ -/* struct netlink_client *c=sst; */ -/* struct netlink *st=c->nst; */ - - /* For now we don't output anything */ - BUF_ASSERT_USED(buf); -} - -static bool_t netlink_inst_check_config(void *sst, struct buffer_if *buf) -{ -/* struct netlink_client *c=sst; */ -/* struct netlink *st=c->nst; */ - - BUF_ASSERT_USED(buf); - /* We need to eat all of the configuration information from the buffer - for backward compatibility. */ - buf->size=0; - return True; -} - static void netlink_inst_set_mtu(void *sst, int32_t new_mtu) { struct netlink_client *c=sst; @@ -832,14 +828,10 @@ static void netlink_inst_set_mtu(void *sst, int32_t new_mtu) } static void netlink_inst_reg(void *sst, netlink_deliver_fn *deliver, - void *dst, int32_t max_start_pad, - int32_t max_end_pad) + void *dst) { struct netlink_client *c=sst; - struct netlink *st=c->nst; - if (max_start_pad > st->max_start_pad) st->max_start_pad=max_start_pad; - if (max_end_pad > st->max_end_pad) st->max_end_pad=max_end_pad; c->deliver=deliver; c->dst=dst; } @@ -910,8 +902,6 @@ static closure_t *netlink_inst_create(struct netlink *st, c->ops.reg=netlink_inst_reg; c->ops.deliver=netlink_inst_incoming; c->ops.set_quality=netlink_set_quality; - c->ops.output_config=netlink_inst_output_config; - c->ops.check_config=netlink_inst_check_config; c->ops.set_mtu=netlink_inst_set_mtu; c->nst=st; @@ -969,8 +959,6 @@ netlink_deliver_fn *netlink_init(struct netlink *st, st->cl.type=CL_PURE; st->cl.apply=netlink_inst_apply; st->cl.interface=st; - st->max_start_pad=0; - st->max_end_pad=0; st->clients=NULL; st->routes=NULL; st->n_clients=0;