Annotation of embedaddon/libnet/sample/gre.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  *
        !             3:  *  libnet 1.1
        !             4:  *  Build a GRE packet
        !             5:  *  To view: tcpdump -s 0 -n -X -vvv proto gre
        !             6:  *
        !             7:  *  Copyright (c) 2003 Frédéric Raynal <pappy@security-labs.org>
        !             8:  *  All rights reserved.
        !             9:  *
        !            10:  *
        !            11:  *  KNOWN BUG
        !            12:  *    the encapsulated headers have wrong checksums. I guess this is due to
        !            13:  *    the one pass libnet_pblock_coalesce() which is really to complicated :(
        !            14:  *
        !            15:  *
        !            16:  *  Default packet:
        !            17:  *   # ./gre -d 1.2.3.4                
        !            18:  *   libnet 1.1 packet shaping: GRE 1701 [link]
        !            19:  *   Wrote 78 byte GRE packet; check the wire.
        !            20:  *
        !            21:  *   18:58:12.112157 192.168.1.2 > 1.2.3.4: gre 198.35.123.50.1234 > 103.69.139.107.53: S [bad tcp cksum 698a!] 16843009:16843009(0) win 32767 (ttl 64, id 242, len 40, bad cksum 0!) (ttl 255, id 255, len 64)
        !            22:  *   0x0000   4500 0040 00ff 0000 ff2f f4df c0a8 0102        E..@...../......
        !            23:  *   0x0010   0102 0304 0000 0800 4500 0028 00f2 0000        ........E..(....
        !            24:  *   0x0020   4006 0000 c623 7b32 6745 8b6b 04d2 0035        @....#{2gE.k...5
        !            25:  *   0x0030   0101 0101 0202 0202 5002 7fff 6666 0000        ........P...ff..
        !            26:  *
        !            27:  *  Packet with a computed checksum 
        !            28:  *   # ./gre -d 1.2.3.4 -c 0
        !            29:  *   libnet 1.1 packet shaping: GRE 1701 [link]
        !            30:  *   Wrote 82 byte GRE packet; check the wire.
        !            31:  *   
        !            32:  *   18:58:22.587513 192.168.1.2 > 1.2.3.4: gre [Cv0] C:7c62 198.35.123.50.1234 > 103.69.139.107.53: S [bad tcp cksum 698a!] 16843009:16843009(0) win 32767 (ttl 64, id 242, len 40, bad cksum 0!) (ttl 255, id 255, len 68)
        !            33:  *   0x0000   4500 0044 00ff 0000 ff2f f4db c0a8 0102        E..D...../......
        !            34:  *   0x0010   0102 0304 8000 0800 7c62 0000 4500 0028        ........|b..E..(
        !            35:  *   0x0020   00f2 0000 4006 0000 c623 7b32 6745 8b6b        ....@....#{2gE.k
        !            36:  *   0x0030   04d2 0035 0101 0101 0202 0202 5002 7fff        ...5........P...
        !            37:  *   0x0040   6666 0000                                      ff..
        !            38:  *
        !            39:  *
        !            40:  *  Packet with a forced checksum 
        !            41:  *   # ./gre -d 1.2.3.4 -c 6666
        !            42:  *   libnet 1.1 packet shaping: GRE 1701 [link]
        !            43:  *   Wrote 68 byte GRE packet; check the wire.
        !            44:  *   
        !            45:  *   19:04:12.108080 192.168.1.2 > 1.2.3.4: gre [Cv0] C:1a0a 198.35.123.50.1234 > 103.69.139.107.53: S [bad tcp cksum 698a!] 16843009:16843009(0) win 32767 (ttl 64, id 242, len 40, bad cksum 0!) (ttl 255, id 255, len 68)
        !            46:  *   0x0000   4500 0044 00ff 0000 ff2f f4db c0a8 0102        E..D...../......
        !            47:  *   0x0010   0102 0304 8000 0800 1a0a 0000 4500 0028        ............E..(
        !            48:  *   0x0020   00f2 0000 4006 0000 c623 7b32 6745 8b6b        ....@....#{2gE.k
        !            49:  *   0x0030   04d2 0035 0101 0101 0202 0202 5002 7fff        ...5........P...
        !            50:  *   0x0040   6666 0000                                      ff..
        !            51:  *
        !            52:  *
        !            53:  * 
        !            54:  *
        !            55:  * Redistribution and use in source and binary forms, with or without
        !            56:  * modification, are permitted provided that the following conditions
        !            57:  * are met:
        !            58:  * 1. Redistributions of source code must retain the above copyright
        !            59:  *    notice, this list of conditions and the following disclaimer.
        !            60:  * 2. Redistributions in binary form must reproduce the above copyright
        !            61:  *    notice, this list of conditions and the following disclaimer in the
        !            62:  *    documentation and/or other materials provided with the distribution.
        !            63:  *
        !            64:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !            65:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            66:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            67:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            68:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            69:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            70:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            71:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            72:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            73:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            74:  * SUCH DAMAGE.
        !            75:  *
        !            76:  */
        !            77: 
        !            78: #if (HAVE_CONFIG_H)
        !            79: #include "../include/config.h"
        !            80: #endif
        !            81: #include "./libnet_test.h"
        !            82: 
        !            83: 
        !            84: void
        !            85: usage(char *prog)
        !            86: {
        !            87:     fprintf(stderr, "Usage: %s\n", prog);
        !            88:     fprintf(stderr, "\t IP options:  -d <dst ip> [-s src ip]\n");
        !            89:     fprintf(stderr, "\t GRE options: [-v] set RFC 2637 mode (PPP in GRE) (default is RFC 1701 for IP in GRE)\n");
        !            90:     fprintf(stderr, "\t\t RFC 1701 options (IP in GRE):\n");
        !            91:     fprintf(stderr, "\t\t   [-c sum]  [-r routing] [-k key] [-n seqnum]\n");
        !            92:     fprintf(stderr, "\t\t   IP in GRE options: [-S src ip]  [-D dst ip]\n");
        !            93:     fprintf(stderr, "\t\t RFC 2637 options (PPP in GRE):\n");
        !            94:     fprintf(stderr, "\t\t   [-a ack]\n");
        !            95:     
        !            96:     exit(1);
        !            97: }
        !            98: 
        !            99: /*
        !           100:  *                ---------------------------------
        !           101:  *                |       Delivery Header         |
        !           102:  *                ---------------------------------
        !           103:  *                |       GRE Header              |
        !           104:  *               ---------------------------------
        !           105:  *                |       Payload packet          |
        !           106:  *                ---------------------------------
        !           107:  */
        !           108: int
        !           109: main(int argc, char *argv[])
        !           110: {
        !           111:     char c;
        !           112:     libnet_t *l;
        !           113:     char errbuf[LIBNET_ERRBUF_SIZE];
        !           114:     u_long src_ip = 0, dst_ip = 0, gre_src_ip = 0, gre_dst_ip = 0;
        !           115:     u_short checksum = 0, offset = 0;
        !           116:     u_char *routing = NULL;
        !           117:     u_long key = 0, seq = 0;
        !           118:     u_short gre_flags = 0;
        !           119:     u_long len;
        !           120:     u_long size = 0;
        !           121:     libnet_ptag_t t;
        !           122: 
        !           123:     printf("libnet 1.1 packet shaping: GRE [link]\n");
        !           124:     
        !           125:     /*
        !           126:      *  Initialize the library.  Root priviledges are required.
        !           127:      */
        !           128:     l = libnet_init(
        !           129:             LIBNET_LINK,                            /* injection type */
        !           130:             NULL,                                   /* network interface */
        !           131:             errbuf);                                /* error buffer */
        !           132:   
        !           133:     if (!l)
        !           134:     {
        !           135:         fprintf(stderr, "libnet_init: %s", errbuf);
        !           136:         exit(EXIT_FAILURE);
        !           137:     }
        !           138: 
        !           139:     /*
        !           140:      * parse options
        !           141:      */
        !           142:     while ((c = getopt(argc, argv, "d:s:D:S:c:r:k:n:va:")) != EOF)
        !           143:     {
        !           144:         switch (c)
        !           145:         {
        !           146:            
        !           147:             case 'd':
        !           148:                 if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
        !           149:                 {
        !           150:                     fprintf(stderr, "Bad destination IP address: %s\n", optarg);
        !           151:                     exit(EXIT_FAILURE);
        !           152:                 }
        !           153:                 break;
        !           154:             case 's':
        !           155:                 if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
        !           156:                 {
        !           157:                     fprintf(stderr, "Bad source IP address: %s\n", optarg);
        !           158:                     exit(EXIT_FAILURE);
        !           159:                 }
        !           160:                 break;
        !           161:             case 'D':
        !           162:                 if ((gre_dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
        !           163:                 {
        !           164:                     fprintf(stderr, "Bad destination IP address (GRE): %s\n", optarg);
        !           165:                     exit(EXIT_FAILURE);
        !           166:                 }
        !           167:                 break;
        !           168:             case 'S':
        !           169:                 if ((gre_src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
        !           170:                 {
        !           171:                     fprintf(stderr, "Bad source IP address (GRE): %s\n", optarg);
        !           172:                     exit(EXIT_FAILURE);
        !           173:                 }
        !           174:                 break;
        !           175:            case 'c':
        !           176:                checksum = atoi(optarg);
        !           177:                gre_flags|=GRE_CSUM;
        !           178:                 break;
        !           179:            case 'r':
        !           180:                routing = optarg;
        !           181:                gre_flags|=GRE_ROUTING;
        !           182:                 break;
        !           183:            case 'k':
        !           184:                key = atoi(optarg);
        !           185:                gre_flags|=GRE_KEY;
        !           186:                 break;
        !           187:            case 'n':
        !           188:                seq = atoi(optarg);
        !           189:                gre_flags|=GRE_SEQ;
        !           190:                 break;
        !           191:            case 'v':
        !           192:                gre_flags|=(GRE_VERSION_1|GRE_KEY);
        !           193:                break;
        !           194:            case 'a':
        !           195:                if (! (gre_flags & GRE_VERSION_1))
        !           196:                    usage(argv[0]);
        !           197:                seq = atoi(optarg);    /* seq in v0 is ack in v1 */
        !           198:                gre_flags|=GRE_ACK;
        !           199:                break;
        !           200:             default:
        !           201:                 exit(EXIT_FAILURE);
        !           202:         }
        !           203:     }
        !           204: 
        !           205:     /*
        !           206:      * check options 
        !           207:      */
        !           208:     if (!dst_ip)
        !           209:     {
        !           210:        usage(argv[0]);
        !           211:     }
        !           212: 
        !           213:     if (!src_ip)
        !           214:     {
        !           215:        src_ip = libnet_get_ipaddr4(l);
        !           216:     }
        !           217: 
        !           218:     if (!gre_dst_ip)
        !           219:     {
        !           220:        gre_dst_ip = libnet_get_prand(LIBNET_PRu32);
        !           221:     }
        !           222: 
        !           223:     if (!gre_src_ip)
        !           224:     {
        !           225:        gre_src_ip = libnet_get_prand(LIBNET_PRu32);
        !           226:     }
        !           227: 
        !           228: 
        !           229:     if ( (gre_flags & GRE_VERSION_MASK) == 0)
        !           230:     {
        !           231:        /*
        !           232:         * Build a TCP/IP packet embedded in GRE message
        !           233:         */
        !           234:        size = LIBNET_TCP_H;
        !           235:        t = libnet_build_tcp(
        !           236:            1234,                                       /* source port */
        !           237:            53,                                         /* destination port */
        !           238:            0x01010101,                                 /* sequence number */
        !           239:            0x02020202,                                 /* acknowledgement num */
        !           240:            TH_SYN,                                     /* control flags */
        !           241:            32767,                                      /* window size */
        !           242:            0,                                          /* checksum */
        !           243:            0,                                          /* urgent pointer */
        !           244:            size,                                       /* TCP packet size */
        !           245:            NULL,                                       /* payload */
        !           246:            0,                                          /* payload size */
        !           247:            l,                                          /* libnet handle */
        !           248:            0);                                         /* libnet id */
        !           249:        if (t == -1)
        !           250:        {
        !           251:            fprintf(stderr, "Can't build TCP header (GRE): %s\n", libnet_geterror(l));
        !           252:            goto bad;
        !           253:        }
        !           254:        
        !           255:        size += LIBNET_IPV4_H;
        !           256:        t = libnet_build_ipv4(
        !           257:            size,                                       /* length */
        !           258:            0,                                          /* TOS */
        !           259:            242,                                        /* IP ID */
        !           260:            0,                                          /* IP Frag */
        !           261:            64,                                         /* TTL */
        !           262:            IPPROTO_TCP,                                /* protocol */
        !           263:            0,                                          /* checksum */
        !           264:            gre_src_ip,                                 /* source IP */
        !           265:            gre_dst_ip,                                 /* destination IP */
        !           266:            NULL,                                       /* payload */
        !           267:            0,                                          /* payload size */
        !           268:            l,                                          /* libnet handle */
        !           269:            0);                                         /* libnet id */
        !           270:        if (t == -1)
        !           271:        {
        !           272:            fprintf(stderr, "Can't build IP header (GRE): %s\n", libnet_geterror(l));
        !           273:            goto bad;
        !           274:        } 
        !           275:     }
        !           276: 
        !           277:     if ( (gre_flags & GRE_VERSION_MASK) == 1)
        !           278:     {
        !           279:        offset = libnet_get_prand(LIBNET_PRu16);
        !           280:        if (~gre_flags & GRE_ACK)
        !           281:        {
        !           282:            u_char ppp[4] = "\x00\x01"; /* PPP padding */
        !           283:            checksum = 2; /* checksum is in fact payload_s in PPP/GRE (v1) */
        !           284:            size = 2;
        !           285:            gre_flags|=GRE_SEQ;
        !           286:            key = libnet_get_prand(LIBNET_PRu32);
        !           287: 
        !           288:            /*
        !           289:             * Build a PPP packet embedded in GRE message
        !           290:             */
        !           291:            t = libnet_build_data(
        !           292:                ppp,
        !           293:                checksum,
        !           294:                l, 
        !           295:                0
        !           296:            );
        !           297:            if (t == -1)
        !           298:            {
        !           299:                fprintf(stderr, "Can't build PPP header (GRE): %s\n", libnet_geterror(l));
        !           300:                goto bad;
        !           301:            }
        !           302:        }
        !           303:        gre_flags&=~(GRE_CSUM|GRE_ROUTING);
        !           304:     }
        !           305: 
        !           306:     /*
        !           307:      * Build the GRE message
        !           308:      */
        !           309:     if (gre_flags & GRE_ROUTING)
        !           310:     {
        !           311:        /* as packet are stacked, start by the last one, ie null sre */
        !           312:        size += LIBNET_GRE_SRE_H;
        !           313:        t = libnet_build_gre_last_sre(l, 0);
        !           314:        if (t == -1)
        !           315:        {
        !           316:            fprintf(stderr, "Can't build GRE last SRE header: %s\n", libnet_geterror(l));
        !           317:            goto bad;
        !           318:        }
        !           319:        size += LIBNET_GRE_SRE_H + strlen(routing);
        !           320:        t = libnet_build_gre_sre(
        !           321:            GRE_IP,                                 /* address family */
        !           322:            0,                                      /* offset */
        !           323:            strlen(routing),                        /* routing length */
        !           324:            routing,                                /* routing info */
        !           325:            NULL,                                   /* payload */
        !           326:            0,                                      /* payload size */
        !           327:            l,                                      /* libnet handle */
        !           328:            0);                                     /* libnet id */
        !           329:        if (t == -1)
        !           330:        {
        !           331:            fprintf(stderr, "Can't build GRE last SRE header: %s\n", libnet_geterror(l));
        !           332:            goto bad;
        !           333:        }
        !           334:     }
        !           335: 
        !           336:     len = libnet_getgre_length(gre_flags);
        !           337:     size += len;
        !           338:     t = libnet_build_gre(
        !           339:         gre_flags,                                  /* flags & version */
        !           340:         (gre_flags & GRE_VERSION_1 ? GRE_PPP : GRE_IP), /* type */
        !           341:         checksum,                                   /* v0: checksum / v1: payload_s */
        !           342:         offset,                                     /* v0: offset   / v1: callID    */
        !           343:         key,                                        /* v0: key      / v1: seq bum   */
        !           344:         seq,                                        /* v0: seq num  / v1: ack       */
        !           345:        size,                                       /* length */
        !           346:         NULL,                                       /* payload */
        !           347:         0,                                          /* payload size */
        !           348:         l,                                          /* libnet handle */
        !           349:         0);                                         /* libnet id */
        !           350:     if (t == -1)
        !           351:     {
        !           352:         fprintf(stderr, "Can't build GRE header: %s\n", libnet_geterror(l));
        !           353:         goto bad;
        !           354:     }
        !           355: 
        !           356:     
        !           357:     /*
        !           358:      * Build the "real" IP header
        !           359:      */
        !           360:     size+=LIBNET_IPV4_H;
        !           361:     t = libnet_build_ipv4(
        !           362:         size,                                       /* length */
        !           363:         0,                                          /* TOS */
        !           364:         255,                                        /* IP ID */
        !           365:         0,                                          /* IP Frag */
        !           366:         255,                                        /* TTL */
        !           367:         IPPROTO_GRE,                                /* protocol */
        !           368:         0,                                          /* checksum */
        !           369:         src_ip,                                     /* source IP */
        !           370:         dst_ip,                                     /* destination IP */
        !           371:         NULL,                                       /* payload */
        !           372:         0,                                          /* payload size */
        !           373:         l,                                          /* libnet handle */
        !           374:         0);                                         /* libnet id */
        !           375:     if (t == -1)
        !           376:     {
        !           377:         fprintf(stderr, "Can't build IP header (GRE): %s\n", libnet_geterror(l));
        !           378:         goto bad;
        !           379:     } 
        !           380: 
        !           381:     t = libnet_autobuild_ethernet(
        !           382:             "11:11:11:11:11:11",                                    /* ethernet destination */
        !           383:             ETHERTYPE_IP,                          /* protocol type */
        !           384:             l);                                     /* libnet handle */
        !           385:     if (t == -1)
        !           386:     {
        !           387:         fprintf(stderr, "Can't build ethernet header: %s\n",
        !           388:                 libnet_geterror(l));
        !           389:         goto bad;
        !           390:     }
        !           391:     /*
        !           392:      *  Write it to the wire.
        !           393:      */
        !           394: 
        !           395:     c = libnet_write(l);
        !           396:     if (c == -1)
        !           397:     {
        !           398:         fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
        !           399:         goto bad;
        !           400:     }
        !           401:     else
        !           402:     {
        !           403:         fprintf(stderr, "Wrote %d byte GRE packet; check the wire.\n", c);
        !           404:     }
        !           405:     libnet_destroy(l);
        !           406:     return (EXIT_SUCCESS);
        !           407: bad:
        !           408:     libnet_destroy(l);
        !           409:     return (EXIT_FAILURE); 
        !           410: }

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