"Fossies" - the Fresh Open Source Software Archive

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

    1 
    2 /* Link Level scan */
    3 
    4 /* COOL!!!!  Linux can send out short ether frames!
    5  */
    6 
    7 /* ARGHH!!!!!  The IEEE specifies things in bitwise little-endian order.
    8  */
    9 
   10 #if !defined(linux)
   11 #define __GLIBC__   1   /* XXX */
   12 #endif
   13 
   14 #include "isic.h"
   15 
   16 
   17 char *atoether(char *);
   18 
   19 int main(int argc, char **argv)
   20 {
   21     u_char compare[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   22     u_char dhost[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   23     u_char shost[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
   24     struct ether_header *ether = NULL;
   25     u_int16_t proto = htons(ETHERTYPE_IP);
   26     struct ether_addr *ea = NULL;
   27     u_int16_t *data = NULL;
   28     char dev[128] = "";
   29     u_char *buf = NULL;
   30     int proto_rand = 0;
   31     struct timeval tv, tv2;
   32     int max_len = ETHER_FRAME_SIZE;
   33     u_long count = 0xffffffffl;
   34     u_long data_pushed = 0;
   35     struct ip *ip = NULL;
   36     u_long data_len = 0;
   37     int rand_source = 0;
   38     int rand_dest = 0;
   39     long mark = 1000;
   40         u_long skip = 0;           /* Skip how many packets */
   41     u_long acx = 0;
   42     int debug = 0;
   43     u_int len = 0;
   44     u_int cx = 0;
   45     float sec;
   46     int seed;
   47     u_int c;
   48 
   49     /* libnet variables */
   50     char errbuf[LIBNET_ERRBUF_SIZE];
   51     libnet_t *l;
   52 
   53     seed = getpid();
   54 
   55     while((c=getopt(argc, argv, "hi:s:d:k:p:r:c:l:Dvm:")) != (unsigned) EOF) {
   56       switch (c) {
   57       case 'i':
   58         if (rindex(optarg, '/'))
   59             strncpy(dev, (char *) rindex(optarg, '/')+1, 128);
   60         else
   61             strncpy(dev, optarg, 128);
   62         dev[127] = '\0';
   63         break;
   64       case 's':
   65         if ( strcmp(optarg, "rand") == 0 ) {
   66             printf("Using random source MAC's\n");
   67             shost[0] = 0xff;
   68             rand_source = 1;
   69             break;
   70         }
   71         bcopy(atoether(optarg), shost, 6);
   72         break;
   73       case 'd':
   74         if ( strcmp(optarg, "rand") == 0 ) {
   75             printf("Using random destination MAC's\n");
   76             dhost[0] = 0xff;
   77             rand_dest = 1;
   78             break;
   79         }
   80         bcopy(atoether(optarg), dhost, 6);
   81         break;
   82       case 'r':
   83         seed = atoi(optarg);
   84         break;
   85       case 'c':
   86         count = atol(optarg);
   87         break;
   88       case 'm':
   89         mark = atol(optarg);
   90         if (mark <= 0)
   91             exit(printf("Please use a positive arg for -m\n"));
   92         break;
   93       case 'k':
   94         skip = atol(optarg);
   95         printf("Will not transmit first %li packet(s).\n", skip);
   96         break;
   97       case 'D':
   98         debug++;
   99         break;
  100       case 'l':
  101         max_len = atoi(optarg);
  102         if ( max_len > 1500 ) {
  103             printf("Maximum Length of %i is longer than the max "
  104                 "ethernet frame size of %i\n", max_len,
  105                 ETHER_FRAME_SIZE);
  106             exit(0);
  107         }
  108         if ( max_len <  14) {
  109             printf("You seam to have entered %i as the maximum "
  110                 "length...  Please make it >= 14\n", max_len);
  111             exit(0);
  112         }
  113         break;
  114       case 'p':
  115         if ( strcasecmp(optarg, "rand") == 0 ) {
  116             proto_rand++;
  117             break;
  118         }
  119         proto_rand = 0;
  120         proto = htons(atoi(optarg));
  121         break;
  122        case 'v':
  123         printf("Version %s\n", VERSION);
  124         exit(0);
  125       case 'h':
  126       default:
  127         usage(argv[0]);
  128         exit( 0 );
  129       }
  130     }
  131 
  132 
  133     if ( *dev == '\0' ) {
  134         usage(argv[0]);
  135         exit( 0 );
  136     }
  137 
  138     /* Initialize libnet context, Root priviledges are required.*/ 
  139     l = libnet_init(
  140             LIBNET_LINK_ADV,                        /* injection type */
  141             dev,                                    /* network interface */
  142             errbuf);                                /* error buffer */
  143 
  144     if (l == NULL) {
  145       fprintf(stderr, "Can not initialize libnet: %s", errbuf);
  146       exit( -1 );
  147     }
  148 
  149     max_len -= 6 + 6 + 2;
  150 
  151     printf("Seeding with %i\n", seed);
  152     srand(seed);
  153 
  154     if ( (buf = malloc(ETHER_FRAME_SIZE)) == NULL ) {
  155         perror("malloc");
  156         exit( -1 );
  157     }
  158     bzero(buf, ETHER_FRAME_SIZE);
  159     ether = (struct ether_header *) buf;
  160 
  161     if ( bcmp(dhost, compare, 6) == 0 )
  162         memset(ether->ether_dhost, 0xff, 6);
  163     else    bcopy(dhost, ether->ether_dhost, 6);
  164     if ( bcmp(shost, compare, 6) == 0 ) {
  165         if ( (ea = (struct ether_addr *)libnet_get_hwaddr(l)) == 0 )
  166             fprintf(stderr, "Cannot get MAC for %s: %s", dev, libnet_geterror(l));
  167         bcopy(ea, ether->ether_shost, 6);
  168     } else  bcopy(shost, ether->ether_shost, 6);
  169 
  170 
  171     printf("Maximum packet size (minus header) is %i bytes\n", max_len);
  172     if ( proto_rand )
  173         printf("Ethernet protocols will be randomized.\n");
  174     else    printf("Ethernet protocol will be %i.\n", ntohs(proto));
  175 
  176 
  177     if ( !rand_dest )
  178         printf("Sending to MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
  179             ether->ether_dhost[0], ether->ether_dhost[1],
  180             ether->ether_dhost[2], ether->ether_dhost[3],
  181             ether->ether_dhost[4], ether->ether_dhost[5]);
  182     else    printf("Sending to random MAC addresses.\n");
  183     if ( !rand_source )
  184         printf("Sending from MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
  185             ether->ether_shost[0], ether->ether_shost[1],
  186             ether->ether_shost[2], ether->ether_shost[3],
  187             ether->ether_shost[4], ether->ether_shost[5]);
  188     else    printf("Sending from random MAC addresses.\n");
  189 
  190     ip = (struct ip *) (buf + 14);
  191 
  192     data = (u_int16_t *) (buf + 14);
  193     printf("Sending...\n");
  194     gettimeofday(&tv, NULL);
  195     for ( acx = 1; acx <= count; acx++ ) {
  196         len = sizeof(struct ether_header);
  197 
  198         if ( rand_source ) {
  199             ((u_int16_t *) ether->ether_shost)[0] = RAND16;
  200             ((u_int16_t *) ether->ether_shost)[1] = RAND16;
  201             ((u_int16_t *) ether->ether_shost)[2] = RAND16;
  202         }
  203         if ( rand_dest ) {
  204             ((u_int16_t *) ether->ether_dhost)[0] = RAND16;
  205             ((u_int16_t *) ether->ether_dhost)[1] = RAND16;
  206             ((u_int16_t *) ether->ether_dhost)[2] = RAND16;
  207         }
  208         if ( proto_rand )
  209             ether->ether_type = RAND16;
  210         else    ether->ether_type = proto;
  211 
  212         data_len = (u_int) (max_len * (rand()/((float) RAND_MAX + 1)));
  213         data_len >>= 1;
  214         for ( cx = 0; cx < data_len; cx++ )
  215             data[cx] = RAND16;
  216         data_len <<= 1;
  217         if ( rand() & 0x1 ) {
  218             data_len++;
  219             data[cx] = RAND16;
  220         }
  221         len += data_len;
  222     
  223         ip->ip_len = htons(data_len);
  224         ip->ip_sum = 0;
  225         libnet_do_checksum(l, (u_int8_t *) ip, IPPROTO_IP, data_len);
  226 
  227         if ( debug ) {
  228             printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x  ->  ",
  229                 ether->ether_shost[0], ether->ether_shost[1],
  230                 ether->ether_shost[2], ether->ether_shost[3],
  231                 ether->ether_shost[4], ether->ether_shost[5]);
  232             printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t",
  233                 ether->ether_dhost[0], ether->ether_dhost[1],
  234                 ether->ether_dhost[2], ether->ether_dhost[3],
  235                 ether->ether_dhost[4], ether->ether_dhost[5]);
  236             switch( ntohs(ether->ether_type) ) {
  237                 case ETHERTYPE_IP:
  238                     printf("Proto IP  \t");
  239                     break;
  240                 case ETHERTYPE_ARP:
  241                     printf("Proto ARP \t");
  242                     break;
  243                 case ETHERTYPE_PUP:
  244                     printf("Proto PUP \t");
  245                     break;
  246                 case ETHERTYPE_REVARP:
  247                     printf("Proto RARP\t");
  248                     break;
  249                 case ETHERTYPE_VLAN:
  250                     printf("Proto VLAN\t");
  251                     break;
  252                 default:
  253                     printf("Proto %u\t",
  254                         ntohs(ether->ether_type));
  255             }
  256             printf("Length %i\n", len);
  257         }
  258 
  259         if ( acx >= skip ) {
  260             c = libnet_adv_write_link(l, buf, len);
  261             if (c !=(u_int) -1)
  262                 data_pushed += c;
  263         }
  264 
  265     /*  if ( c != len ) 
  266      *      perror("write_ll");
  267      */ 
  268         if ( !(acx % mark) ) {
  269             gettimeofday(&tv2, NULL);
  270             sec = (tv2.tv_sec - tv.tv_sec)
  271                 - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  272             printf(" %8lu @ %.1f pkts/sec and %.1f k/s\n", acx,
  273                 mark/sec, (data_pushed/1024.0)/sec );
  274             data_pushed = 0;
  275             gettimeofday(&tv, NULL);
  276         }
  277     }
  278 
  279         if ((acx-1) % mark) {       /* There is a remainder */
  280         gettimeofday(&tv2, NULL);
  281         sec = (tv2.tv_sec - tv.tv_sec)
  282             - (tv.tv_usec - tv2.tv_usec) / 1000000.0;
  283         printf(" %8lu @ %.1f pkts/sec and %.1f k/s\n", acx-1,
  284             ((acx-1) % mark)/sec, (data_pushed/1024.0)/sec );
  285     }
  286 
  287     libnet_destroy(l);
  288     free( buf );
  289     return ( 0 );
  290 }
  291 
  292 char *atoether( char *txt )
  293 {
  294     static char retval[6];
  295     int ret_pos = 0;
  296     int len = 0;
  297     int val = 0;
  298     int cx = 0;
  299 
  300     len = strlen(txt);
  301     bzero(retval, 6);
  302 
  303     for (ret_pos = 0, cx = 0; cx < len; cx++) {
  304         if ( txt[cx] == '\0' )
  305             return( retval );
  306         if ( (txt[cx] == ':') || (txt[cx] == '-') ) {
  307             ret_pos++;
  308             val = 0;
  309             continue;
  310         }
  311         /* Shutdup */
  312         switch ( txt[cx] ) {
  313             case '0':   val = 0;  break;
  314             case '1':   val = 1;  break;
  315             case '2':   val = 2;  break;
  316             case '3':   val = 3;  break;
  317             case '4':   val = 4;  break;
  318             case '5':   val = 5;  break;
  319             case '6':   val = 6;  break;
  320             case '7':   val = 7;  break;
  321             case '8':   val = 8;  break;
  322             case '9':   val = 9;  break;
  323             case 'A':
  324             case 'a':   val = 10; break;
  325             case 'B':
  326             case 'b':   val = 11; break;
  327             case 'C':
  328             case 'c':   val = 12; break;
  329             case 'D':
  330             case 'd':   val = 13; break;
  331             case 'E':
  332             case 'e':   val = 14; break;
  333             case 'F':
  334             case 'f':   val = 15; break;
  335         }
  336         retval[ret_pos] = (u_int8_t) (((retval[ret_pos]) << 4) + val);
  337     }
  338     
  339     return( retval );
  340 }
  341 
  342 
  343 
  344 void
  345 usage(char *name)
  346 {
  347     printf(
  348 "usage: %s -i interface [-s <source MAC>] [-d <destination MAC>]\n"
  349 "          [-p <protocol #> or 'rand'>]   [-r <random seed>]\n"
  350 "          [-c <# of pkts to send>] [-k <skip packets>] \n"
  351 "          [-l <max pkt length>] [-m <# of pkts between printout>]\n\n"
  352 "       - Be careful, the source MAC defaults to your interface\n"
  353 "         and the dest MAC defaults to broadcast\n"
  354 "       - You can use 'rand' for the source and/or the dest MAC\n\n"
  355 "   examples:\n"
  356 "       esic -i eth0 -d 02:de:ad:be:ef:40 -r123 -c10000\n"
  357 "       esic -i ep0 -s 01:02:34:56:07:89 -p rand -m5000\n\n",
  358         (char *) (index(name, '/') == NULL)
  359             ? (char *) name
  360             : (char *) (rindex(name, '/') + 1) );
  361 }