"Fossies" - the Fresh Open Source Software Archive

Member "isic-0.07/isic6.c" (16 Dec 2006, 11741 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 "isic6.c" see the Fossies "Dox" file reference documentation.

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