"Fossies" - the Fresh Open Source Software Archive

Member "isic-0.07/tcpsic6.c" (16 Dec 2006, 13146 Bytes) of package /linux/privat/old/isic-0.07.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tcpsic6.c" see the Fossies "Dox" file reference documentation.

    1 #include "isic.h"
    2 
    3 /* This is tuned for ethernet sized frames (1500 bytes)
    4  * For user over a modem or frame (or other) you will have to change the
    5  * 'rand() & 0x4ff' line below.  The 0x4ff needs to be less than the size of
    6  * the frame size minus the length of the ip header (20 bytes IIRC) minus the
    7  * length of the TCP header.
    8  */
    9 
   10 
   11 /* Variables shared between main and the signal handler so we can display
   12  * output if ctrl-c'd
   13  */
   14 u_int seed = 0;
   15 u_long acx = 0;
   16 struct timeval starttime;
   17 u_long datapushed = 0;          /* How many bytes we pushed */
   18 
   19 
   20 int
   21 main(int argc, char **argv)
   22 {
   23     int c, frag_flag = 0, dstopt_flag = 0;
   24     u_char *buf = NULL;
   25     u_short *payload = NULL;
   26     u_int payload_s = 0;
   27     int packet_len = 0, dstopt_tlen = 0;
   28     char addrbuf[INET6_ADDRSTRLEN];
   29 
   30     /* libnet variables */
   31     char errbuf[LIBNET_ERRBUF_SIZE];
   32     libnet_t *l;
   33     char *device = NULL;
   34 
   35     /* Packet Variables */
   36     u_int src_addr_flag = 0, dst_addr_flag = 0;
   37     u_char ver, hlim, nxt;
   38     u_int16_t plen;
   39     u_int32_t flow;
   40     struct ip6_hdr *ip6 = NULL;
   41     struct libnet_in6_addr src_addr;
   42     struct libnet_in6_addr dst_addr;
   43 
   44     struct tcphdr *tcp = NULL;
   45     u_short src_prt = 0, dst_prt = 0;
   46 
   47     struct ip6_frag *ip6_fraghdr = NULL; /* IPv6 fragment header */
   48     u_char f6_nxt = 0, f6_rsv = 0;
   49     u_int32_t f6_id = 0;
   50     u_int16_t f6_offlg = 0;
   51 
   52     struct ip6_dest *ip6_dopthdr = NULL; /* IPv6 destination option header */
   53     u_char dstopt_nxt = 0, dstopt_len = 0;
   54         
   55     /* Functionality Variables */
   56     int src_ip_rand = 0, dst_ip_rand = 0;
   57     struct timeval tv, tv2;
   58     float sec;
   59     unsigned int cx = 0;
   60     u_long max_pushed = 10240;      /* 10MB/sec */
   61     u_long num_to_send = 0xffffffff;    /* Send 4billion packets */
   62     u_long skip = 0;            /* Skip how many packets */
   63     int printout = 0;           /* Debugging */
   64     int dst_port_rand = 0;
   65     int src_port_rand = 0;
   66     char *tmp_port = NULL;
   67     u_int repeat = 1;
   68 
   69     /* Defaults */
   70     float FragPct   =   10;
   71     float DstOpts   =   10;
   72     float UrgPct    =   10;
   73     float TCPOptsPct=   10;
   74     float TCPCksm   =   10;
   75 
   76     /* Not crypto strong randomness but we don't really care.  And this  *
   77      * gives us a way to determine the seed while the program is running *
   78      * if we need to repeat the results                  */
   79     seed = getpid();
   80 
   81     /* Initialize libnet context, Root priviledges are required.*/ 
   82     l = libnet_init(
   83             LIBNET_RAW6_ADV,                        /* injection type */
   84             device,                                 /* network interface */
   85             errbuf);                                /* error buffer */
   86 
   87     if (l == NULL) {
   88       fprintf(stderr, "libnet_init() failed: %s", errbuf);
   89       exit( -1 );
   90     }
   91     
   92     while((c = getopt(argc, argv, "hd:s:r:m:k:Dp:F:I:u:T:t:vx:")) != EOF){
   93       switch (c) {
   94        case 'h':
   95         usage(argv[0]);
   96         exit(0);
   97         break;
   98        case 'd':
   99         dst_port_rand = 1;
  100         if ( (tmp_port = index(optarg, ',')) != NULL ) {
  101             *tmp_port++ = '\0';
  102             dst_port_rand = 0;
  103             dst_prt = htons((u_int) atol(tmp_port));
  104         }
  105         if ( strcmp(optarg, "rand") == 0 ) {
  106             printf("Using random destination IP's\n");
  107             dst_addr_flag = 1;  /* Just to pass sanity checks */
  108             dst_ip_rand = 1;
  109             break;
  110         }
  111         dst_addr = libnet_name2addr6(l, optarg, LIBNET_RESOLVE);
  112         if (strncmp((char *)&dst_addr, (char *)&in6addr_error, sizeof(in6addr_error)) == 0) {
  113           fprintf(stderr, "Bad destination IPv6 address!\n");
  114           exit( -1 );
  115         }
  116         dst_addr_flag = 1;
  117         break;
  118        case 's':
  119         src_port_rand = 1;
  120         if ( (tmp_port = index(optarg, ',')) != NULL ) {
  121             *tmp_port++ = '\0';
  122             src_port_rand = 0;
  123             src_prt = htons((u_int) atol(tmp_port));
  124         }
  125         if ( strcmp(optarg, "rand") == 0 ) {
  126             printf("Using random source IP's\n");
  127             src_addr_flag = 1;  /* Just to pass sanity checks */
  128             src_ip_rand = 1;
  129             break;
  130         }
  131         src_addr = libnet_name2addr6(l, optarg, LIBNET_RESOLVE);
  132         if (strncmp((char *)&src_addr, (char *)&in6addr_error, sizeof(in6addr_error)) == 0) {
  133           fprintf(stderr, "Bad source IPv6 address!\n");
  134           exit( -1 );
  135         }
  136         src_addr_flag = 1;
  137         break;
  138        case 'r':
  139         seed = atoi(optarg);
  140         break;
  141        case 'm':
  142         max_pushed = atol(optarg);
  143         break;
  144        case 'k':
  145         skip = atol(optarg);
  146         printf("Will not transmit first %li packets.\n", skip);
  147         break;
  148        case 'D':
  149         printout++;
  150         break;
  151        case 'p':
  152         num_to_send = atoi(optarg);
  153         break;
  154        case 'F':
  155         FragPct = atof(optarg);
  156         break;
  157        case 'I':
  158         DstOpts = atof(optarg);
  159         break;
  160        case 'T':
  161         TCPOptsPct = atof(optarg);
  162         break;
  163        case 'u':
  164         UrgPct = atof(optarg);
  165         break;
  166        case 't':
  167         TCPCksm = atof(optarg);
  168         break;
  169        case 'x':
  170         repeat = atoi(optarg);
  171         break;
  172        case 'v':
  173         printf("Version %s\n", VERSION);
  174         exit(0);
  175        }
  176     }
  177 
  178     if ( !src_addr_flag || !dst_addr_flag ) {
  179         usage(argv[0]);
  180         exit(EXIT_FAILURE);
  181     }
  182 
  183     printf("Compiled against Libnet %s\n", LIBNET_VERSION);
  184     printf("Installing Signal Handlers.\n");
  185     if ( signal(SIGTERM, &sighandler) == SIG_ERR )
  186         printf("Failed to install signal handler for SIGTERM\n");
  187     if ( signal(SIGINT, &sighandler) == SIG_ERR )
  188         printf("Failed to install signal handler for SIGINT\n");
  189     if ( signal(SIGQUIT, &sighandler) == SIG_ERR )
  190         printf("Failed to install signal handler for SIGQUIT\n");
  191 
  192     printf("Seeding with %i\n", seed);
  193     srand(seed);
  194     max_pushed *= 1024;
  195 
  196     if ( (buf = malloc(IP_MAXPACKET)) == NULL ) {
  197         perror("malloc: ");
  198         exit( -1 );
  199     }
  200 
  201 
  202     if ( max_pushed >= 10000000 )
  203         printf("No Maximum traffic limiter\n");
  204     else printf("Maximum traffic rate = %.2f k/s\n", max_pushed/1024.0 );
  205 
  206     if ( src_port_rand )
  207         printf("Using random source ports.\n");
  208     if ( dst_port_rand )
  209         printf("Using random destination ports.\n");
  210 
  211 
  212     printf("Frag'd Pcnt\t= %.0f%%\t", FragPct);
  213     printf("IPv6 Dst Opts\t= %.0f%%\n", DstOpts);
  214     printf("Urg Pcnt\t= %.0f%%\t", UrgPct);
  215     printf("Bad TCP Cksm\t= %.0f%%\t", TCPCksm);
  216     printf("TCP Opts Pcnt\t= %.0f%%\n", TCPOptsPct);
  217     printf("\n");
  218 
  219 
  220     /* Drop them down to floats so we can multiply and not overflow */
  221     FragPct     /= 100;
  222     DstOpts     /= 100;
  223     UrgPct      /= 100;
  224     TCPOptsPct  /= 100;
  225     TCPCksm     /= 100;
  226 
  227     
  228 
  229     /*************
  230     * Main Loop *
  231     *************/
  232     gettimeofday(&tv, NULL);
  233     gettimeofday(&starttime, NULL);
  234     ver = 6;
  235 
  236     for(acx = 0; acx < num_to_send; acx++) {
  237         packet_len = IP6_H;
  238     
  239         hlim    = RAND8;
  240         flow    = RAND32;
  241         nxt = IPPROTO_TCP;
  242         tcp = (struct tcphdr *) (buf + IP6_H); /* for no extension header case */
  243 
  244         if ( src_ip_rand == 1 ) {
  245           (src_addr.__u6_addr.__u6_addr32)[0] = RAND32;
  246           (src_addr.__u6_addr.__u6_addr32)[1] = RAND32;
  247           (src_addr.__u6_addr.__u6_addr32)[2] = RAND32;
  248           (src_addr.__u6_addr.__u6_addr32)[3] = RAND32;
  249         }
  250         if ( dst_ip_rand == 1 ) {
  251           (dst_addr.__u6_addr.__u6_addr32)[0] = RAND32;
  252           (dst_addr.__u6_addr.__u6_addr32)[1] = RAND32;
  253           (dst_addr.__u6_addr.__u6_addr32)[2] = RAND32;
  254           (dst_addr.__u6_addr.__u6_addr32)[3] = RAND32;
  255         }
  256         
  257         if ( rand() <= (RAND_MAX * FragPct) ) {
  258           /* should add fragment header after IPv6 header */
  259           f6_offlg = RAND16;
  260           f6_id    = RAND32;
  261           f6_nxt   = IPPROTO_TCP;
  262           f6_rsv   = RAND8;
  263           nxt = IPPROTO_FRAGMENT;
  264           tcp = (struct tcphdr *) (buf + IP6_H + IP6_FRAGH); /* adjust the pointer */
  265           ip6_fraghdr = (struct ip6_frag *)(buf + IP6_H);
  266           frag_flag = 1;
  267           packet_len += IP6_FRAGH;
  268         }
  269 
  270         if ( rand() <= (RAND_MAX * DstOpts) ) {
  271             /* should add Destination Options header */         
  272             dstopt_len = (int)(9.0*rand()/(RAND_MAX+1.0)); /* maximun 10 x 8 = 80 bytes */
  273             dstopt_nxt = IPPROTO_TCP;
  274             dstopt_flag = 1;
  275             dstopt_tlen = (dstopt_len << 3) + 8;
  276             packet_len += dstopt_tlen;          
  277             if (frag_flag) {
  278                 f6_nxt = IPPROTO_DSTOPTS;
  279                 tcp = (struct tcphdr *) (buf + IP6_H + IP6_FRAGH + dstopt_tlen);
  280                 ip6_dopthdr = (struct ip6_dest *)(buf + IP6_H + IP6_FRAGH);
  281             }
  282             else {
  283                 nxt = IPPROTO_DSTOPTS;
  284                 tcp = (struct tcphdr *) (buf + IP6_H + dstopt_tlen);
  285                 ip6_dopthdr = (struct ip6_dest *)(buf + IP6_H);
  286             }
  287         }
  288 
  289         payload_s = rand() & 0x4ff;            /* length of 1279 */
  290         packet_len += payload_s;
  291 
  292         if ( rand() <= (RAND_MAX * TCPOptsPct) )
  293             tcp->th_off = rand() & 0xf;
  294         else    tcp->th_off = 5;
  295         packet_len += (tcp->th_off) << 2;
  296         plen = packet_len - IP6_H;      
  297         /*
  298         *  Build the IPv6 header
  299         */
  300         ip6 = (struct ip6_hdr *) buf;
  301         ip6->ip6_flow   = htonl(flow);
  302         ip6->ip6_vfc    = ver<<4;              /* version 6 */
  303         ip6->ip6_plen   = htons(plen);         /* payload length */
  304         ip6->ip6_nxt    = nxt;                 /* next header value */
  305         ip6->ip6_hlim   = hlim;                /* hop limit */
  306         memcpy(&(ip6->ip6_src), &src_addr, sizeof(struct in6_addr));
  307         memcpy(&(ip6->ip6_dst), &dst_addr, sizeof(struct in6_addr));
  308 
  309         if (frag_flag) {
  310           /* Build fragment header */
  311           ip6_fraghdr->ip6f_nxt      = f6_nxt;   /* next header value */
  312           ip6_fraghdr->ip6f_reserved = f6_rsv;   /* reserved field */
  313           ip6_fraghdr->ip6f_offlg    = htons(f6_offlg); /* offset, reserved and flag */
  314           ip6_fraghdr->ip6f_ident    = htonl(f6_id);    /* fragment id */
  315         }
  316 
  317         if (dstopt_flag) {
  318             /* Build destination options header */
  319             ip6_dopthdr->ip6d_nxt = dstopt_nxt;
  320             ip6_dopthdr->ip6d_len = dstopt_len; /* remember: it is 8 bytes by unit */
  321             payload = (ushort *)(ip6_dopthdr);
  322             payload[1] = RAND16;   /* set the 3rd and 4th bytes */
  323             payload[2] = RAND16;   /* set the 5-6th bytes */
  324             payload[3] = RAND16;   /* set the 7-8th bytes */
  325             /* set the remaining in the header */
  326             for (cx = 0; cx < (u_int)(dstopt_len << 2); cx+=1) {
  327                 payload[cx+4] = RAND16;
  328             }
  329         }
  330     
  331         /* Build TCP header */
  332         if ( src_port_rand == 1 )
  333             tcp->th_sport = RAND16;
  334         else    tcp->th_sport = src_prt;
  335         if ( dst_port_rand == 1 )
  336             tcp->th_dport = RAND16;
  337         else    tcp->th_dport = dst_prt;
  338 
  339         tcp->th_seq = RAND32;
  340         tcp->th_ack = RAND32;
  341         tcp->th_x2  = rand() & 0xf;     /* 4bit */
  342         tcp->th_flags   = RAND8;
  343         tcp->th_win = RAND16;
  344         tcp->th_sum = 0;
  345         if ( rand() <= (RAND_MAX * UrgPct) ) {
  346             tcp->th_urp = RAND16;
  347             tcp->th_flags |= 0x20; /* set URG bit */
  348         }
  349         else    tcp->th_urp = 0;
  350 
  351         payload = (u_short *)((u_char *) tcp + 20);
  352         for(cx = 0; cx <= (payload_s >> 1); cx+=1)
  353             payload[cx] = RAND16;
  354 
  355         if ( rand() <= (RAND_MAX * TCPCksm) )
  356             tcp->th_sum = RAND16;           
  357         else    libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_TCP, packet_len - IP6_H);
  358         
  359         if ( printout ) {
  360             printf("%s ->",
  361                 inet_ntop(AF_INET6, &src_addr, addrbuf, INET6_ADDRSTRLEN));
  362             printf(" %s ver[%i] plen[%i] nxt[%i] hlim[%i]\n",
  363                 inet_ntop(AF_INET6, &dst_addr, addrbuf, INET6_ADDRSTRLEN), 
  364                               ver & 0xf, plen, nxt, hlim);
  365         }
  366          
  367         if ( skip <= acx ) {
  368             for ( cx = 0; cx < repeat; cx++ ) {
  369                 c = libnet_write_raw_ipv6(l, buf, packet_len);
  370                 if (c != -1)
  371                   datapushed+=c;
  372             }
  373             if ( c < (packet_len) )
  374                 perror("Failed to send packet");
  375         } 
  376 
  377         if ( !(acx % 1000) ) {
  378             if ( acx == 0 )
  379                 continue;
  380             gettimeofday(&tv2, NULL);
  381             sec = (tv2.tv_sec - tv.tv_sec)
  382                   - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  383             printf(" %li @ %.1f pkts/sec and %.1f k/s\n", acx,
  384                 1000/sec, (datapushed / 1024.0) / sec);
  385             datapushed=0;
  386             gettimeofday(&tv, NULL);
  387         }
  388 
  389 
  390         /* Flood protection for low traffic limit only. */
  391         if ( max_pushed < 10000000 ) {
  392             gettimeofday(&tv2, NULL);
  393             sec = (tv2.tv_sec - tv.tv_sec)
  394                     - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  395             if ( (datapushed / sec) >= max_pushed )
  396                 usleep(10); /* 10 should give up our timeslice */
  397         }
  398     }
  399 
  400 
  401     gettimeofday(&tv, NULL);
  402     printf("\nWrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  403         (tv.tv_sec-starttime.tv_sec)
  404         + (tv.tv_usec-starttime.tv_usec) / 1000000.0,
  405         acx / ((tv.tv_sec-starttime.tv_sec)
  406                        + (tv.tv_usec-starttime.tv_usec)/1000000.0) );
  407 
  408     libnet_destroy(l);
  409     free(buf);
  410     return ( 0 );
  411 }
  412 
  413 
  414 void usage(char *name)
  415 {
  416    fprintf(stderr,
  417     "usage: %s [-v] [-D] -s <sourceip>[,port] -d <destination ip>[,port]\n"
  418     "          [-r seed] [-m <max kB/s to generate>]\n"
  419     "          [-p <pkts to generate>] [-k <skip packets>] [-x <repeat times>]\n\n"
  420     "       Percentage Opts: [-F frags] [-I <IPv6 Destination Options>]\n"
  421     "                        [-T <TCP Options>] [-u <urgent data>] [-t <Bad TCP Cksm>]\n\n"
  422     "       [-D] causes packet info to be printed out -- DEBUGGING\n\n"
  423     "       ex: -s 2001:1:2:3:4::1,23  -d 2001:1:2:3:4::2 -I 100\n"
  424     "           will give a 100%% chance of IPv6 Destination ^^^ Options \n"
  425     "       ex: -s 2001:a:b:c:d::1,23  -d 2001:a:b:c:d::2 -p 100 -r 103334\n"
  426     "       ex: -s rand -d rand,1234 -r 23342\n"
  427     "              ^^^^ causes random source addr\n"
  428     "       ex: -s rand -d rand -k 10000 -p 10001 -r 666\n"
  429     "           Will only send the 10001 packet with random seed 666\n"
  430     "           this is especially useful if you suspect that packet is\n"
  431     "           causing a problem with the target stack.\n\n",
  432     ((char *) rindex(name, '/')) == ((char *) NULL)
  433         ? (char *) name
  434         : (char *) rindex(name, '/') + 1);
  435 }
  436 
  437 void sighandler(int sig)
  438 {
  439     struct timeval tv;
  440     gettimeofday(&tv, NULL);
  441 
  442     printf("\n");
  443     printf("Caught signal %i\n", sig);
  444 
  445     printf("Used random seed %i\n", seed);
  446     printf("Wrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  447         (tv.tv_sec - starttime.tv_sec)
  448           + (tv.tv_usec - starttime.tv_usec)/1000000.0,
  449         acx / (( tv.tv_sec - starttime.tv_sec)
  450           + (tv.tv_usec - starttime.tv_usec)/1000000.0)
  451         );
  452 
  453     fflush(stdout);
  454     exit(0);
  455 }