Annotation of embedaddon/libnet/src/libnet_build_icmp.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *  $Id: libnet_build_icmp.c,v 1.16 2004/03/29 17:24:34 mike Exp $
                      3:  *
                      4:  *  libnet
                      5:  *  libnet_build_icmp.c - ICMP packet assemblers
                      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
                     41: 
                     42: /* some common cruft for completing ICMP error packets */
                     43: #define LIBNET_BUILD_ICMP_ERR_FINISH(len)                                    \
                     44: do                                                                           \
                     45: {                                                                            \
                     46:     n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, len);              \
                     47:     if (n == -1)                                                             \
                     48:     {                                                                        \
                     49:         goto bad;                                                            \
                     50:     }                                                                        \
                     51:                                                                              \
                     52:     if ((payload && !payload_s) || (!payload && payload_s))                  \
                     53:     {                                                                        \
                     54:         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,                             \
                     55:                 "%s(): payload inconsistency\n", __func__);                  \
                     56:         goto bad;                                                            \
                     57:     }                                                                        \
                     58:                                                                              \
                     59:     if (payload && payload_s)                                                \
                     60:     {                                                                        \
                     61:         n = libnet_pblock_append(l, p, payload, payload_s);                  \
                     62:         if (n == -1)                                                         \
                     63:         {                                                                    \
                     64:             goto bad;                                                        \
                     65:         }                                                                    \
                     66:     }                                                                        \
                     67:                                                                              \
                     68:     if (sum == 0)                                                            \
                     69:     {                                                                        \
                     70:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);                \
                     71:     }                                                                        \
                     72: } while (0)
                     73: 
                     74: libnet_ptag_t
                     75: libnet_build_icmpv4_echo(u_int8_t type, u_int8_t code, u_int16_t sum,
                     76: u_int16_t id, u_int16_t seq, u_int8_t *payload, u_int32_t payload_s,
                     77: libnet_t *l, libnet_ptag_t ptag) 
                     78: {
                     79:     u_int32_t n, h;
                     80:     libnet_pblock_t *p;
                     81:     struct libnet_icmpv4_hdr icmp_hdr;
                     82: 
                     83:     if (l == NULL)
                     84:     { 
                     85:         return (-1);
                     86:     } 
                     87: 
                     88:     n = LIBNET_ICMPV4_ECHO_H + payload_s;        /* size of memory block */
                     89:     h = LIBNET_ICMPV4_ECHO_H + payload_s;        /* hl for checksum */
                     90: 
                     91:     /*
                     92:      *  Find the existing protocol block if a ptag is specified, or create
                     93:      *  a new one.
                     94:      */
                     95:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_ECHO_H);
                     96:     if (p == NULL)
                     97:     {
                     98:         return (-1);
                     99:     }
                    100: 
                    101:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    102:     icmp_hdr.icmp_type = type;          /* packet type */
                    103:     icmp_hdr.icmp_code = code;          /* packet code */
                    104:     icmp_hdr.icmp_sum  = (sum ? htons(sum) : 0);  /* checksum */
                    105:     icmp_hdr.icmp_id   = htons(id);            /* packet id */
                    106:     icmp_hdr.icmp_seq  = htons(seq);           /* packet seq */
                    107: 
                    108:     n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV4_ECHO_H);
                    109:     if (n == -1)
                    110:     {
                    111:         goto bad;
                    112:     }
                    113: 
                    114:     if ((payload && !payload_s) || (!payload && payload_s))
                    115:     {
                    116:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    117:                  "%s(): payload inconsistency\n", __func__);
                    118:         goto bad;
                    119:     }
                    120:  
                    121:     if (payload && payload_s)
                    122:     {
                    123:         n = libnet_pblock_append(l, p, payload, payload_s);
                    124:         if (n == -1)
                    125:         {
                    126:             goto bad;
                    127:         }
                    128:     }
                    129:  
                    130:     if (sum == 0)
                    131:     {
                    132:         /*
                    133:          *  If checksum is zero, by default libnet will compute a checksum
                    134:          *  for the user.  The programmer can override this by calling
                    135:          *  libnet_toggle_checksum(l, ptag, 1);
                    136:          */
                    137:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
                    138:     }
                    139:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
                    140:             LIBNET_PBLOCK_ICMPV4_ECHO_H));
                    141: bad:
                    142:     libnet_pblock_delete(l, p);   
                    143:     return (-1);
                    144: }
                    145: 
                    146: libnet_ptag_t
                    147: libnet_build_icmpv4_mask(u_int8_t type, u_int8_t code, u_int16_t sum,
                    148: u_int16_t id, u_int16_t seq, u_int32_t mask, u_int8_t *payload,
                    149: u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
                    150: {
                    151:     u_int32_t n, h;
                    152:     libnet_pblock_t *p;
                    153:     struct libnet_icmpv4_hdr icmp_hdr;
                    154: 
                    155:     if (l == NULL)
                    156:     { 
                    157:         return (-1);
                    158:     } 
                    159: 
                    160:     n = LIBNET_ICMPV4_MASK_H + payload_s;        /* size of memory block */
                    161:     h = LIBNET_ICMPV4_MASK_H + payload_s;        /* hl for checksum */
                    162: 
                    163:     /*
                    164:      *  Find the existing protocol block if a ptag is specified, or create
                    165:      *  a new one.
                    166:      */
                    167:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_MASK_H);
                    168:     if (p == NULL)
                    169:     {
                    170:         return (-1);
                    171:     }
                    172: 
                    173:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    174:     icmp_hdr.icmp_type = type;          /* packet type */
                    175:     icmp_hdr.icmp_code = code;          /* packet code */
                    176:     icmp_hdr.icmp_sum  = (sum ? htons(sum) : 0);  /* checksum */
                    177:     icmp_hdr.icmp_id   = htons(id);     /* packet id */
                    178:     icmp_hdr.icmp_seq  = htons(seq);    /* packet seq */
                    179:     icmp_hdr.icmp_mask = htonl(mask);   /* address mask */
                    180: 
                    181:     n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV4_MASK_H);
                    182:     if (n == -1)
                    183:     {
                    184:         goto bad;
                    185:     }
                    186: 
                    187:     if ((payload && !payload_s) || (!payload && payload_s))
                    188:     {
                    189:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    190:                             "%s(): payload inconsistency\n", __func__);
                    191:         goto bad;
                    192:     }
                    193:  
                    194:     if (payload && payload_s)
                    195:     {
                    196:         n = libnet_pblock_append(l, p, payload, payload_s);
                    197:         if (n == -1)
                    198:         {
                    199:             goto bad;
                    200:         }
                    201:     }
                    202:  
                    203:     if (sum == 0)
                    204:     {
                    205:         /*
                    206:          *  If checksum is zero, by default libnet will compute a checksum
                    207:          *  for the user.  The programmer can override this by calling
                    208:          *  libnet_toggle_checksum(l, ptag, 1);
                    209:          */
                    210:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
                    211:     }
                    212:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
                    213:             LIBNET_PBLOCK_ICMPV4_MASK_H));
                    214: bad:
                    215:     libnet_pblock_delete(l, p);
                    216:     return (-1);
                    217: }
                    218: 
                    219: libnet_ptag_t
                    220: libnet_build_icmpv4_timestamp(u_int8_t type, u_int8_t code, u_int16_t sum,
                    221: u_int16_t id, u_int16_t seq, n_time otime, n_time rtime, n_time ttime,
                    222: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
                    223: {
                    224:     u_int32_t n, h;
                    225:     libnet_pblock_t *p;
                    226:     struct libnet_icmpv4_hdr icmp_hdr;
                    227: 
                    228:     if (l == NULL)
                    229:     { 
                    230:         return (-1);
                    231:     } 
                    232: 
                    233:     n = LIBNET_ICMPV4_TS_H + payload_s;        /* size of memory block */
                    234:     h = LIBNET_ICMPV4_TS_H + payload_s;        /* hl for checksum */
                    235: 
                    236:     /*
                    237:      *  Find the existing protocol block if a ptag is specified, or create
                    238:      *  a new one.
                    239:      */
                    240:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_TS_H);
                    241:     if (p == NULL)
                    242:     {
                    243:         return (-1);
                    244:     }
                    245: 
                    246:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    247:     icmp_hdr.icmp_type  = type;             /* packet type */
                    248:     icmp_hdr.icmp_code  = code;             /* packet code */
                    249:     icmp_hdr.icmp_sum   = (sum ? htons(sum) : 0); /* checksum */
                    250:     icmp_hdr.icmp_id    = htons(id);        /* packet id */
                    251:     icmp_hdr.icmp_seq   = htons(seq);       /* packet seq */
                    252:     icmp_hdr.icmp_otime = htonl(otime);     /* original timestamp */
                    253:     icmp_hdr.icmp_rtime = htonl(rtime);     /* receive timestamp */
                    254:     icmp_hdr.icmp_ttime = htonl(ttime);     /* transmit timestamp */
                    255: 
                    256:     n = libnet_pblock_append(l, p, (u_int8_t *)&icmp_hdr, LIBNET_ICMPV4_TS_H);
                    257:     if (n == -1)
                    258:     {
                    259:         goto bad;
                    260:     }
                    261: 
                    262:     if ((payload && !payload_s) || (!payload && payload_s))
                    263:     {
                    264:          snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                    265:                             "%s(): payload inconsistency\n", __func__);
                    266:         goto bad;
                    267:     }
                    268:  
                    269:     if (payload && payload_s)
                    270:     {
                    271:         n = libnet_pblock_append(l, p, payload, payload_s);
                    272:         if (n == -1)
                    273:         {
                    274:             goto bad;
                    275:         }
                    276:     }
                    277:  
                    278:     if (sum == 0)
                    279:     {
                    280:         /*
                    281:          *  If checksum is zero, by default libnet will compute a checksum
                    282:          *  for the user.  The programmer can override this by calling
                    283:          *  libnet_toggle_checksum(l, ptag, 1);
                    284:          */
                    285:         libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
                    286:     }
                    287:     return (ptag ? ptag : libnet_pblock_update(l, p, h, 
                    288:             LIBNET_PBLOCK_ICMPV4_TS_H));
                    289: bad:
                    290:     libnet_pblock_delete(l, p);
                    291:     return (-1);
                    292: }
                    293: 
                    294: libnet_ptag_t
                    295: libnet_build_icmpv4_unreach(u_int8_t type, u_int8_t code, u_int16_t sum,
                    296: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
                    297: {
                    298:     u_int32_t n, h;
                    299:     libnet_pblock_t *p;
                    300:     struct libnet_icmpv4_hdr icmp_hdr;
                    301: 
                    302:     if (l == NULL)
                    303:     { 
                    304:         return (-1);
                    305:     } 
                    306:     n = LIBNET_ICMPV4_UNREACH_H + payload_s;        /* size of memory block */
                    307: 
                    308:     /* 
                    309:      * FREDRAYNAL: as ICMP checksum includes what is embedded in 
                    310:      * the payload, and what is after the ICMP header, we need to include
                    311:      * those 2 sizes.
                    312:      */
                    313:     h = LIBNET_ICMPV4_UNREACH_H + payload_s + l->total_size; 
                    314: 
                    315:     /*
                    316:      *  Find the existing protocol block if a ptag is specified, or create
                    317:      *  a new one.
                    318:      */
                    319:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_UNREACH_H);
                    320:     if (p == NULL)
                    321:     {
                    322:         return (-1);
                    323:     }
                    324: 
                    325:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    326:     icmp_hdr.icmp_type = type;          /* packet type */
                    327:     icmp_hdr.icmp_code = code;          /* packet code */
                    328:     icmp_hdr.icmp_sum  = (sum ? htons(sum) : 0);  /* checksum */
                    329:     icmp_hdr.icmp_id   = 0;             /* must be 0 */
                    330:     icmp_hdr.icmp_seq  = 0;             /* must be 0 */
                    331: 
                    332:     LIBNET_BUILD_ICMP_ERR_FINISH(LIBNET_ICMPV4_UNREACH_H);
                    333: 
                    334:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
                    335:             LIBNET_PBLOCK_ICMPV4_UNREACH_H));
                    336: bad:
                    337:     libnet_pblock_delete(l, p);
                    338:     return (-1);
                    339: }
                    340: 
                    341: libnet_ptag_t
                    342: libnet_build_icmpv4_timeexceed(u_int8_t type, u_int8_t code, u_int16_t sum,
                    343: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
                    344: {
                    345:     u_int32_t n, h;
                    346:     libnet_pblock_t *p;
                    347:     struct libnet_icmpv4_hdr icmp_hdr;
                    348: 
                    349:     if (l == NULL)
                    350:     { 
                    351:         return (-1);
                    352:     } 
                    353: 
                    354:     /* size of memory block */
                    355:     n = LIBNET_ICMPV4_TIMXCEED_H;
                    356:     /* 
                    357:      * FREDRAYNAL: as ICMP checksum includes what is embedded in 
                    358:      * the payload, and what is after the ICMP header, we need to include
                    359:      * those 2 sizes.
                    360:      */
                    361:     h = LIBNET_ICMPV4_TIMXCEED_H + payload_s + l->total_size; 
                    362: 
                    363:     /*
                    364:      *  Find the existing protocol block if a ptag is specified, or create
                    365:      *  a new one.
                    366:      */
                    367:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_TIMXCEED_H);
                    368:     if (p == NULL)
                    369:     {
                    370:         return (-1);
                    371:     }
                    372: 
                    373:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    374:     icmp_hdr.icmp_type = type;          /* packet type */
                    375:     icmp_hdr.icmp_code = code;          /* packet code */
                    376:     icmp_hdr.icmp_sum  = (sum ? htons(sum) : 0);  /* checksum */
                    377:     icmp_hdr.icmp_id   = 0;             /* must be 0 */
                    378:     icmp_hdr.icmp_seq  = 0;             /* must be 0 */
                    379: 
                    380:     LIBNET_BUILD_ICMP_ERR_FINISH(LIBNET_ICMPV4_TIMXCEED_H);
                    381: 
                    382:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
                    383:             LIBNET_PBLOCK_ICMPV4_TIMXCEED_H));
                    384: bad:
                    385:     libnet_pblock_delete(l, p);
                    386:     return (-1);
                    387: }
                    388: 
                    389: libnet_ptag_t
                    390: libnet_build_icmpv4_redirect(u_int8_t type, u_int8_t code, u_int16_t sum,
                    391: u_int32_t gateway, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
                    392: libnet_ptag_t ptag)
                    393: 
                    394: {
                    395:     u_int32_t n, h;
                    396:     libnet_pblock_t *p;
                    397:     struct libnet_icmpv4_hdr icmp_hdr;
                    398: 
                    399:     if (l == NULL)
                    400:     { 
                    401:         return (-1);
                    402:     } 
                    403: 
                    404:     n = LIBNET_ICMPV4_REDIRECT_H;               /* size of memory block */
                    405:     /* 
                    406:      * FREDRAYNAL: as ICMP checksum includes what is embedded in 
                    407:      * the payload, and what is after the ICMP header, we need to include
                    408:      * those 2 sizes.
                    409:      */
                    410:     h = LIBNET_ICMPV4_REDIRECT_H + payload_s + l->total_size; 
                    411: 
                    412:     /*
                    413:      *  Find the existing protocol block if a ptag is specified, or create
                    414:      *  a new one.
                    415:      */
                    416:     p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ICMPV4_REDIRECT_H);
                    417:     if (p == NULL)
                    418:     {
                    419:         return (-1);
                    420:     }
                    421: 
                    422:     memset(&icmp_hdr, 0, sizeof(icmp_hdr));
                    423:     icmp_hdr.icmp_type      = type;             /* packet type */
                    424:     icmp_hdr.icmp_code      = code;             /* packet code */
                    425:     icmp_hdr.icmp_sum       = (sum ? htons(sum) : 0);  /* checksum */
                    426:     icmp_hdr.hun.gateway    = gateway;
                    427: 
                    428:     LIBNET_BUILD_ICMP_ERR_FINISH(LIBNET_ICMPV4_REDIRECT_H);
                    429: 
                    430:     return (ptag ? ptag : libnet_pblock_update(l, p, h,
                    431:             LIBNET_PBLOCK_ICMPV4_REDIRECT_H));
                    432: bad:
                    433:     libnet_pblock_delete(l, p);
                    434:     return (-1);
                    435: }
                    436: 
                    437: /* EOF */

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