Diff for /embedaddon/libnet/src/libnet_checksum.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/07/22 11:54:42 version 1.1.1.3, 2023/09/27 11:11:38
Line 30 Line 30
  *   *
  */   */
   
#if (HAVE_CONFIG_H)#include "common.h"
#include "../include/config.h" 
#endif 
#if (!(_WIN32) || (__CYGWIN__))  
#include "../include/libnet.h" 
#else 
#include "../include/win32/libnet.h" 
#endif 
   
 /* FIXME - unit test these - 0 is debian's version, else is -RC1's */  
 /* Note about aliasing warning:  
  *  
  *   http://mail.opensolaris.org/pipermail/tools-gcc/2005-August/000047.html  
  *  
  * See RFC 1071, and:  
  *  
  *   http://mathforum.org/library/drmath/view/54379.html  
  */  
 #undef DEBIAN  
 /* Note: len is in bytes, not 16-bit words! */  /* Note: len is in bytes, not 16-bit words! */
 int  int
 libnet_in_cksum(uint16_t *addr, int len)  libnet_in_cksum(uint16_t *addr, int len)
 {  {
    int sum;    int sum = 0;
#ifdef DEBIAN 
    uint16_t last_byte; 
 
    sum = 0; 
    last_byte = 0; 
#else 
     union      union
     {      {
         uint16_t s;          uint16_t s;
         uint8_t b[2];          uint8_t b[2];
    }pad;    } pad;
   
     sum = 0;      sum = 0;
 #endif  
   
     while (len > 1)      while (len > 1)
     {      {
         sum += *addr++;          sum += *addr++;
         len -= 2;          len -= 2;
     }      }
#ifdef DEBIAN
     if (len == 1)      if (len == 1)
     {      {
         *(uint8_t *)&last_byte = *(uint8_t *)addr;  
         sum += last_byte;  
 #else  
     if (len == 1)  
     {  
         pad.b[0] = *(uint8_t *)addr;          pad.b[0] = *(uint8_t *)addr;
         pad.b[1] = 0;          pad.b[1] = 0;
         sum += pad.s;          sum += pad.s;
 #endif  
     }      }
   
     return (sum);      return (sum);
Line 133  static int check_ip_payload_size(libnet_t*l, const uin Line 103  static int check_ip_payload_size(libnet_t*l, const uin
     if((iphdr+ip_hl+h_len) > end)      if((iphdr+ip_hl+h_len) > end)
     {      {
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)\n", func,                "%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)", func,
                 (int)(end - iphdr), ip_hl, h_len);                  (int)(end - iphdr), ip_hl, h_len);
         return -1;          return -1;
     }      }
Line 187  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 157  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
     /* will need to update this for ipv6 at some point */      /* will need to update this for ipv6 at some point */
     struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;      struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;
     struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */      struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */
    int ip_hl   = 0;    int ip_hl = 0;
    int sum     = 0;    int sum = 0;
     uint8_t ip_nh = 0;
   
     /* Check for memory under/over reads/writes. */      /* Check for memory under/over reads/writes. */
     if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end)      if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end)
     {      {
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): ipv4 hdr not inside packet (where %d, size %d)\n", __func__,            "%s(): ipv4 hdr not inside packet (where %d, size %d)", __func__,
             (int)(iphdr-beg), (int)(end-beg));              (int)(iphdr-beg), (int)(end-beg));
         return -1;          return -1;
     }      }
Line 208  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 179  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
         ip6h_p = (struct libnet_ipv6_hdr *)iph_p;          ip6h_p = (struct libnet_ipv6_hdr *)iph_p;
         iph_p = NULL;          iph_p = NULL;
         ip_hl   = 40;          ip_hl   = 40;
           ip_nh = ip6h_p->ip_nh;
   
         if((uint8_t*)(ip6h_p+1) > end)          if((uint8_t*)(ip6h_p+1) > end)
         {          {
             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): ipv6 hdr not inside packet\n", __func__);                    "%s(): ipv6 hdr not inside packet", __func__);
             return -1;              return -1;
         }          }
   
           /* FIXME this entire fragile exercise would be avoided if we just passed
            * in the pointer to the protocol block 'q' we are checksumming, which
            * we know.
            */
           while (ip_nh != protocol && (uint8_t*)ip6h_p + ip_hl + 1 < end)
           {
               /* next header is not the upper layer protocol */
              switch (ip_nh)
              {
                 case IPPROTO_DSTOPTS:
                 case IPPROTO_HOPOPTS:
                 case IPPROTO_ROUTING:
                 case IPPROTO_FRAGMENT:
                 case IPPROTO_AH:
                 case IPPROTO_ESP:
                 case IPPROTO_MH:
                    /*
                     * count option headers to the header length for
                     * checksum processing
                     */
                    /* Common structure of ipv6 ext headers is:
                     *  uint8: next header protocol
                     *  uint8: length of this header, in multiples of 8, not
                     *    including first eight octets
                     * The pointer arithmetic below follows from above.
                     */
                    ip_nh = *((uint8_t*)ip6h_p+ip_hl); /* next next header */
                    ip_hl += (*((uint8_t*)ip6h_p+ip_hl+1)+1)*8; /* ext header length */
                    break;
                 default:
                    snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                        "%s(): unsupported extension header (%d)", __func__, ip_nh);
                    return -1;
              }
   
           }
     }      }
     else      else
     {      {
Line 223  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 233  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
     if((iphdr+ip_hl) > end)      if((iphdr+ip_hl) > end)
     {      {
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
            "%s(): ip hdr len not inside packet\n", __func__);            "%s(): ip hdr len not inside packet", __func__);
         return -1;          return -1;
     }      }
   
Line 238  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 248  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             struct libnet_tcp_hdr *tcph_p =              struct libnet_tcp_hdr *tcph_p =
                 (struct libnet_tcp_hdr *)(iphdr + ip_hl);                  (struct libnet_tcp_hdr *)(iphdr + ip_hl);
   
            h_len = end - (uint8_t*) tcph_p; /* ignore h_len, sum the packet we've coalesced */            h_len = (int)(end - (uint8_t*) tcph_p); /* ignore h_len, sum the packet we've coalesced */
   
             CHECK_IP_PAYLOAD_SIZE();              CHECK_IP_PAYLOAD_SIZE();
   
Line 292  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 302  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             struct libnet_udp_hdr *udph_p =              struct libnet_udp_hdr *udph_p =
                 (struct libnet_udp_hdr *)(iphdr + ip_hl);                  (struct libnet_udp_hdr *)(iphdr + ip_hl);
   
            h_len = end - (uint8_t*) udph_p; /* ignore h_len, sum the packet we've coalesced */            h_len = (int)(end - (uint8_t*) udph_p); /* ignore h_len, sum the packet we've coalesced */
   
             CHECK_IP_PAYLOAD_SIZE();              CHECK_IP_PAYLOAD_SIZE();
   
Line 315  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 325  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             struct libnet_icmpv4_hdr *icmph_p =              struct libnet_icmpv4_hdr *icmph_p =
                 (struct libnet_icmpv4_hdr *)(iphdr + ip_hl);                  (struct libnet_icmpv4_hdr *)(iphdr + ip_hl);
   
            h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */            h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */
   
             CHECK_IP_PAYLOAD_SIZE();              CHECK_IP_PAYLOAD_SIZE();
   
Line 337  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 347  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             struct libnet_icmpv6_hdr *icmph_p =              struct libnet_icmpv6_hdr *icmph_p =
                 (struct libnet_icmpv6_hdr *)(iphdr + ip_hl);                  (struct libnet_icmpv6_hdr *)(iphdr + ip_hl);
   
            h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */            h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */
   
             CHECK_IP_PAYLOAD_SIZE();              CHECK_IP_PAYLOAD_SIZE();
   
Line 356  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 366  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             struct libnet_igmp_hdr *igmph_p =              struct libnet_igmp_hdr *igmph_p =
                 (struct libnet_igmp_hdr *)(iphdr + ip_hl);                  (struct libnet_igmp_hdr *)(iphdr + ip_hl);
   
            h_len = end - (uint8_t*) igmph_p; /* ignore h_len, sum the packet we've coalesced */            h_len = (int)(end - (uint8_t*) igmph_p); /* ignore h_len, sum the packet we've coalesced */
   
             CHECK_IP_PAYLOAD_SIZE();              CHECK_IP_PAYLOAD_SIZE();
   
Line 380  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 390  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
                 !(fv & (GRE_CSUM|GRE_VERSION_1)))                  !(fv & (GRE_CSUM|GRE_VERSION_1)))
             {              {
                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                  snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )\n",  __func__, fv);                "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )",  __func__, fv);
                 return (-1);                  return (-1);
             }              }
             sum = libnet_in_cksum((uint16_t *)greh_p, h_len);              sum = libnet_in_cksum((uint16_t *)greh_p, h_len);
Line 496  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 506  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
             if((iphdr+h_len) > end)              if((iphdr+h_len) > end)
             {              {
                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                  snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                        "%s(): cdp payload not inside packet\n", __func__);                        "%s(): cdp payload not inside packet", __func__);
                 return -1;                  return -1;
             }              }
   
Line 519  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int  Line 529  libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int 
         default:          default:
         {          {
             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,              snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): unsupported protocol %d\n", __func__, protocol);                "%s(): unsupported protocol %d", __func__, protocol);
             return (-1);              return (-1);
         }          }
     }      }
Line 536  libnet_ip_check(uint16_t *addr, int len) Line 546  libnet_ip_check(uint16_t *addr, int len)
     return (LIBNET_CKSUM_CARRY(sum));      return (LIBNET_CKSUM_CARRY(sum));
 }  }
   
/* EOF *//**
  * Local Variables:
  *  indent-tabs-mode: nil
  *  c-file-style: "stroustrup"
  * End:
  */

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


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