Annotation of embedaddon/coova-chilli/src/chksum.c, revision 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>