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

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: 
                     33: #if (HAVE_CONFIG_H)
                     34: #include "../include/config.h"
                     35: #endif
                     36: #if (!(_WIN32) || (__CYGWIN__)) 
                     37: #include "../include/libnet.h"
                     38: #else
                     39: #include "../include/win32/libnet.h"
                     40: #endif
1.1.1.2 ! misho      41: 
        !            42: /* FIXME - unit test these - 0 is debian's version, else is -RC1's */
        !            43: /* Note about aliasing warning:
        !            44:  *
        !            45:  *   http://mail.opensolaris.org/pipermail/tools-gcc/2005-August/000047.html
        !            46:  *
        !            47:  * See RFC 1071, and:
        !            48:  *
        !            49:  *   http://mathforum.org/library/drmath/view/54379.html
        !            50:  */
        !            51: #undef DEBIAN
        !            52: /* Note: len is in bytes, not 16-bit words! */
1.1       misho      53: int
1.1.1.2 ! misho      54: libnet_in_cksum(uint16_t *addr, int len)
1.1       misho      55: {
                     56:     int sum;
1.1.1.2 ! misho      57: #ifdef DEBIAN
        !            58:     uint16_t last_byte;
1.1       misho      59: 
                     60:     sum = 0;
1.1.1.2 ! misho      61:     last_byte = 0;
        !            62: #else
        !            63:     union
        !            64:     {
        !            65:         uint16_t s;
        !            66:         uint8_t b[2];
        !            67:     }pad;
        !            68: 
        !            69:     sum = 0;
        !            70: #endif
1.1       misho      71: 
                     72:     while (len > 1)
                     73:     {
                     74:         sum += *addr++;
                     75:         len -= 2;
                     76:     }
1.1.1.2 ! misho      77: #ifdef DEBIAN
1.1       misho      78:     if (len == 1)
                     79:     {
1.1.1.2 ! misho      80:         *(uint8_t *)&last_byte = *(uint8_t *)addr;
        !            81:         sum += last_byte;
        !            82: #else
        !            83:     if (len == 1)
        !            84:     {
        !            85:         pad.b[0] = *(uint8_t *)addr;
        !            86:         pad.b[1] = 0;
        !            87:         sum += pad.s;
        !            88: #endif
1.1       misho      89:     }
                     90: 
                     91:     return (sum);
                     92: }
                     93: 
                     94: int
                     95: libnet_toggle_checksum(libnet_t *l, libnet_ptag_t ptag, int mode)
                     96: {
                     97:     libnet_pblock_t *p;
                     98: 
                     99:     p = libnet_pblock_find(l, ptag);
                    100:     if (p == NULL)
                    101:     {
                    102:         /* err msg set in libnet_pblock_find() */
                    103:         return (-1);
                    104:     }
                    105:     if (mode == LIBNET_ON)
                    106:     {
                    107:         if ((p->flags) & LIBNET_PBLOCK_DO_CHECKSUM)
                    108:         {
                    109:             return (1);
                    110:         }
                    111:         else
                    112:         {
                    113:             (p->flags) |= LIBNET_PBLOCK_DO_CHECKSUM;
                    114:             return (1);
                    115:         }
                    116:     }
                    117:     else
                    118:     {
                    119:         if ((p->flags) & LIBNET_PBLOCK_DO_CHECKSUM)
                    120:         {
                    121:             (p->flags) &= ~LIBNET_PBLOCK_DO_CHECKSUM;
                    122:             return (1);
                    123:         }
                    124:         else
                    125:         {
                    126:             return (1);
                    127:         }
                    128:     }
                    129: }
                    130: 
1.1.1.2 ! misho     131: 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)
        !           132: {
        !           133:     if((iphdr+ip_hl+h_len) > end)
        !           134:     {
        !           135:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           136:                 "%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)\n", func,
        !           137:                (int)(end - iphdr), ip_hl, h_len);
        !           138:         return -1;
        !           139:     }
        !           140: 
        !           141:     return 0;
        !           142: }
        !           143: 
1.1       misho     144: 
1.1.1.2 ! misho     145: /*
        !           146:  * For backwards binary compatibility. The calculations done here can easily
        !           147:  * result in buffer overreads and overwrites. You have been warned. And no, it
        !           148:  * is not possible to fix, the API contains no information on the buffer's
        !           149:  * boundary. libnet itself calls the safe function, libnet_inet_checksum(). So
        !           150:  * should you.
        !           151:  */
1.1       misho     152: int
1.1.1.2 ! misho     153: libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len)
1.1       misho     154: {
1.1.1.2 ! misho     155:     uint16_t ip_len = 0;
        !           156:     struct libnet_ipv4_hdr* ip4 = (struct libnet_ipv4_hdr *)iphdr;
        !           157:     struct libnet_ipv6_hdr* ip6 = (struct libnet_ipv6_hdr *)iphdr;
        !           158: 
        !           159:     if(ip4->ip_v == 6) {
        !           160:         ip_len = ntohs(ip6->ip_len);
        !           161:     } else {
        !           162:         ip_len = ntohs(ip4->ip_len);
        !           163:     }
        !           164: 
        !           165:     return libnet_inet_checksum(l, iphdr, protocol, h_len,
        !           166:             iphdr, iphdr + ip_len
        !           167:             );
        !           168: }
        !           169: 
        !           170: 
        !           171: #define CHECK_IP_PAYLOAD_SIZE() do { \
        !           172:     int e=check_ip_payload_size(l,iphdr,ip_hl, h_len, end, __func__);\
        !           173:     if(e) return e;\
        !           174: } while(0)
1.1       misho     175: 
                    176: 
1.1.1.2 ! misho     177: /*
        !           178:  * We are checksumming pblock "q"
        !           179:  *
        !           180:  * iphdr is the pointer to it's encapsulating IP header
        !           181:  * protocol describes the type of "q", expressed as an IPPROTO_ value
        !           182:  * h_len is the h_len from "q"
        !           183:  */
        !           184: int
        !           185: libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end)
        !           186: {
        !           187:     /* will need to update this for ipv6 at some point */
        !           188:     struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;
        !           189:     struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */
        !           190:     int ip_hl   = 0;
        !           191:     int sum     = 0;
        !           192: 
        !           193:     /* Check for memory under/over reads/writes. */
        !           194:     if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end)
1.1       misho     195:     {
                    196:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.2 ! misho     197:             "%s(): ipv4 hdr not inside packet (where %d, size %d)\n", __func__,
        !           198:            (int)(iphdr-beg), (int)(end-beg));
        !           199:         return -1;
1.1       misho     200:     }
                    201: 
                    202:     /*
                    203:      *  Figure out which IP version we're dealing with.  We'll assume v4
                    204:      *  and overlay a header structure to yank out the version.
                    205:      */
1.1.1.2 ! misho     206:     if (iph_p->ip_v == 6)
1.1       misho     207:     {
1.1.1.2 ! misho     208:         ip6h_p = (struct libnet_ipv6_hdr *)iph_p;
        !           209:         iph_p = NULL;
1.1       misho     210:         ip_hl   = 40;
1.1.1.2 ! misho     211:         if((uint8_t*)(ip6h_p+1) > end)
        !           212:         {
        !           213:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           214:                     "%s(): ipv6 hdr not inside packet\n", __func__);
        !           215:             return -1;
        !           216:         }
1.1       misho     217:     }
                    218:     else
                    219:     {
                    220:         ip_hl = iph_p->ip_hl << 2;
                    221:     }
                    222: 
1.1.1.2 ! misho     223:     if((iphdr+ip_hl) > end)
        !           224:     {
        !           225:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           226:             "%s(): ip hdr len not inside packet\n", __func__);
        !           227:         return -1;
        !           228:     }
        !           229: 
1.1       misho     230:     /*
                    231:      *  Dug Song came up with this very cool checksuming implementation
                    232:      *  eliminating the need for explicit psuedoheader use.  Check it out.
                    233:      */
                    234:     switch (protocol)
                    235:     {
                    236:         case IPPROTO_TCP:
                    237:         {
                    238:             struct libnet_tcp_hdr *tcph_p =
1.1.1.2 ! misho     239:                 (struct libnet_tcp_hdr *)(iphdr + ip_hl);
        !           240: 
        !           241:            h_len = end - (uint8_t*) tcph_p; /* ignore h_len, sum the packet we've coalesced */
        !           242: 
        !           243:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     244: 
                    245: #if (STUPID_SOLARIS_CHECKSUM_BUG)
                    246:             tcph_p->th_sum = tcph_p->th_off << 2;
                    247:             return (1);
                    248: #endif /* STUPID_SOLARIS_CHECKSUM_BUG */
                    249: #if (HAVE_HPUX11)   
                    250:             if (l->injection_type != LIBNET_LINK)
                    251:             {
                    252:                 /*
                    253:                  *  Similiar to the Solaris Checksum bug - but need to add
                    254:                  *  the size of the TCP payload (only for raw sockets).
                    255:                  */
                    256:                 tcph_p->th_sum = (tcph_p->th_off << 2) +
1.1.1.2 ! misho     257:                         (h_len - (tcph_p->th_off << 2));
1.1       misho     258:                 return (1); 
                    259:             }
                    260: #endif
1.1.1.2 ! misho     261:             /* TCP checksum is over the IP pseudo header:
        !           262:              * ip src
        !           263:              * ip dst
        !           264:              * tcp protocol (IPPROTO_TCP)
        !           265:              * tcp length, including the header
        !           266:              * + the TCP header (with checksum set to zero) and data
        !           267:              */
1.1       misho     268:             tcph_p->th_sum = 0;
1.1.1.2 ! misho     269:             if (ip6h_p)
1.1       misho     270:             {
1.1.1.2 ! misho     271:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
1.1       misho     272:             }
                    273:             else
                    274:             {
1.1.1.2 ! misho     275:                 /* 8 = src and dst */
        !           276:                 sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
1.1       misho     277:             }
1.1.1.2 ! misho     278:             sum += ntohs(IPPROTO_TCP + h_len);
        !           279:             sum += libnet_in_cksum((uint16_t *)tcph_p, h_len);
1.1       misho     280:             tcph_p->th_sum = LIBNET_CKSUM_CARRY(sum);
1.1.1.2 ! misho     281: #if 0
        !           282:             printf("tcp sum calculated: %#x/%d h_len %d\n",
        !           283:                     ntohs(tcph_p->th_sum),
        !           284:                     ntohs(tcph_p->th_sum),
        !           285:                     h_len
        !           286:                   );
        !           287: #endif
1.1       misho     288:             break;
                    289:         }
                    290:         case IPPROTO_UDP:
                    291:         {
                    292:             struct libnet_udp_hdr *udph_p =
1.1.1.2 ! misho     293:                 (struct libnet_udp_hdr *)(iphdr + ip_hl);
        !           294: 
        !           295:            h_len = end - (uint8_t*) udph_p; /* ignore h_len, sum the packet we've coalesced */
        !           296: 
        !           297:             CHECK_IP_PAYLOAD_SIZE();
        !           298: 
1.1       misho     299:             udph_p->uh_sum = 0;
1.1.1.2 ! misho     300:             if (ip6h_p)
1.1       misho     301:             {
1.1.1.2 ! misho     302:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
1.1       misho     303:             }
                    304:             else
                    305:             {
1.1.1.2 ! misho     306:                 sum = libnet_in_cksum((uint16_t *)&iph_p->ip_src, 8);
1.1       misho     307:             }
1.1.1.2 ! misho     308:             sum += ntohs(IPPROTO_UDP + h_len);
        !           309:             sum += libnet_in_cksum((uint16_t *)udph_p, h_len);
1.1       misho     310:             udph_p->uh_sum = LIBNET_CKSUM_CARRY(sum);
                    311:             break;
                    312:         }
                    313:         case IPPROTO_ICMP:
                    314:         {
                    315:             struct libnet_icmpv4_hdr *icmph_p =
1.1.1.2 ! misho     316:                 (struct libnet_icmpv4_hdr *)(iphdr + ip_hl);
        !           317: 
        !           318:             h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */
        !           319: 
        !           320:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     321: 
                    322:             icmph_p->icmp_sum = 0;
1.1.1.2 ! misho     323:             /* Hm, is this valid? Is the checksum algorithm for ICMPv6 encapsulated in IPv4
        !           324:              * actually defined?
        !           325:              */
        !           326:             if (ip6h_p)
1.1       misho     327:             {
1.1.1.2 ! misho     328:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
        !           329:                 sum += ntohs(IPPROTO_ICMP6 + h_len);
1.1       misho     330:             }
1.1.1.2 ! misho     331:             sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
        !           332:             icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
        !           333:             break;
        !           334:         }
        !           335:         case IPPROTO_ICMPV6:
        !           336:         {
        !           337:             struct libnet_icmpv6_hdr *icmph_p =
        !           338:                 (struct libnet_icmpv6_hdr *)(iphdr + ip_hl);
        !           339: 
        !           340:             h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */
        !           341: 
        !           342:             CHECK_IP_PAYLOAD_SIZE();
        !           343: 
        !           344:             icmph_p->icmp_sum = 0;
        !           345:             if (ip6h_p)
        !           346:             {
        !           347:                 sum = libnet_in_cksum((uint16_t *)&ip6h_p->ip_src, 32);
        !           348:                 sum += ntohs(IPPROTO_ICMP6 + h_len);
        !           349:             }
        !           350:             sum += libnet_in_cksum((uint16_t *)icmph_p, h_len);
1.1       misho     351:             icmph_p->icmp_sum = LIBNET_CKSUM_CARRY(sum);
                    352:             break;
                    353:         }
                    354:         case IPPROTO_IGMP:
                    355:         {
                    356:             struct libnet_igmp_hdr *igmph_p =
1.1.1.2 ! misho     357:                 (struct libnet_igmp_hdr *)(iphdr + ip_hl);
        !           358: 
        !           359:            h_len = end - (uint8_t*) igmph_p; /* ignore h_len, sum the packet we've coalesced */
        !           360: 
        !           361:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     362: 
                    363:             igmph_p->igmp_sum = 0;
1.1.1.2 ! misho     364:             sum = libnet_in_cksum((uint16_t *)igmph_p, h_len);
1.1       misho     365:             igmph_p->igmp_sum = LIBNET_CKSUM_CARRY(sum);
                    366:             break;
                    367:         }
                    368:        case IPPROTO_GRE:
                    369:        {
                    370:             /* checksum is always at the same place in GRE header
                    371:              * in the multiple RFC version of the protocol ... ouf !!!
                    372:              */
                    373:            struct libnet_gre_hdr *greh_p = 
1.1.1.2 ! misho     374:                (struct libnet_gre_hdr *)(iphdr + ip_hl);
        !           375:            uint16_t fv = ntohs(greh_p->flags_ver);
        !           376: 
        !           377:             CHECK_IP_PAYLOAD_SIZE();
        !           378: 
1.1       misho     379:            if (!(fv & (GRE_CSUM|GRE_ROUTING | GRE_VERSION_0)) ||
                    380:                 !(fv & (GRE_CSUM|GRE_VERSION_1)))
                    381:            {
                    382:                snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    383:                 "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )\n",  __func__, fv);
                    384:                return (-1);
                    385:            }
1.1.1.2 ! misho     386:            sum = libnet_in_cksum((uint16_t *)greh_p, h_len);
1.1       misho     387:            greh_p->gre_sum = LIBNET_CKSUM_CARRY(sum);
                    388:            break;
                    389:        }
                    390:         case IPPROTO_OSPF:
                    391:         {
                    392:             struct libnet_ospf_hdr *oh_p =
1.1.1.2 ! misho     393:                 (struct libnet_ospf_hdr *)(iphdr + ip_hl);
        !           394: 
        !           395:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     396: 
                    397:             oh_p->ospf_sum = 0;
1.1.1.2 ! misho     398:             sum += libnet_in_cksum((uint16_t *)oh_p, h_len);
1.1       misho     399:             oh_p->ospf_sum = LIBNET_CKSUM_CARRY(sum);
                    400:             break;
                    401:         }
                    402:         case IPPROTO_OSPF_LSA:
                    403:         {
                    404:             struct libnet_ospf_hdr *oh_p =
1.1.1.2 ! misho     405:                 (struct libnet_ospf_hdr *)(iphdr + ip_hl);
1.1       misho     406:             struct libnet_lsa_hdr *lsa_p =
1.1.1.2 ! misho     407:                 (struct libnet_lsa_hdr *)(iphdr + 
1.1       misho     408:                 ip_hl + oh_p->ospf_len);
                    409: 
1.1.1.2 ! misho     410:             /* FIXME need additional length check, to account for ospf_len */
1.1       misho     411:             lsa_p->lsa_sum = 0;
1.1.1.2 ! misho     412:             sum += libnet_in_cksum((uint16_t *)lsa_p, h_len);
1.1       misho     413:             lsa_p->lsa_sum = LIBNET_CKSUM_CARRY(sum);
                    414:             break;
                    415: #if 0
                    416:             /*
                    417:              *  Reworked fletcher checksum taken from RFC 1008.
                    418:              */
                    419:             int c0, c1;
                    420:             struct libnet_lsa_hdr *lsa_p = (struct libnet_lsa_hdr *)buf;
1.1.1.2 ! misho     421:             uint8_t *p, *p1, *p2, *p3;
1.1       misho     422: 
                    423:             c0 = 0;
                    424:             c1 = 0;
                    425: 
                    426:             lsa_p->lsa_cksum = 0;
                    427: 
                    428:             p = buf;
                    429:             p1 = buf;
                    430:             p3 = buf + len;             /* beginning and end of buf */
                    431: 
                    432:             while (p1 < p3)
                    433:             {
                    434:                 p2 = p1 + LIBNET_MODX;
                    435:                 if (p2 > p3)
                    436:                 {
                    437:                     p2 = p3;
                    438:                 }
                    439:   
                    440:                 for (p = p1; p < p2; p++)
                    441:                 {
                    442:                     c0 += (*p);
                    443:                     c1 += c0;
                    444:                 }
                    445: 
                    446:                 c0 %= 255;
                    447:                 c1 %= 255;      /* modular 255 */
                    448:  
                    449:                 p1 = p2;
                    450:             }
                    451: 
                    452: #if AWR_PLEASE_REWORK_THIS
                    453:             lsa_p->lsa_cksum[0] = (((len - 17) * c0 - c1) % 255);
                    454:             if (lsa_p->lsa_cksum[0] <= 0)
                    455:             {
                    456:                 lsa_p->lsa_cksum[0] += 255;
                    457:             }
                    458: 
                    459:             lsa_p->lsa_cksum[1] = (510 - c0 - lsa_p->lsa_cksum[0]);
                    460:             if (lsa_p->lsa_cksum[1] > 255)
                    461:             {
                    462:                 lsa_p->lsa_cksum[1] -= 255;
                    463:             }
                    464: #endif
                    465:             break;
                    466: #endif
                    467:         }
                    468:         case IPPROTO_IP:
                    469:         {
1.1.1.2 ! misho     470:             if(!iph_p) {
        !           471:                 /* IPv6 doesn't have a checksum */
        !           472:             } else {
        !           473:                 iph_p->ip_sum = 0;
        !           474:                 sum = libnet_in_cksum((uint16_t *)iph_p, ip_hl);
        !           475:                 iph_p->ip_sum = LIBNET_CKSUM_CARRY(sum);
        !           476:             }
1.1       misho     477:             break;
                    478:         }
                    479:         case IPPROTO_VRRP:
                    480:         {
                    481:             struct libnet_vrrp_hdr *vrrph_p =
1.1.1.2 ! misho     482:                 (struct libnet_vrrp_hdr *)(iphdr + ip_hl);
        !           483:             CHECK_IP_PAYLOAD_SIZE();
1.1       misho     484: 
                    485:             vrrph_p->vrrp_sum = 0;
1.1.1.2 ! misho     486:             sum = libnet_in_cksum((uint16_t *)vrrph_p, h_len);
1.1       misho     487:             vrrph_p->vrrp_sum = LIBNET_CKSUM_CARRY(sum);
                    488:             break;
                    489:         }
                    490:         case LIBNET_PROTO_CDP:
                    491:         {   /* XXX - Broken: how can we easily get the entire packet size? */
1.1.1.2 ! misho     492:            /* FIXME you can't, checksumming non-IP protocols was not supported by libnet */
1.1       misho     493:             struct libnet_cdp_hdr *cdph_p =
1.1.1.2 ! misho     494:                 (struct libnet_cdp_hdr *)iphdr;
        !           495: 
        !           496:             if((iphdr+h_len) > end)
        !           497:             {
        !           498:                 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
        !           499:                         "%s(): cdp payload not inside packet\n", __func__);
        !           500:                 return -1;
        !           501:             }
1.1       misho     502: 
                    503:             cdph_p->cdp_sum = 0;
1.1.1.2 ! misho     504:             sum = libnet_in_cksum((uint16_t *)cdph_p, h_len);
1.1       misho     505:             cdph_p->cdp_sum = LIBNET_CKSUM_CARRY(sum);
                    506:             break;
                    507:         }
                    508:         case LIBNET_PROTO_ISL:
                    509:         {
1.1.1.2 ! misho     510: #if 0
        !           511:             struct libnet_isl_hdr *islh_p =
        !           512:                 (struct libnet_isl_hdr *)buf;
        !           513: #endif
1.1       misho     514:             /*
                    515:              *  Need to compute 4 byte CRC for the ethernet frame and for
                    516:              *  the ISL frame itself.  Use the libnet_crc function.
                    517:              */
                    518:         }
                    519:         default:
                    520:         {
                    521:             snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
1.1.1.2 ! misho     522:                 "%s(): unsupported protocol %d\n", __func__, protocol);
1.1       misho     523:             return (-1);
                    524:         }
                    525:     }
                    526:     return (1);
                    527: }
                    528: 
                    529: 
1.1.1.2 ! misho     530: uint16_t
        !           531: libnet_ip_check(uint16_t *addr, int len)
1.1       misho     532: {
                    533:     int sum;
                    534: 
                    535:     sum = libnet_in_cksum(addr, len);
                    536:     return (LIBNET_CKSUM_CARRY(sum));
                    537: }
                    538: 
                    539: /* EOF */

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