"Fossies" - the Fresh Open Source Software Archive

Member "isic-0.07/tcpsic.c" (16 Dec 2006, 11271 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 "tcpsic.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;
   24     u_char *buf = NULL;
   25     u_short *payload = NULL;
   26     u_int payload_s = 0;
   27     int packet_len = 0;
   28 
   29     struct ip *ip_hdr = NULL;
   30     struct tcphdr *tcp = NULL;
   31     u_short *ip_opts = NULL;
   32 
   33     /* libnet variables */
   34     char errbuf[LIBNET_ERRBUF_SIZE];
   35     libnet_t *l;
   36     char *device = NULL;
   37 
   38     /* Packet Variables */
   39     u_int32_t src_ip = 0, dst_ip = 0;
   40     u_short src_prt = 0, dst_prt = 0;
   41     u_char tos, ttl, ver;
   42     u_int id, frag_off;
   43     u_int ipopt_len;
   44 
   45 
   46     /* Functionality Variables */
   47     int src_ip_rand = 0, dst_ip_rand = 0;
   48     struct timeval tv, tv2;
   49     float sec;
   50     unsigned int cx = 0;
   51     u_long max_pushed = 10240;      /* 10MB/sec */
   52     u_long num_to_send = 0xffffffff;    /* Send 4billion packets */
   53     u_long skip = 0;            /* Skip how many packets */
   54     int printout = 0;           /* Debugging */
   55     int dst_port_rand = 0;
   56     int src_port_rand = 0;
   57     char *tmp_port = NULL;
   58     u_int repeat = 1;
   59 
   60     /* Defaults */
   61     float FragPct   =   10;
   62     float BadIPVer  =   10;
   63     float IPOpts    =   10;
   64     float UrgPct    =   10;
   65     float TCPOptsPct=   10;
   66     float TCPCksm   =   10;
   67 
   68 
   69 
   70     /* Not crypto strong randomness but we don't really care.  And this  *
   71      * gives us a way to determine the seed while the program is running *
   72      * if we need to repeat the results                  */
   73     seed = getpid();
   74 
   75     /* Initialize libnet context, Root priviledges are required.*/ 
   76     l = libnet_init(
   77             LIBNET_RAW4_ADV,                        /* injection type */
   78             device,                                 /* network interface */
   79             errbuf);                                /* error buffer */
   80 
   81     if (l == NULL) {
   82       fprintf(stderr, "libnet_init() failed: %s", errbuf);
   83       exit( -1 );
   84     }
   85     
   86 
   87     while((c = getopt(argc, argv, "hd:s:r:m:k:Dp:V:F:I:u:T:t:vx:")) != EOF){
   88       switch (c) {
   89        case 'h':
   90         usage(argv[0]);
   91         exit(0);
   92         break;
   93        case 'd':
   94         dst_port_rand = 1;
   95         if ( (tmp_port = index(optarg, ',')) != NULL ) {
   96             *tmp_port++ = '\0';
   97             dst_port_rand = 0;
   98             dst_prt = htons((u_int) atol(tmp_port));
   99         }
  100         if ( strcmp(optarg, "rand") == 0 ) {
  101             printf("Using random dest IP's\n");
  102             dst_ip = 1; /* Just to pass sanity checks */
  103             dst_ip_rand = 1;
  104             break;
  105         }
  106         if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == (u_int32_t)-1) {
  107             fprintf(stderr, "Bad dest IP\n");
  108             exit( -1 );
  109         }
  110         break;
  111        case 's':
  112         src_port_rand = 1;
  113         if ( (tmp_port = index(optarg, ',')) != NULL ) {
  114             *tmp_port++ = '\0';
  115             src_port_rand = 0;
  116             src_prt = htons((u_int) atol(tmp_port));
  117         }
  118         if ( strcmp(optarg, "rand") == 0 ) {
  119             printf("Using random source IP's\n");
  120             src_ip = 1; /* Just to pass sanity checks */
  121             src_ip_rand = 1;
  122             break;
  123         }
  124         if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == (u_int32_t)-1) {
  125             fprintf(stderr, "Bad source IP\n");
  126             exit( -1 );
  127         }
  128         break;
  129        case 'r':
  130         seed = atoi(optarg);
  131         break;
  132        case 'm':
  133         max_pushed = atol(optarg);
  134         break;
  135        case 'k':
  136         skip = atol(optarg);
  137         printf("Will not transmit first %li packets.\n", skip);
  138         break;
  139        case 'D':
  140         printout++;
  141         break;
  142        case 'p':
  143         num_to_send = atoi(optarg);
  144         break;
  145        case 'V':
  146         BadIPVer = atof(optarg);
  147         break;
  148        case 'F':
  149         FragPct = atof(optarg);
  150         break;
  151        case 'I':
  152         IPOpts = atof(optarg);
  153         break;
  154        case 'T':
  155         TCPOptsPct = atof(optarg);
  156         break;
  157        case 'u':
  158         UrgPct = atof(optarg);
  159         break;
  160        case 't':
  161         TCPCksm = atof(optarg);
  162         break;
  163        case 'x':
  164         repeat = atoi(optarg);
  165         break;
  166        case 'v':
  167         printf("Version %s\n", VERSION);
  168         exit(0);
  169        }
  170     }
  171 
  172     if ( !src_ip || !dst_ip ) {
  173         usage(argv[0]);
  174         exit(EXIT_FAILURE);
  175     }
  176 
  177     printf("Compiled against Libnet %s\n", LIBNET_VERSION);
  178     printf("Installing Signal Handlers.\n");
  179     if ( signal(SIGTERM, &sighandler) == SIG_ERR )
  180         printf("Failed to install signal handler for SIGTERM\n");
  181     if ( signal(SIGINT, &sighandler) == SIG_ERR )
  182         printf("Failed to install signal handler for SIGINT\n");
  183     if ( signal(SIGQUIT, &sighandler) == SIG_ERR )
  184         printf("Failed to install signal handler for SIGQUIT\n");
  185 
  186     printf("Seeding with %i\n", seed);
  187     srand(seed);
  188     max_pushed *= 1024;
  189 
  190     if ( (buf = malloc(IP_MAXPACKET)) == NULL ) {
  191         perror("malloc: ");
  192         exit( -1 );
  193     }
  194 
  195 
  196     if ( max_pushed >= 10000000 )
  197         printf("No Maximum traffic limiter\n");
  198     else printf("Maximum traffic rate = %.2f k/s\n", max_pushed/1024.0 );
  199 
  200     if ( src_port_rand )
  201         printf("Using random source ports.\n");
  202     if ( dst_port_rand )
  203         printf("Using random destination ports.\n");
  204 
  205     printf("Bad IP Version\t= %.0f%%\t\t", BadIPVer);
  206     printf("IP Opts Pcnt\t= %.0f%%\n", IPOpts);
  207 
  208     printf("Frag'd Pcnt\t= %.0f%%\t\t", FragPct);
  209     printf("Urg Pcnt\t= %.0f%%\n", UrgPct);
  210 
  211     printf("Bad TCP Cksm\t= %.0f%%\t\t", TCPCksm);
  212     printf("TCP Opts Pcnt\t= %.0f%%\n", TCPOptsPct);
  213     printf("\n");
  214 
  215 
  216     /* Drop them down to floats so we can multiply and not overflow */
  217     BadIPVer    /= 100;
  218     FragPct     /= 100;
  219     IPOpts      /= 100;
  220     UrgPct      /= 100;
  221     TCPOptsPct  /= 100;
  222     TCPCksm     /= 100;
  223 
  224     
  225 
  226     /*************
  227     * Main Loop *
  228     *************/
  229     gettimeofday(&tv, NULL);
  230     gettimeofday(&starttime, NULL);
  231 
  232     for(acx = 0; acx < num_to_send; acx++) {
  233         packet_len = IP_H;
  234     
  235         tos = RAND8;
  236         id  = acx & 0xffff;
  237         ttl = RAND8;
  238 
  239 
  240         if ( rand() <= (RAND_MAX * FragPct) )
  241             frag_off = RAND16;
  242         else    frag_off = 0;
  243 
  244         /* We're not going to pad IP Options */
  245         if ( rand() <= (RAND_MAX * IPOpts) ) {
  246             ipopt_len = 10 * (rand() / (float) RAND_MAX);
  247             ipopt_len = ipopt_len << 1;
  248             ip_opts = (u_short *) buf;
  249             packet_len += ipopt_len << 1;
  250 
  251             for ( cx = 0; cx < ipopt_len; cx++ )
  252                 ip_opts[cx] = RAND16;
  253             tcp = (struct tcphdr *) (buf + IP_H + (ipopt_len << 1));
  254             ipopt_len = ipopt_len >> 1;
  255         } else {
  256             ipopt_len = 0;
  257             tcp = (struct tcphdr *) (buf + IP_H);
  258         }
  259 
  260 
  261         if ( src_ip_rand == 1 )
  262           src_ip = RAND32;
  263         if ( dst_ip_rand == 1 )
  264           dst_ip = RAND32;
  265 
  266         if ( rand() <= (RAND_MAX * BadIPVer ) )
  267             ver = rand() & 0xf;
  268         else    ver = 4;
  269 
  270         payload_s = rand() & 0x4ff;            /* length of 1279 */
  271         packet_len += payload_s;
  272 
  273         if ( rand() <= (RAND_MAX * TCPOptsPct) )
  274             tcp->th_off = rand() & 0xf;
  275         else    tcp->th_off = 5;
  276         packet_len += (tcp->th_off) << 2;
  277         
  278 
  279         /*
  280         *  Build the IP header
  281         */
  282         ip_hdr = (struct ip *) buf;
  283         ip_hdr->ip_v    = ver;                 /* version 4 */
  284         ip_hdr->ip_hl   = 5 + ipopt_len;       /* 20 byte header */
  285         ip_hdr->ip_tos  = tos;                 /* IP tos */
  286         ip_hdr->ip_len  = htons(packet_len);   /* total length */
  287         ip_hdr->ip_id   = htons(id);           /* IP ID */
  288         ip_hdr->ip_off  = htons(frag_off);     /* fragmentation flags */
  289         ip_hdr->ip_ttl  = ttl;                 /* time to live */
  290         ip_hdr->ip_p    = IPPROTO_TCP;         /* transport protocol */
  291         ip_hdr->ip_sum  = 0;                   /* do this later */
  292         ip_hdr->ip_src.s_addr = src_ip;
  293         ip_hdr->ip_dst.s_addr = dst_ip;
  294         
  295         if ( src_port_rand == 1 )
  296             tcp->th_sport = RAND16;
  297         else    tcp->th_sport = src_prt;
  298         if ( dst_port_rand == 1 )
  299             tcp->th_dport = RAND16;
  300         else    tcp->th_dport = dst_prt;
  301 
  302         tcp->th_seq = RAND32;
  303         tcp->th_ack = RAND32;
  304         tcp->th_x2  = rand() & 0xf;     /* 4bit */
  305         tcp->th_flags   = RAND8;
  306         tcp->th_win = RAND16;
  307         tcp->th_sum = 0;
  308         if ( rand() <= (RAND_MAX * UrgPct) )
  309             tcp->th_urp = RAND16;
  310         else    tcp->th_urp = 0;
  311 
  312 
  313         payload = (u_short *)((u_char *) tcp + 20);
  314         for(cx = 0; cx <= (payload_s >> 1); cx+=1)
  315             payload[cx] = RAND16;
  316 
  317         if ( rand() <= (RAND_MAX * TCPCksm) )
  318             tcp->th_sum = RAND16;
  319         else    libnet_do_checksum(l, (u_int8_t *)buf, IPPROTO_TCP, (tcp->th_off<<2)+payload_s);
  320         
  321         if ( printout ) {
  322             printf("%s ->",
  323                 inet_ntoa(*((struct in_addr*) &src_ip )));
  324             printf(" %s tos[%i] id[%i] ver[%i] frag[%i]\n",
  325                 inet_ntoa(*((struct in_addr*) &dst_ip )), tos,
  326                 id, ver, frag_off);
  327         }       
  328          
  329         if ( skip <= acx ) {
  330             for ( cx = 0; cx < repeat; cx++ ) {
  331                 c = libnet_write_raw_ipv4(l, buf, packet_len);
  332                 if (c != -1)
  333                   datapushed+=c;
  334             }
  335             if (c < (packet_len) ) {
  336                 perror("Failed to send packet");
  337         /*   Reduce noise
  338          *      fprintf(stderr, "Packet Failed '%i'\n", c);
  339          *      printf("%s ->", 
  340          *           inet_ntoa(*((struct in_addr*) &src_ip )));
  341          *
  342          *      printf(" %s tos[%i] id[%i] ver[%i] "
  343          *           "frag[%i]\n",
  344          *           inet_ntoa(*((struct in_addr*) &dst_ip )),
  345          *          tos, id, ver, frag_off);
  346          */
  347             }
  348         } 
  349 
  350         if ( !(acx % 1000) ) {
  351             if ( acx == 0 )
  352                 continue;
  353             gettimeofday(&tv2, NULL);
  354             sec = (tv2.tv_sec - tv.tv_sec)
  355                   - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  356             printf(" %li @ %.1f pkts/sec and %.1f k/s\n", acx,
  357                 1000/sec, (datapushed / 1024.0) / sec);
  358             datapushed=0;
  359             gettimeofday(&tv, NULL);
  360         }
  361 
  362         /* Flood protection for low traffic only. */
  363         if ( max_pushed < 10000000 ) {
  364             gettimeofday(&tv2, NULL);
  365             sec = (tv2.tv_sec - tv.tv_sec)
  366                     - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  367             if ( (datapushed / sec) >= max_pushed )
  368                 usleep(10); /* 10 should give up our timeslice */
  369         }
  370     }
  371 
  372 
  373     gettimeofday(&tv, NULL);
  374     printf("\nWrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  375         (tv.tv_sec-starttime.tv_sec)
  376         + (tv.tv_usec-starttime.tv_usec) / 1000000.0,
  377         acx / ((tv.tv_sec-starttime.tv_sec)
  378                        + (tv.tv_usec-starttime.tv_usec)/1000000.0) );
  379 
  380     libnet_destroy(l);
  381     free(buf);
  382     return ( 0 );
  383 }
  384 
  385 
  386 void usage(char *name)
  387 {
  388    fprintf(stderr,
  389     "usage: %s [-v] [-D] -s <sourceip>[,port] -d <destination ip>[,port]\n"
  390     "          [-r seed] [-m <max kB/s to generate>]\n"
  391     "          [-p <pkts to generate>] [-k <skip packets>] [-x <repeat times>]\n\n"
  392     "       Percentage Opts: [-F frags] [-V <Bad IP Version>] [-I <IP Options>]\n"
  393     "                        [-T <TCP Options>] [-u <urgent data>] [-t <Bad TCP Cksm>]\n\n"
  394     "       [-D] causes packet info to be printed out -- DEBUGGING\n\n"
  395     "       ex: -s 10.10.10.10,23   -d 10.10.10.100 -I 100\n"
  396     "           will give a 100%% chance of IP Options ^^^\n"
  397     "       ex: -s 10.10.10.10,23   -d 10.10.10.100 -p 100 -r 103334\n"
  398     "       ex: -s rand -d rand,1234 -r 23342\n"
  399     "              ^^^^ causes random source addr\n"
  400     "       ex: -s rand -d rand -k 10000 -p 10001 -r 666\n"
  401     "           Will only send the 10001 packet with random seed 666\n"
  402     "           this is especially useful if you suspect that packet is\n"
  403     "           causing a problem with the target stack.\n\n",
  404     ((char *) rindex(name, '/')) == ((char *) NULL)
  405         ? (char *) name
  406         : (char *) rindex(name, '/') + 1);
  407 }
  408 
  409 void sighandler(int sig)
  410 {
  411     struct timeval tv;
  412     gettimeofday(&tv, NULL);
  413 
  414     printf("\n");
  415     printf("Caught signal %i\n", sig);
  416 
  417     printf("Used random seed %i\n", seed);
  418     printf("Wrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  419         (tv.tv_sec - starttime.tv_sec)
  420           + (tv.tv_usec - starttime.tv_usec)/1000000.0,
  421         acx / (( tv.tv_sec - starttime.tv_sec)
  422           + (tv.tv_usec - starttime.tv_usec)/1000000.0)
  423         );
  424 
  425     fflush(stdout);
  426     exit(0);
  427 }