Annotation of embedaddon/libnet/src/libnet_checksum.c, revision 1.1.1.3

1.1       misho       1: /*
1.1.1.2   misho       2:  *  $Id: libnet_checksum.c,v 1.14 2004/11/09 07:05:07 mike Exp $
1.1       misho       3:  *
                      4:  *  libnet
                      5:  *  libnet_checksum.c - checksum routines
                      6:  *
                      7:  *  Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
                      8:  *  All rights reserved.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     29:  * SUCH DAMAGE.
                     30:  *
                     31:  */
                     32: 
1.1.1.3 ! misho      33: #include "common.h"
1.1.1.2   misho      34: 
                     35: /* Note: len is in bytes, not 16-bit words! */
1.1       misho      36: int
1.1.1.2   misho      37: libnet_in_cksum(uint16_t *addr, int len)
1.1       misho      38: {
1.1.1.3 ! misho      39:     int sum = 0;
1.1.1.2   misho      40:     union
                     41:     {
                     42:         uint16_t s;
                     43:         uint8_t b[2];
1.1.1.3 ! misho      44:     } pad;
1.1.1.2   misho      45: 
                     46:     sum = 0;
1.1       misho      47: 
                     48:     while (len > 1)
                     49:     {
                     50:         sum += *addr++;
                     51:         len -= 2;
                     52:     }
1.1.1.3 ! misho      53: 
1.1.1.2   misho      54:     if (len == 1)
                     55:     {
                     56:         pad.b[0] = *(uint8_t *)addr;
                     57:         pad.b[1] = 0;
                     58:         sum += pad.s;
1.1       misho      59:     }
                     60: 
                     61:     return (sum);
                     62: }
                     63: 
                     64: int
                     65: libnet_toggle_checksum(libnet_t *l, libnet_ptag_t ptag, int mode)
                     66: {
                     67:     libnet_pblock_t *p;
                     68: 
                     69:     p = libnet_pblock_find(l, ptag);
                     70:     if (p == NULL)
                     71:     {
                     72:         /* err msg set in libnet_pblock_find() */
                     73:         return (-1);
                     74:     }
                     75:     if (mode == LIBNET_ON)
                     76:     {
                     77:         if ((p->flags) & LIBNET_PBLOCK_DO_CHECKSUM)
                     78:         {
                     79:             return (1);
                     80:         }
                     81:         else
                     82:         {
                     83:             (p->flags) |= LIBNET_PBLOCK_DO_CHECKSUM;
                     84:             return (1);
                     85:         }
                     86:     }
                     87:     else
                     88:     {
                     89:         if ((p->flags) & LIBNET_PBLOCK_DO_CHECKSUM)
                     90:         {
                     91:             (p->flags) &= ~LIBNET_PBLOCK_DO_CHECKSUM;
                     92:             return (1);
                     93:         }
                     94:         else
                     95:         {
                     96:             return (1);
                     97:         }
                     98:     }
                     99: }
                    100: 
1.1.1.2   misho     101: static int check_ip_payload_size(libnet_t*l, const uint8_t *iphdr, int ip_hl, int h_len, const uint8_t * end, const char* func)
                    102: {
                    103:     if((iphdr+ip_hl+h_len) > end)
                    104:     {
                    105:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     106:                 "%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)", func,
1.1.1.2   misho     107:                (int)(end - iphdr), ip_hl, h_len);
                    108:         return -1;
                    109:     }
                    110: 
                    111:     return 0;
                    112: }
                    113: 
1.1       misho     114: 
1.1.1.2   misho     115: /*
                    116:  * For backwards binary compatibility. The calculations done here can easily
                    117:  * result in buffer overreads and overwrites. You have been warned. And no, it
                    118:  * is not possible to fix, the API contains no information on the buffer's
                    119:  * boundary. libnet itself calls the safe function, libnet_inet_checksum(). So
                    120:  * should you.
                    121:  */
1.1       misho     122: int
1.1.1.2   misho     123: libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len)
1.1       misho     124: {
1.1.1.2   misho     125:     uint16_t ip_len = 0;
                    126:     struct libnet_ipv4_hdr* ip4 = (struct libnet_ipv4_hdr *)iphdr;
                    127:     struct libnet_ipv6_hdr* ip6 = (struct libnet_ipv6_hdr *)iphdr;
                    128: 
                    129:     if(ip4->ip_v == 6) {
                    130:         ip_len = ntohs(ip6->ip_len);
                    131:     } else {
                    132:         ip_len = ntohs(ip4->ip_len);
                    133:     }
                    134: 
                    135:     return libnet_inet_checksum(l, iphdr, protocol, h_len,
                    136:             iphdr, iphdr + ip_len
                    137:             );
                    138: }
                    139: 
                    140: 
                    141: #define CHECK_IP_PAYLOAD_SIZE() do { \
                    142:     int e=check_ip_payload_size(l,iphdr,ip_hl, h_len, end, __func__);\
                    143:     if(e) return e;\
                    144: } while(0)
1.1       misho     145: 
                    146: 
1.1.1.2   misho     147: /*
                    148:  * We are checksumming pblock "q"
                    149:  *
                    150:  * iphdr is the pointer to it's encapsulating IP header
                    151:  * protocol describes the type of "q", expressed as an IPPROTO_ value
                    152:  * h_len is the h_len from "q"
                    153:  */
                    154: int
                    155: libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end)
                    156: {
                    157:     /* will need to update this for ipv6 at some point */
                    158:     struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;
                    159:     struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */
1.1.1.3 ! misho     160:     int ip_hl = 0;
        !           161:     int sum = 0;
        !           162:     uint8_t ip_nh = 0;
1.1.1.2   misho     163: 
                    164:     /* Check for memory under/over reads/writes. */
                    165:     if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end)
1.1       misho     166:     {
                    167:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     168:             "%s(): ipv4 hdr not inside packet (where %d, size %d)", __func__,
1.1.1.2   misho     169:            (int)(iphdr-beg), (int)(end-beg));
                    170:         return -1;
1.1       misho     171:     }
                    172: 
                    173:     /*
                    174:      *  Figure out which IP version we're dealing with.  We'll assume v4
                    175:      *  and overlay a header structure to yank out the version.
                    176:      */
1.1.1.2   misho     177:     if (iph_p->ip_v == 6)
1.1       misho     178:     {
1.1.1.2   misho     179:         ip6h_p = (struct libnet_ipv6_hdr *)iph_p;
                    180:         iph_p = NULL;
1.1       misho     181:         ip_hl   = 40;
1.1.1.3 ! misho     182:         ip_nh = ip6h_p->ip_nh;
        !           183: 
1.1.1.2   misho     184:         if((uint8_t*)(ip6h_p+1) > end)
                    185:         {
                    186:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     187:                     "%s(): ipv6 hdr not inside packet", __func__);
1.1.1.2   misho     188:             return -1;
                    189:         }
1.1.1.3 ! misho     190: 
        !           191:         /* FIXME this entire fragile exercise would be avoided if we just passed
        !           192:          * in the pointer to the protocol block 'q' we are checksumming, which
        !           193:          * we know.
        !           194:          */
        !           195:         while (ip_nh != protocol && (uint8_t*)ip6h_p + ip_hl + 1 < end)
        !           196:         {
        !           197:             /* next header is not the upper layer protocol */
        !           198:            switch (ip_nh)
        !           199:            {
        !           200:               case IPPROTO_DSTOPTS:
        !           201:               case IPPROTO_HOPOPTS:
        !           202:               case IPPROTO_ROUTING:
        !           203:               case IPPROTO_FRAGMENT:
        !           204:               case IPPROTO_AH:
        !           205:               case IPPROTO_ESP:
        !           206:               case IPPROTO_MH:
        !           207:                  /*
        !           208:                   * count option headers to the header length for
        !           209:                   * checksum processing
        !           210:                   */
        !           211:                  /* Common structure of ipv6 ext headers is:
        !           212:                   *  uint8: next header protocol
        !           213:                   *  uint8: length of this header, in multiples of 8, not
        !           214:                   *    including first eight octets
        !           215:                   * The pointer arithmetic below follows from above.
        !           216:                   */
        !           217:                  ip_nh = *((uint8_t*)ip6h_p+ip_hl); /* next next header */
        !           218:                  ip_hl += (*((uint8_t*)ip6h_p+ip_hl+1)+1)*8; /* ext header length */
        !           219:                  break;
        !           220:               default:
        !           221:                  snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           222:                      "%s(): unsupported extension header (%d)", __func__, ip_nh);
        !           223:                  return -1;
        !           224:            }
        !           225: 
        !           226:         }
1.1       misho     227:     }
                    228:     else
                    229:     {
                    230:         ip_hl = iph_p->ip_hl << 2;
                    231:     }
                    232: 
1.1.1.2   misho     233:     if((iphdr+ip_hl) > end)
                    234:     {
                    235:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     236:             "%s(): ip hdr len not inside packet", __func__);
1.1.1.2   misho     237:         return -1;
                    238:     }
                    239: 
1.1       misho     240:     /*
                    241:      *  Dug Song came up with this very cool checksuming implementation
                    242:      *  eliminating the need for explicit psuedoheader use.  Check it out.
                    243:      */
                    244:     switch (protocol)
                    245:     {
                    246:         case IPPROTO_TCP:
                    247:         {
                    248:             struct libnet_tcp_hdr *tcph_p =
1.1.1.2   misho     249:                 (struct libnet_tcp_hdr *)(iphdr + ip_hl);
                    250: 
1.1.1.3 ! misho     251:            h_len = (int)(end - (uint8_t*) tcph_p); /* ignore h_len, sum the packet we've coalesced */
1.1.1.2   misho     252: 
                    253:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     254: 
                    255: #if (STUPID_SOLARIS_CHECKSUM_BUG)
                    256:             tcph_p->th_sum = tcph_p->th_off << 2;
                    257:             return (1);
                    258: #endif /* STUPID_SOLARIS_CHECKSUM_BUG */
                    259: #if (HAVE_HPUX11)   
                    260:             if (l->injection_type != LIBNET_LINK)
                    261:             {
                    262:                 /*
                    263:                  *  Similiar to the Solaris Checksum bug - but need to add
                    264:                  *  the size of the TCP payload (only for raw sockets).
                    265:                  */
                    266:                 tcph_p->th_sum = (tcph_p->th_off << 2) +
1.1.1.2   misho     267:                         (h_len - (tcph_p->th_off << 2));
1.1       misho     268:                 return (1); 
                    269:             }
                    270: #endif
1.1.1.2   misho     271:             /* TCP checksum is over the IP pseudo header:
                    272:              * ip src
                    273:              * ip dst
                    274:              * tcp protocol (IPPROTO_TCP)
                    275:              * tcp length, including the header
                    276:              * + the TCP header (with checksum set to zero) and data
                    277:              */
1.1       misho     278:             tcph_p->th_sum = 0;
1.1.1.2   misho     279:             if (ip6h_p)
1.1       misho     280:             {
1.1.1.2   misho     281:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
1.1       misho     282:             }
                    283:             else
                    284:             {
1.1.1.2   misho     285:                 /* 8 = src and dst */
                    286:                 sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
1.1       misho     287:             }
1.1.1.2   misho     288:             sum += ntohs(IPPROTO_TCP + h_len);
                    289:             sum += libnet_in_cksum((uint16_t *)tcph_p, h_len);
1.1       misho     290:             tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum);
1.1.1.2   misho     291: #if 0
                    292:             printf("tcp sum calculated: %#x/%d h_len %d\n",
                    293:                     ntohs(tcph_p->th_sum),
                    294:                     ntohs(tcph_p->th_sum),
                    295:                     h_len
                    296:                   );
                    297: #endif
1.1       misho     298:             break;
                    299:         }
                    300:         case IPPROTO_UDP:
                    301:         {
                    302:             struct libnet_udp_hdr *udph_p =
1.1.1.2   misho     303:                 (struct libnet_udp_hdr *)(iphdr + ip_hl);
                    304: 
1.1.1.3 ! misho     305:            h_len = (int)(end - (uint8_t*) udph_p); /* ignore h_len, sum the packet we've coalesced */
1.1.1.2   misho     306: 
                    307:             CHECK_IP_PAYLOAD_SIZE();
                    308: 
1.1       misho     309:             udph_p->uh_sum = 0;
1.1.1.2   misho     310:             if (ip6h_p)
1.1       misho     311:             {
1.1.1.2   misho     312:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
1.1       misho     313:             }
                    314:             else
                    315:             {
1.1.1.2   misho     316:                 sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
1.1       misho     317:             }
1.1.1.2   misho     318:             sum += ntohs(IPPROTO_UDP + h_len);
                    319:             sum += libnet_in_cksum((uint16_t *)udph_p, h_len);
1.1       misho     320:             udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum);
                    321:             break;
                    322:         }
                    323:         case IPPROTO_ICMP:
                    324:         {
                    325:             struct libnet_icmpv4_hdr *icmph_p =
1.1.1.2   misho     326:                 (struct libnet_icmpv4_hdr *)(iphdr + ip_hl);
                    327: 
1.1.1.3 ! misho     328:             h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */
1.1.1.2   misho     329: 
                    330:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     331: 
                    332:             icmph_p->icmp_sum = 0;
1.1.1.2   misho     333:             /* Hm, is this valid? Is the checksum algorithm for ICMPv6 encapsulated in IPv4
                    334:              * actually defined?
                    335:              */
                    336:             if (ip6h_p)
1.1       misho     337:             {
1.1.1.2   misho     338:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
                    339:                 sum += ntohs(IPPROTO_ICMP6 + h_len);
1.1       misho     340:             }
1.1.1.2   misho     341:             sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
                    342:             icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
                    343:             break;
                    344:         }
                    345:         case IPPROTO_ICMPV6:
                    346:         {
                    347:             struct libnet_icmpv6_hdr *icmph_p =
                    348:                 (struct libnet_icmpv6_hdr *)(iphdr + ip_hl);
                    349: 
1.1.1.3 ! misho     350:             h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */
1.1.1.2   misho     351: 
                    352:             CHECK_IP_PAYLOAD_SIZE();
                    353: 
                    354:             icmph_p->icmp_sum = 0;
                    355:             if (ip6h_p)
                    356:             {
                    357:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
                    358:                 sum += ntohs(IPPROTO_ICMP6 + h_len);
                    359:             }
                    360:             sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
1.1       misho     361:             icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
                    362:             break;
                    363:         }
                    364:         case IPPROTO_IGMP:
                    365:         {
                    366:             struct libnet_igmp_hdr *igmph_p =
1.1.1.2   misho     367:                 (struct libnet_igmp_hdr *)(iphdr + ip_hl);
                    368: 
1.1.1.3 ! misho     369:            h_len = (int)(end - (uint8_t*) igmph_p); /* ignore h_len, sum the packet we've coalesced */
1.1.1.2   misho     370: 
                    371:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     372: 
                    373:             igmph_p->igmp_sum = 0;
1.1.1.2   misho     374:             sum = libnet_in_cksum((uint16_t *)igmph_p, h_len);
1.1       misho     375:             igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum);
                    376:             break;
                    377:         }
                    378:        case IPPROTO_GRE:
                    379:        {
                    380:             /* checksum is always at the same place in GRE header
                    381:              * in the multiple RFC version of the protocol ... ouf !!!
                    382:              */
                    383:            struct libnet_gre_hdr *greh_p = 
1.1.1.2   misho     384:                (struct libnet_gre_hdr *)(iphdr + ip_hl);
                    385:            uint16_t fv = ntohs(greh_p->flags_ver);
                    386: 
                    387:             CHECK_IP_PAYLOAD_SIZE();
                    388: 
1.1       misho     389:            if (!(fv & (GRE_CSUM|GRE_ROUTING | GRE_VERSION_0)) ||
                    390:                 !(fv & (GRE_CSUM|GRE_VERSION_1)))
                    391:            {
                    392:                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     393:                 "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )",  __func__, fv);
1.1       misho     394:                return (-1);
                    395:            }
1.1.1.2   misho     396:            sum = libnet_in_cksum((uint16_t *)greh_p, h_len);
1.1       misho     397:            greh_p->gre_sum = LIBNET_CKSUM_CARRY(sum);
                    398:            break;
                    399:        }
                    400:         case IPPROTO_OSPF:
                    401:         {
                    402:             struct libnet_ospf_hdr *oh_p =
1.1.1.2   misho     403:                 (struct libnet_ospf_hdr *)(iphdr + ip_hl);
                    404: 
                    405:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     406: 
                    407:             oh_p->ospf_sum = 0;
1.1.1.2   misho     408:             sum += libnet_in_cksum((uint16_t *)oh_p, h_len);
1.1       misho     409:             oh_p->ospf_sum = LIBNET_CKSUM_CARRY(sum);
                    410:             break;
                    411:         }
                    412:         case IPPROTO_OSPF_LSA:
                    413:         {
                    414:             struct libnet_ospf_hdr *oh_p =
1.1.1.2   misho     415:                 (struct libnet_ospf_hdr *)(iphdr + ip_hl);
1.1       misho     416:             struct libnet_lsa_hdr *lsa_p =
1.1.1.2   misho     417:                 (struct libnet_lsa_hdr *)(iphdr + 
1.1       misho     418:                 ip_hl + oh_p->ospf_len);
                    419: 
1.1.1.2   misho     420:             /* FIXME need additional length check, to account for ospf_len */
1.1       misho     421:             lsa_p->lsa_sum = 0;
1.1.1.2   misho     422:             sum += libnet_in_cksum((uint16_t *)lsa_p, h_len);
1.1       misho     423:             lsa_p->lsa_sum = LIBNET_CKSUM_CARRY(sum);
                    424:             break;
                    425: #if 0
                    426:             /*
                    427:              *  Reworked fletcher checksum taken from RFC 1008.
                    428:              */
                    429:             int c0, c1;
                    430:             struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf;
1.1.1.2   misho     431:             uint8_t *p, *p1, *p2, *p3;
1.1       misho     432: 
                    433:             c0 = 0;
                    434:             c1 = 0;
                    435: 
                    436:             lsa_p->lsa_cksum = 0;
                    437: 
                    438:             p = buf;
                    439:             p1 = buf;
                    440:             p3 = buf + len;             /* beginning and end of buf */
                    441: 
                    442:             while (p1 < p3)
                    443:             {
                    444:                 p2 = p1 + LIBNET_MODX;
                    445:                 if (p2 > p3)
                    446:                 {
                    447:                     p2 = p3;
                    448:                 }
                    449:   
                    450:                 for (p = p1; p < p2; p++)
                    451:                 {
                    452:                     c0 += (*p);
                    453:                     c1 += c0;
                    454:                 }
                    455: 
                    456:                 c0 %= 255;
                    457:                 c1 %= 255;      /* modular 255 */
                    458:  
                    459:                 p1 = p2;
                    460:             }
                    461: 
                    462: #if AWR_PLEASE_REWORK_THIS
                    463:             lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255);
                    464:             if (lsa_p->lsa_cksum[0] <= 0)
                    465:             {
                    466:                 lsa_p->lsa_cksum[0] += 255;
                    467:             }
                    468: 
                    469:             lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]);
                    470:             if (lsa_p->lsa_cksum[1] > 255)
                    471:             {
                    472:                 lsa_p->lsa_cksum[1] -= 255;
                    473:             }
                    474: #endif
                    475:             break;
                    476: #endif
                    477:         }
                    478:         case IPPROTO_IP:
                    479:         {
1.1.1.2   misho     480:             if(!iph_p) {
                    481:                 /* IPv6 doesn't have a checksum */
                    482:             } else {
                    483:                 iph_p->ip_sum = 0;
                    484:                 sum = libnet_in_cksum((uint16_t *)iph_p, ip_hl);
                    485:                 iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum);
                    486:             }
1.1       misho     487:             break;
                    488:         }
                    489:         case IPPROTO_VRRP:
                    490:         {
                    491:             struct libnet_vrrp_hdr *vrrph_p =
1.1.1.2   misho     492:                 (struct libnet_vrrp_hdr *)(iphdr + ip_hl);
                    493:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     494: 
                    495:             vrrph_p->vrrp_sum = 0;
1.1.1.2   misho     496:             sum = libnet_in_cksum((uint16_t *)vrrph_p, h_len);
1.1       misho     497:             vrrph_p->vrrp_sum = LIBNET_CKSUM_CARRY(sum);
                    498:             break;
                    499:         }
                    500:         case LIBNET_PROTO_CDP:
                    501:         {   /* XXX - Broken: how can we easily get the entire packet size? */
1.1.1.2   misho     502:            /* FIXME you can't, checksumming non-IP protocols was not supported by libnet */
1.1       misho     503:             struct libnet_cdp_hdr *cdph_p =
1.1.1.2   misho     504:                 (struct libnet_cdp_hdr *)iphdr;
                    505: 
                    506:             if((iphdr+h_len) > end)
                    507:             {
                    508:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     509:                         "%s(): cdp payload not inside packet", __func__);
1.1.1.2   misho     510:                 return -1;
                    511:             }
1.1       misho     512: 
                    513:             cdph_p->cdp_sum = 0;
1.1.1.2   misho     514:             sum = libnet_in_cksum((uint16_t *)cdph_p, h_len);
1.1       misho     515:             cdph_p->cdp_sum = LIBNET_CKSUM_CARRY(sum);
                    516:             break;
                    517:         }
                    518:         case LIBNET_PROTO_ISL:
                    519:         {
1.1.1.2   misho     520: #if 0
                    521:             struct libnet_isl_hdr *islh_p =
                    522:                 (struct libnet_isl_hdr *)buf;
                    523: #endif
1.1       misho     524:             /*
                    525:              *  Need to compute 4 byte CRC for the ethernet frame and for
                    526:              *  the ISL frame itself.  Use the libnet_crc function.
                    527:              */
                    528:         }
                    529:         default:
                    530:         {
                    531:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.3 ! misho     532:                 "%s(): unsupported protocol %d", __func__, protocol);
1.1       misho     533:             return (-1);
                    534:         }
                    535:     }
                    536:     return (1);
                    537: }
                    538: 
                    539: 
1.1.1.2   misho     540: uint16_t
                    541: libnet_ip_check(uint16_t *addr, int len)
1.1       misho     542: {
                    543:     int sum;
                    544: 
                    545:     sum = libnet_in_cksum(addr, len);
                    546:     return (LIBNET_CKSUM_CARRY(sum));
                    547: }
                    548: 
1.1.1.3 ! misho     549: /**
        !           550:  * Local Variables:
        !           551:  *  indent-tabs-mode: nil
        !           552:  *  c-file-style: "stroustrup"
        !           553:  * End:
        !           554:  */

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