Annotation of embedaddon/coova-chilli/src/chksum.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Chksum library functions
                      3:  * Copyright (c) 2006-2008 David Bird <david@coova.com>
                      4:  *
                      5:  * The contents of this file may be used under the terms of the GNU
                      6:  * General Public License Version 2, provided that the above copyright
                      7:  * notice and this permission notice is included in all copies or
                      8:  * substantial portions of the software.
                      9:  *
                     10:  */
                     11: 
                     12: #include "system.h"
                     13: #include "pkt.h"
                     14: #include "options.h"
                     15: #include "syserr.h"
                     16: 
                     17: #define cksum_wrap(c) (c=(c>>16)+(c&0xffff),(~(c+(c>>16))&0xffff))
                     18: 
                     19: int
                     20: in_cksum(uint16_t *addr, size_t len)
                     21: {
                     22:   size_t      nleft = len;
                     23:   uint32_t    sum = 0;
                     24:   uint16_t  * w = addr;
                     25:   
                     26:   while (nleft > 1)  {
                     27:     sum += *w++;
                     28:     nleft -= 2;
                     29:   }
                     30:   
                     31:   if (nleft == 1) {
                     32:     uint16_t ans = 0;
                     33:     *(unsigned char *)(&ans) = *(unsigned char *)w ;
                     34:     sum += ans;
                     35:   }
                     36:   
                     37:   return(sum);
                     38: }
                     39: 
                     40: int chksum(struct pkt_iphdr_t *iph) {
                     41:   size_t hlen = (iph->version_ihl & 0x0f) << 2;
                     42:   int sum;
                     43: 
                     44:   switch(iph->protocol) {
                     45:   case PKT_IP_PROTO_TCP:
                     46:     {
                     47:       struct pkt_tcphdr_t *tcph = (struct pkt_tcphdr_t *)(((void *)iph) + hlen);
                     48:       size_t len = (size_t)ntohs(iph->tot_len);
                     49:       
                     50:       if (len > 2000) return -1; /* too long? */
                     51:       
                     52:       len -= (iph->version_ihl & 0x0f) << 2;
                     53:       
                     54:       if (len < 20) return -1;  /* too short? */
                     55:       
                     56:       tcph->check = 0;
                     57:       sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
                     58:       sum += ntohs(IPPROTO_TCP + len);
                     59:       sum += in_cksum((uint16_t *)tcph, len);
                     60:       tcph->check = cksum_wrap(sum);
                     61:     }
                     62:     break;
                     63:     
                     64:   case PKT_IP_PROTO_UDP:
                     65:     {
                     66:       struct pkt_udphdr_t *udph = (struct pkt_udphdr_t *)(((void *)iph) + hlen);
                     67:       size_t len = (size_t)ntohs(udph->len);
                     68:       
                     69:       udph->check = 0;
                     70:       sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
                     71:       sum += ntohs(IPPROTO_UDP + len);
                     72:       sum += in_cksum((uint16_t *)udph, len);
                     73:       udph->check = cksum_wrap(sum);
                     74:     }
                     75:     break;
                     76:   }
                     77:   
                     78:   iph->check = 0;
                     79:   sum = in_cksum((uint16_t *)iph, hlen);
                     80:   iph->check = cksum_wrap(sum);
                     81:   
                     82:   return 0;
                     83: }
                     84: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>