chiark / gitweb /
changelog: describe version 0.3.0
[secnet.git] / netlink.c
index 70eb9283b080104e37131d65170cdd7581988988..486df6fd1515f24ce4204fb3229a4ec22ac8f925 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -123,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;
 
@@ -147,7 +147,7 @@ static inline uint16_t ip_csum(uint8_t *iph,uint32_t count)
  *      By Jorge Cwik <jorge@laser.satlink.net>, 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__(
@@ -177,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
@@ -264,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;
@@ -383,19 +384,29 @@ static void netlink_icmp_simple(struct netlink *st, struct buffer_if *buf,
  * 3. Checksums correctly.
  * 4. Doesn't have a bogus length
  */
-static bool_t netlink_check(struct netlink *st, struct buffer_if *buf)
+static bool_t netlink_check(struct netlink *st, struct buffer_if *buf,
+                           char *errmsgbuf, int errmsgbuflen)
 {
+#define BAD(...) do{                                   \
+       snprintf(errmsgbuf,errmsgbuflen,__VA_ARGS__);   \
+       return False;                                   \
+    }while(0)
+
     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;
-    if (ip_fast_csum((uint8_t *)iph, iph->ihl)!=0) return False;
+    if (iph->ihl < 5) BAD("ihl %u",iph->ihl);
+    if (iph->version != 4) BAD("version %u",iph->version);
+    if (buf->size < iph->ihl*4) BAD("size %"PRId32"<%u*4",buf->size,iph->ihl);
+    if (ip_fast_csum((uint8_t *)iph, iph->ihl)!=0) BAD("csum");
     len=ntohs(iph->tot_len);
     /* There should be no padding */
-    if (buf->size!=len || len<(iph->ihl<<2)) return False;
+    if (buf->size!=len) BAD("len %"PRId32"!=%"PRId32,buf->size,len);
+    if (len<(iph->ihl<<2)) BAD("len %"PRId32"<(%u<<2)",len,iph->ihl);
     /* XXX check that there's no source route specified */
     return True;
+
+#undef BAD
 }
 
 /* Deliver a packet. "client" is the _origin_ of the packet, not its
@@ -594,11 +605,13 @@ static void netlink_incoming(struct netlink *st, struct netlink_client *client,
 {
     uint32_t source,dest;
     struct iphdr *iph;
+    char errmsgbuf[50];
 
     BUF_ASSERT_USED(buf);
-    if (!netlink_check(st,buf)) {
-       Message(M_WARNING,"%s: bad IP packet from %s\n",
-               st->name,client?client->name:"host");
+    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",
+               errmsgbuf);
        BUF_FREE(buf);
        return;
     }
@@ -695,7 +708,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; i<snets->entries; i++) {
@@ -763,7 +776,7 @@ 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
@@ -790,28 +803,7 @@ 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, uint32_t new_mtu)
+static void netlink_inst_set_mtu(void *sst, int32_t new_mtu)
 {
     struct netlink_client *c=sst;
 
@@ -819,8 +811,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;
@@ -847,7 +839,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);
@@ -896,8 +889,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;
 
@@ -907,7 +898,7 @@ static closure_t *netlink_inst_create(struct netlink *st,
     c->deliver=NULL;
     c->dst=NULL;
     c->name=name;
-    c->link_quality=LINK_QUALITY_DOWN;
+    c->link_quality=LINK_QUALITY_UNUSED;
     c->mtu=mtu?mtu:st->mtu;
     c->options=options;
     c->outcount=0;