"Fossies" - the Fresh Open Source Software Archive

Member "isic-0.07/multisic.c" (22 Dec 2006, 14498 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 "multisic.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 /* Variables shared between main and the signal handler so we can display
   11  * output if ctrl-c'd
   12  */
   13 u_int seed = 0;
   14 u_long acx = 0;
   15 struct timeval starttime;
   16 u_long datapushed = 0;          /* How many bytes we pushed */
   17 
   18 
   19 char *atoether( char * );
   20 
   21 int
   22 main(int argc, char **argv)
   23 {
   24     int c;
   25     u_char *buf = NULL;
   26     u_short *payload = NULL;
   27     u_int payload_s = 0;
   28     int packet_len = 0;
   29     char device[128] = "";
   30 
   31     struct ether_addr *ea = NULL;
   32     struct ether_header *ether = NULL;
   33     struct ip *ip_hdr = NULL;
   34     struct udphdr *udp = NULL;
   35     u_short *ip_opts = NULL;
   36 
   37     /* libnet variables */
   38     char errbuf[LIBNET_ERRBUF_SIZE];
   39     libnet_t *l = NULL;
   40 
   41     /* Packet Variables */
   42     u_int32_t src_ip = 0, dst_ip = 0;
   43     u_short src_prt = 0, dst_prt = 0;
   44     u_char tos, ttl, ver;
   45     u_int id, frag_off;
   46     u_int ipopt_len;
   47     u_char first_octets[] = {224, 225, 232, 233, 234, 235, 236, 237, 238, 239};
   48     size_t octet_array_size = (sizeof(first_octets) / sizeof(first_octets[0]));
   49     u_char compare[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   50     u_char dhost[] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x00};
   51     u_char shost[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   52     u_int16_t proto = htons(ETHERTYPE_IP);
   53 
   54     /* Functionality Variables */
   55     int src_ip_rand = 0, dst_ip_rand = 0;
   56     int src_mac_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 BadIPVer  =   10;
   72     float IPOpts    =   10;
   73     float UDPCksm   =   10;
   74 
   75     /* Not crypto strong randomness but we don't really care.  And this  *
   76      * gives us a way to determine the seed while the program is running *
   77      * if we need to repeat the results                  */
   78     seed = getpid();
   79     
   80     while((c = getopt(argc, argv, "i:hd:s:r:m:k:Dp:V:F:I:U:vx:z:")) != EOF) {
   81       switch (c) {
   82        case 'z':
   83         if ( strcmp(optarg, "rand") == 0 ) {
   84             printf("Using random source MAC's\n");
   85             shost[0] = 0xff;
   86             src_mac_rand = 1;
   87             break;
   88         }
   89         bcopy(atoether(optarg), shost, 6);
   90         break;
   91        case 'i':
   92         if (rindex(optarg, '/'))
   93             strncpy(device, (char *) rindex(optarg, '/')+1, 128);
   94         else
   95             strncpy(device, optarg, 128);
   96         device[127] = '\0';
   97         break;
   98        case 'h':
   99         usage(argv[0]);
  100         exit(0);
  101         break;
  102        case 'd':
  103         dst_port_rand = 1;
  104         if ( (tmp_port = index(optarg, ',')) != NULL ) {
  105             *tmp_port++ = '\0';
  106             dst_port_rand = 0;
  107             dst_prt = htons((u_int) atol(tmp_port));
  108         }
  109         if ( strcmp(optarg, "rand") == 0 ) {
  110             printf("Using random multicast dest IP's\n");
  111             dst_ip = 1; /* Just to pass sanity checks */
  112             dst_ip_rand = 1;
  113             break;
  114         }
  115         if ((dst_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == (u_int32_t)-1) {
  116             fprintf(stderr, "Bad dest IP\n");
  117             exit( -1 );
  118         }
  119         break;
  120        case 's':
  121         src_port_rand = 1;
  122         if ( (tmp_port = index(optarg, ',')) != NULL ) {
  123             *tmp_port++ = '\0';
  124             src_port_rand = 0;
  125             src_prt = htons((u_int) atol(tmp_port));
  126         }
  127         if ( strcmp(optarg, "rand") == 0 ) {
  128             printf("Using random source IP's\n");
  129             src_ip = 1; /* Just to pass sanity checks */
  130             src_ip_rand = 1;
  131             break;
  132         }
  133         if ((src_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == (u_int32_t)-1) {
  134             fprintf(stderr, "Bad source IP\n");
  135             exit( -1 );
  136         }
  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 'V':
  155         BadIPVer = atof(optarg);
  156         break;
  157        case 'F':
  158         FragPct = atof(optarg);
  159         break;
  160        case 'I':
  161         IPOpts = atof(optarg);
  162         break;
  163        case 'U':
  164         UDPCksm = atof(optarg);
  165         break;
  166        case 'x':
  167         repeat = atoi(optarg);
  168         break;
  169        case 'v':
  170         printf("Version %s\n", VERSION);
  171         exit(0);
  172        }
  173     }
  174 
  175     if ( *device == '\0' || !src_ip || !dst_ip ) {
  176         usage(argv[0]);
  177         exit(EXIT_FAILURE);
  178     }
  179 
  180     /* Initialize libnet context, Root priviledges are required.*/ 
  181     l = libnet_init(
  182             LIBNET_LINK_ADV,                        /* injection type */
  183             device,                                 /* network interface */
  184             errbuf);                                /* error buffer */
  185 
  186     if (l == NULL) {
  187       fprintf(stderr, "libnet_init() failed: %s", errbuf);
  188       exit( -1 );
  189     }
  190 
  191     printf("Compiled against Libnet %s\n", LIBNET_VERSION);
  192     printf("Installing Signal Handlers.\n");
  193     if ( signal(SIGTERM, &sighandler) == SIG_ERR )
  194         printf("Failed to install signal handler for SIGTERM\n");
  195     if ( signal(SIGINT, &sighandler) == SIG_ERR )
  196         printf("Failed to install signal handler for SIGINT\n");
  197     if ( signal(SIGQUIT, &sighandler) == SIG_ERR )
  198         printf("Failed to install signal handler for SIGQUIT\n");
  199 
  200     printf("Seeding with %i\n", seed);
  201     srand(seed);
  202     max_pushed *= 1024;
  203 
  204     if ( src_port_rand )
  205         printf("Using random source ports.\n");
  206     if ( dst_port_rand )
  207         printf("Using random destination ports.\n");
  208 
  209     if ( (buf = malloc(ETHER_FRAME_SIZE)) == NULL ) {
  210         perror("malloc: ");
  211         exit( -1 );
  212     }
  213     bzero(buf, ETHER_FRAME_SIZE);
  214     ether = (struct ether_header *) buf;
  215     ether->ether_type = proto;
  216 
  217     if ( bcmp(shost, compare, 6) == 0 ) {
  218         if ( (ea = (struct ether_addr *)libnet_get_hwaddr(l)) == 0 )
  219             fprintf(stderr, "Cannot get MAC for %s: %s", device, libnet_geterror(l));
  220         bcopy(ea, ether->ether_shost, 6);
  221     } else  bcopy(shost, ether->ether_shost, 6);
  222 
  223     bcopy(dhost, ether->ether_dhost, 3);
  224 
  225     if ( !src_mac_rand )
  226         printf("Sending from MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
  227             ether->ether_shost[0], ether->ether_shost[1],
  228             ether->ether_shost[2], ether->ether_shost[3],
  229             ether->ether_shost[4], ether->ether_shost[5]);
  230     else    printf("Sending from random MAC addresses.\n");
  231     
  232     if ( max_pushed >= 10000000 )
  233         printf("No Maximum traffic limiter\n");
  234     else printf("Maximum traffic rate = %.2f k/s\n", max_pushed/1024.0 );
  235 
  236     printf("Bad IP Version\t= %.0f%%\t\t", BadIPVer);
  237     printf("IP Opts Pcnt\t= %.0f%%\n", IPOpts);
  238 
  239     printf("Frag'd Pcnt\t= %.0f%%\t\t", FragPct);
  240     printf("Bad UDP Cksm\t= %.0f%%\n", UDPCksm);
  241     printf("\n");
  242 
  243 
  244     /* Drop them down to floats so we can multiply and not overflow */
  245     BadIPVer    /= 100;
  246     FragPct     /= 100;
  247     IPOpts      /= 100;
  248     UDPCksm     /= 100;
  249 
  250     
  251 
  252     /*************
  253     * Main Loop *
  254     *************/
  255     gettimeofday(&tv, NULL);
  256     gettimeofday(&starttime, NULL);
  257 
  258     for(acx = 0; acx < num_to_send; acx++) {
  259         if ( src_mac_rand ) {
  260             ((u_int16_t *) ether->ether_shost)[0] = RAND16;
  261             ((u_int16_t *) ether->ether_shost)[1] = RAND16;
  262             ((u_int16_t *) ether->ether_shost)[2] = RAND16;
  263         }
  264 
  265         packet_len = IP_H + UDP_H;
  266     
  267         tos = RAND8;
  268         id  = acx & 0xffff;
  269         ttl = RAND8;
  270 
  271 
  272         if ( rand() <= (RAND_MAX * FragPct) )
  273             frag_off = RAND16;
  274         else    frag_off = 0;
  275 
  276         /* We're not going to pad IP Options */
  277         if ( rand() <= (RAND_MAX * IPOpts) ) {
  278             ipopt_len = 10 * (rand() / (float) RAND_MAX);
  279             ipopt_len = ipopt_len << 1;
  280             ip_opts = (u_short *) (buf + 14);
  281             packet_len += ipopt_len << 1;
  282 
  283             for ( cx = 0; cx < ipopt_len; cx++ )
  284                 ip_opts[cx] = RAND16;
  285             udp = (struct udphdr *) ((buf + 14) + IP_H + (ipopt_len << 1));
  286             ipopt_len = ipopt_len >> 1;
  287         } else {
  288             ipopt_len = 0;
  289             udp = (struct udphdr *) ((buf + 14) + IP_H);
  290         }
  291 
  292         if ( src_ip_rand == 1 )
  293             src_ip = RAND32;
  294         if ( dst_ip_rand == 1 ) {
  295             u_char first_octet = first_octets[rand() % octet_array_size];
  296             dst_ip = ((RAND16 << 16) + (RAND8 << 8) + first_octet); /* little-endian */
  297             }
  298 
  299         ether->ether_dhost[3] = (dst_ip & 0x00007f00) >> 8;
  300         ether->ether_dhost[4] = (dst_ip & 0x00ff0000) >> 16; 
  301         ether->ether_dhost[5] = (dst_ip & 0xff000000) >> 24;
  302 
  303         if ( rand() <= (RAND_MAX * BadIPVer ) )
  304             ver = rand() & 0xf;
  305         else    ver = 4;
  306 
  307         payload_s = rand() & 0x4ff;            /* length of 1279 */
  308         packet_len += payload_s;
  309 
  310         /*
  311          *  Build the IP header
  312          */
  313         ip_hdr = (struct ip *) (buf + 14);
  314         ip_hdr->ip_v    = ver;                 /* version 4 */
  315         ip_hdr->ip_hl   = 5 + ipopt_len;       /* 20 byte header */
  316         ip_hdr->ip_tos  = tos;                 /* IP tos */
  317         ip_hdr->ip_len  = htons(packet_len);   /* total length */
  318         ip_hdr->ip_id   = htons(id);           /* IP ID */
  319         ip_hdr->ip_off  = htons(frag_off);     /* fragmentation flags */
  320         ip_hdr->ip_ttl  = ttl;                 /* time to live */
  321         ip_hdr->ip_p    = IPPROTO_UDP;         /* transport protocol */
  322         ip_hdr->ip_sum  = 0;                   /* do this later */
  323         ip_hdr->ip_src.s_addr = src_ip;
  324         ip_hdr->ip_dst.s_addr = dst_ip;
  325         
  326         if ( src_port_rand == 1 )
  327             udp->uh_sport = RAND16;
  328         else    udp->uh_sport = src_prt;
  329         if ( dst_port_rand == 1 )
  330             udp->uh_dport = RAND16;
  331         else    udp->uh_dport = dst_prt;
  332 
  333 
  334         udp->uh_ulen    = htons(payload_s + UDP_H);
  335         udp->uh_sum = 0;
  336 
  337         payload = (u_short *)((u_char *) udp + UDP_H);
  338         for(cx = 0; cx <= (payload_s >> 1); cx+=1)
  339             payload[cx] = RAND16;
  340 
  341         if ( printout ) {
  342             printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x -> ",
  343                            ether->ether_shost[0], ether->ether_shost[1],
  344                    ether->ether_shost[2], ether->ether_shost[3],
  345                    ether->ether_shost[4], ether->ether_shost[5]);
  346                 printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x  ::  ",
  347                        ether->ether_dhost[0], ether->ether_dhost[1],
  348                        ether->ether_dhost[2], ether->ether_dhost[3],
  349                        ether->ether_dhost[4], ether->ether_dhost[5]);
  350             printf("%s,%i ->",
  351                 inet_ntoa(*((struct in_addr*) &src_ip )),
  352                 htons(udp->uh_sport) );
  353             printf(" %s,%i tos[%i] id[%i] ver[%i] frag[%i]\n",
  354                 inet_ntoa(*((struct in_addr*) &dst_ip )), 
  355                 htons(udp->uh_dport), tos, id, ver, frag_off);
  356         }
  357                 
  358         
  359         if ( rand() <= (RAND_MAX * UDPCksm) )
  360             udp->uh_sum = RAND16;
  361         else {
  362             libnet_do_checksum(l, (u_int8_t *)(buf + 14), IPPROTO_IP, packet_len);
  363             libnet_do_checksum(l, (u_int8_t *)(buf + 14), IPPROTO_UDP, UDP_H + payload_s);
  364         }
  365 
  366          
  367         if ( skip <= acx ) {
  368             for ( cx = 0; cx < repeat; cx++ ) {
  369                 c = libnet_adv_write_link(l, buf, (packet_len + 14));
  370                 if (c != -1)
  371                   datapushed+=c;
  372             }
  373             if (c < (packet_len) ) {
  374                 perror("Failed to send packet");
  375         /*      printf("%s ->", 
  376          *           inet_ntoa(*((struct in_addr*) &src_ip )));
  377          *
  378          *      printf(" %s tos[%i] id[%i] ver[%i] "
  379          *           "frag[%i]\n",
  380          *           inet_ntoa(*((struct in_addr*) &dst_ip )),
  381          *          tos, id, ver, frag_off);
  382          */
  383             }
  384         } 
  385 
  386         if ( !(acx % 1000) ) {
  387             if ( acx == 0 )
  388                 continue;
  389             gettimeofday(&tv2, NULL);
  390             sec = (tv2.tv_sec - tv.tv_sec)
  391                   - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  392             printf(" %li @ %.1f pkts/sec and %.1f k/s\n", acx,
  393                 1000/sec, (datapushed / 1024.0) / sec);
  394             datapushed=0;
  395             gettimeofday(&tv, NULL);
  396         }
  397 
  398 
  399         /* Flood protection for low traffic only. */
  400         if ( max_pushed < 10000000 ) {
  401             gettimeofday(&tv2, NULL);
  402             sec = (tv2.tv_sec - tv.tv_sec)
  403                     - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  404             if ( (datapushed / sec) >= max_pushed )
  405                 usleep(10); /* 10 should give up our timeslice */
  406         }
  407     }
  408 
  409 
  410     gettimeofday(&tv, NULL);
  411     printf("\nWrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  412         (tv.tv_sec-starttime.tv_sec)
  413         + (tv.tv_usec-starttime.tv_usec) / 1000000.0,
  414         acx / ((tv.tv_sec-starttime.tv_sec)
  415                        + (tv.tv_usec-starttime.tv_usec)/1000000.0) );
  416 
  417     libnet_destroy(l);
  418     free(buf);
  419     return ( 0 );
  420 }
  421 
  422 char *atoether( char *txt )
  423 {
  424     static char retval[6];
  425     int ret_pos = 0;
  426     int len = 0;
  427     int val = 0;
  428     int cx = 0;
  429 
  430     len = strlen(txt);
  431     bzero(retval, 6);
  432 
  433     for (ret_pos = 0, cx = 0; cx < len; cx++) {
  434         if ( txt[cx] == '\0' )
  435             return( retval );
  436         if ( (txt[cx] == ':') || (txt[cx] == '-') ) {
  437             ret_pos++;
  438             val = 0;
  439             continue;
  440         }
  441         /* Shutdup */
  442         switch ( txt[cx] ) {
  443             case '0':   val = 0;  break;
  444             case '1':   val = 1;  break;
  445             case '2':   val = 2;  break;
  446             case '3':   val = 3;  break;
  447             case '4':   val = 4;  break;
  448             case '5':   val = 5;  break;
  449             case '6':   val = 6;  break;
  450             case '7':   val = 7;  break;
  451             case '8':   val = 8;  break;
  452             case '9':   val = 9;  break;
  453             case 'A':
  454             case 'a':   val = 10; break;
  455             case 'B':
  456             case 'b':   val = 11; break;
  457             case 'C':
  458             case 'c':   val = 12; break;
  459             case 'D':
  460             case 'd':   val = 13; break;
  461             case 'E':
  462             case 'e':   val = 14; break;
  463             case 'F':
  464             case 'f':   val = 15; break;
  465         }
  466         retval[ret_pos] = (u_int8_t) (((retval[ret_pos]) << 4) + val);
  467     }
  468     
  469     return( retval );
  470 }
  471 
  472 void usage(char *name)
  473 {
  474    fprintf(stderr,
  475     "usage: %s [-v] [-D] -s <source ip>[,port] -d <destination ip>[,port]\n"
  476     "          [-r seed] [-m <max kB/s to generate>] -i [interface]\n"
  477     "          [-p <pkts to generate>] [-k <skip packets>] [-x <repeat times>]\n"
  478     "          [-z <source MAC>]\n\n"
  479     "       Percentage Opts: [-F frags] [-V <Bad IP Version>] [-I <IP Options>]\n"
  480     "                        [-U <UDP Checksum>]\n\n"
  481     "       [-D] causes packet info to be printed out -- DEBUGGING\n\n"
  482     "       This tool sends out UDP packets with random or specified multicast\n"
  483     "       destination IP address.\n\n"
  484     "       ex: -s 10.10.10.10,23 -d 224.10.10.100 -I 100\n"
  485     "           will give a 100%% chance of IP Options ^^^\n"
  486     "       ex: -s 10.10.10.10,23  -d 239.10.10.100 -p 100 -r 103334\n"
  487     "       ex: -s rand -d rand,1234 -r 23342\n"
  488     "              ^^^^ causes random source addr\n"
  489     "       ex: -s rand -d rand -k 10000 -p 10001 -r 666\n"
  490     "           Will only send the 10001 packet with random seed 666\n"
  491     "           this is especially useful if you suspect that packet is\n"
  492     "           causing a problem with the target stack.\n\n",
  493     ((char *) rindex(name, '/')) == ((char *) NULL)
  494         ? (char *) name
  495         : (char *) rindex(name, '/') + 1);
  496 }
  497 
  498 void sighandler(int sig)
  499 {
  500     struct timeval tv;
  501     gettimeofday(&tv, NULL);
  502 
  503     printf("\n");
  504     printf("Caught signal %i\n", sig);
  505 
  506     printf("Used random seed %i\n", seed);
  507     printf("Wrote %li packets in %.2fs @ %.2f pkts/s\n", acx,
  508         (tv.tv_sec - starttime.tv_sec)
  509           + (tv.tv_usec - starttime.tv_usec)/1000000.0,
  510         acx / (( tv.tv_sec - starttime.tv_sec)
  511           + (tv.tv_usec - starttime.tv_usec)/1000000.0)
  512         );
  513 
  514     fflush(stdout);
  515     exit(0);
  516 }