Esempio n. 1
0
File: main.c Progetto: inste/reader
int open_device(char * device) {
	struct termios tio;
	int tty_fd;

	if (!dev_exists(device)) {
		return -ENXIO;
	}

	memset(&tio, 0, sizeof(tio));
	tio.c_iflag = 0;
	tio.c_oflag = 0;
	tio.c_cflag = CS8 | CREAD | CLOCAL;
	tio.c_lflag = 0;
	tio.c_cc[VMIN] = 1;
	tio.c_cc[VTIME] = 5;

	if ((tty_fd = open(device, O_RDWR)) == -1) {
		return -1;
	}

	cfsetospeed(&tio, BAUDRATE);
	cfsetispeed(&tio, BAUDRATE);
	tcsetattr(tty_fd, TCSANOW, &tio);

	return tty_fd;
}
Esempio n. 2
0
// Purpose: Properly handle arguments and configure global structs (tx)
int getopts (int argc, char *argv[])
{
    int i, c, rargs, RX=0, count_set=0, delay_set=0;
    unsigned int time_factor;
    char *packet_type=NULL, *mops_type=NULL;
    char *dum;
    unsigned char *dum1, *dum2;

    libnet_t       *l;
    char err_buf[LIBNET_ERRBUF_SIZE];
    struct libnet_ether_addr *mymac;

    FILE *afp;
    char hexpld[MAX_PAYLOAD_SIZE*2];
    int hexpld_specified=0;

    opterr = 1; // let getopt print error message if necessary


    while ((c = getopt (argc, argv, "hqvVSxra:A:b:B:c:d:f:F:p:P:t:T:M:Q:X:")) != -1)
        switch (c) {
        case 'h':
            usage();
            break;
        case 'q':
            quiet=1;
            break;
        case 'v':
            verbose=1;
            break;
        case 'V':
            verbose=2;
            break;
        case 'S':
            simulate=1;
            break;
        case 'x':
            mz_port = MZ_DEFAULT_PORT;
            break;
        case 'a':
            strncpy (tx.eth_src_txt, optarg, 32);
            tx.packet_mode = 0;
            break;
        case 'A':
            strncpy (tx.ip_src_txt, optarg, 32);
            break;
        case 'b':
            strncpy (tx.eth_dst_txt, optarg, 32);
            tx.packet_mode = 0;
            break;
        case 'B':
            strncpy (tx.ip_dst_txt, optarg, 32);
            break;
        case 'c':
            errno=0;
            tx.count = strtol(optarg, (char **)NULL, 10);
            if ((errno == ERANGE && (tx.count == LONG_MAX || tx.count == LONG_MIN))
                    || (errno != 0 && tx.count == 0)) {
                perror("strtol");
                return (-1);
            }
            if (tx.count<0) tx.count=1;	  //TODO: Allow count=0 which means infinity (need to update all send_functions)
            count_set=1;
            break;
        case 'd':
            errno=0;
            // determine whether seconds or msecs are used
            // default is usec!!!
            time_factor=1;
            if (exists(optarg,"s") || exists(optarg,"sec")) time_factor=1000000;
            if (exists(optarg,"m") || exists(optarg,"msec")) time_factor=1000;
            dum = strtok(optarg,"ms");
            tx.delay = strtol(dum, (char **)NULL, 10) * time_factor;
            if ((errno == ERANGE && (tx.delay == LONG_MAX || tx.delay == LONG_MIN))
                    || (errno != 0 && tx.delay == 0)) {
                perror("strtol");
                return (-1);
            }
            if (tx.delay<0) tx.delay=0; // no delay
            delay_set=1;
            break;
        case 'p':
            errno=0;
            tx.padding = strtol(optarg, (char **)NULL, 10);
            if ((errno == ERANGE && (tx.padding == LONG_MAX || tx.padding == LONG_MIN))
                    || (errno != 0 && tx.padding == 0))  {
                perror("strtol");
                return (-1);
            }
            if (tx.padding>10000) {
                fprintf(stderr, " Warning: Padding must not exceed 10000!\n");
                return -1;
            }
            break;
        case 't':
            packet_type = optarg; // analyzed below
            break;
        case 'X':
            mops_type = optarg; // MOPS TRANSITION STRATEGY -- analyzed below
            break;
        case 'T':
            packet_type = optarg;
            RX = 1;
            break;
        case 'r':
            mz_rand = 1;
            break;
        case 'M':
            if (strncmp(optarg,"help",4)==0) {
                (void) get_mpls_params("help ");
            }
            else {
                strncpy (tx.mpls_txt, optarg, 128);
                tx.eth_type = ETHERTYPE_MPLS;
                tx.packet_mode = 0;
                tx.mpls=1;
            }
            break;
        case 'P':  // ASCII payload
            strncpy((char*)tx.ascii_payload,  optarg, MAX_PAYLOAD_SIZE);
            tx.ascii = 1;
            break;
        case 'f': // ASCII payload in FILE
            afp = fopen(optarg, "r");
            if (fgets((char*)tx.ascii_payload, MAX_PAYLOAD_SIZE, afp) == NULL)
                fprintf(stderr, " mz/getopts: File empty?\n");
            fclose(afp);
            tx.ascii = 1;
            break;
        case 'F': // HEX payload in FILE
            afp = fopen(optarg, "r");
            i=0;
            while ( (hexpld[i]=fgetc(afp))!=EOF ) {
                if (isspace(hexpld[i])) {
                    hexpld[i]=':';
                }
                i++;
            }
            hexpld[i]='\0';
            fclose(afp);
            hexpld_specified=1;
            break;
        case 'Q': // VLAN TAG
            if (strncmp(optarg,"help",4)==0) {
                print_dot1Q_help(); // ugly but most simple and safe solution
            }
            else {
                strncpy (tx.dot1Q_txt, optarg, 32);
                tx.dot1Q=1;
                // determine number of VLAN tags
                for (i=0; i<strlen(tx.dot1Q_txt); i++) {
                    if (tx.dot1Q_txt[i]==',') tx.dot1Q++;
                }
                tx.packet_mode = 0;
            }
            break;
        case '?':
            if ((optopt == 'a') || (optopt == 'b') || (optopt = 'c') ||
                    (optopt == 'd') || (optopt == 'f') || (optopt = 'p') ||
                    (optopt == 't') || (optopt == 'm'))
                fprintf (stderr, " mz/getopts: Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
                fprintf (stderr, " mz/getopts: Unknown option -%c'.\n", optopt);
            else
                fprintf (stderr, " mz/getopts: Unknown option character \\x%x'.\n", optopt);
            return 1;
        default:
            fprintf (stderr," mz/getopts: Could not handle arguments properly!\n");
            return 1;
        }

    // ********************************************
    //       Handle additional arguments
    // ********************************************
    //
    // Greeting text
    if (verbose) {
        fprintf(stderr,"\n"
                MAUSEZAHN_VERSION
                "\n"
                "Use at your own risk and responsibility!\n"
                "-- Verbose mode --\n"
                "\n");
    }

    if (argc<2) {
        usage();
    }

    if ((rargs=argc-optind)>2) {  // number of remaining arguments
        fprintf(stderr," mz/getopts: Too many arguments!\n");
        return -1;
    }


    // There can be 0-2 additional arguments
    switch (rargs) {
    case 0:
        if (lookupdev()) { // no device found
            if (verbose) fprintf(stderr, " mz: no active interfaces found!\n");
            strcpy(tx.device, "lo");
        }
        fprintf(stderr," mz: You must specify an interface. Use ifconfig and try again.\n");
        exit(0);
    case 1: // arg_string OR device given => find out!
        if ( dev_exists(argv[optind]) )
        {
            strncpy (tx.device, argv[optind], 16);
        }
        else
        {   /// arg_string given => no device has been specified -- let's find one!
            strncpy (tx.arg_string, argv[optind], MAX_PAYLOAD_SIZE);
            if (lookupdev())
            {   // no device found
                if (verbose) fprintf(stderr, " mz: no active interfaces found!\n");
                strcpy(tx.device, "lo");
            }
            fprintf(stderr," mz: You must specify a valid interface. Use ifconfig and try again.\n");
            exit(0);
        }
        break;
    case 2: // both device and arg_string given
        if(dev_exists(argv[optind]))
        {
            strncpy (tx.device, argv[optind], 16);
            strncpy (tx.arg_string, argv[optind+1], MAX_PAYLOAD_SIZE);
        }
        else if(dev_exists(argv[optind+1]))
        {
            strncpy (tx.device, argv[optind+1], 16);
            strncpy (tx.arg_string, argv[optind], MAX_PAYLOAD_SIZE);
        }
        else
        {
            if (lookupdev()) { // no device found
                if (verbose) fprintf(stderr, " mz: no active interfaces found!\n");
                strcpy(tx.device, "lo");
            }
            fprintf(stderr," mz: You must specify a valid interface. Use ifconfig and try again.\n");
            exit(0);
        }
        break;
    default:
        fprintf(stderr," mz/getopts: Unknown argument problem!\n");
        return 1;
    }
    if(verbose)
    {
        if(tx.device) fprintf(stderr," mz: Selected interface: %s\n",tx.device );
        if(tx.arg_string) fprintf(stderr," mz: Selected argument string: %s\n", tx.arg_string);
    }

    if (hexpld_specified) {
        strcat(tx.arg_string, ",p=");
        strcat(tx.arg_string, hexpld);
    }


    //////////////////////////////////////////////////////////////////////////
    //
    // Initialize MAC and IP Addresses.
    //
    // - tx.eth_src = own interface MAC
    // - tx.ip_src  = own interface IP or user specified
    // - tx.ip_dst  = 255.255.255.255 or user specified (can be a range)
    // - tx.ip_src_rand ... is set if needed.
    //

    // Get own device MAC address:
    // Don't open context if only a help text is requested
    if  (getarg(tx.arg_string,"help", NULL)!=1) {
        l = libnet_init (LIBNET_LINK_ADV, tx.device, err_buf );
        if (l == NULL) {
            fprintf(stderr, " mz/getopts: libnet_init() failed (%s)", err_buf);
            return -1;
        }
        mymac = libnet_get_hwaddr(l);
        for (i=0; i<6; i++) {
            tx.eth_src[i] = mymac->ether_addr_octet[i];
            tx.eth_mac_own[i] = mymac->ether_addr_octet[i];
        }

        // Set source IP address:
        if (strlen(tx.ip_src_txt)) { // option -A has been specified
            if (mz_strcmp(tx.ip_src_txt, "bcast", 2)==0) {
                tx.ip_src = libnet_name2addr4 (l, "255.255.255.255", LIBNET_DONT_RESOLVE);
            } else if (strcmp(tx.ip_src_txt, "rand") == 0) {
                tx.ip_src_rand = 1;
                tx.ip_src_h  = (u_int32_t) ( ((float) rand()/RAND_MAX)*0xE0000000); //this is 224.0.0.0
            }
            else if (get_ip_range_src(tx.ip_src_txt)) { // returns 1 when no range has been specified
                // name2addr4 accepts a DOTTED DECIMAL ADDRESS or a FQDN:
                tx.ip_src = libnet_name2addr4 (l, tx.ip_src_txt, LIBNET_RESOLVE);
            }
        }
        else { // no source IP specified: by default use own IP address
            tx.ip_src = libnet_get_ipaddr4(l);
        }

        // Set destination IP address:
        if (strlen(tx.ip_dst_txt)) {  // option -B has been specified
            if (mz_strcmp(tx.ip_dst_txt, "rand", 2)==0) {
                fprintf(stderr, "Option -B does not support random destination IP addresses currently.\n");
                return 1;
            }

            if (mz_strcmp(tx.ip_dst_txt, "bcast", 2)==0) {
                tx.ip_dst = libnet_name2addr4 (l, "255.255.255.255", LIBNET_DONT_RESOLVE);
            } else if (get_ip_range_dst(tx.ip_dst_txt)) { // returns 1 when no range has been specified
                // name2addr4 accepts a DOTTED DECIMAL ADDRESS or a FQDN:
                tx.ip_dst = libnet_name2addr4 (l, tx.ip_dst_txt, LIBNET_RESOLVE);
            }
        }
        else { // no destination IP specified: by default use broadcast
            tx.ip_dst = libnet_name2addr4 (l, "255.255.255.255", LIBNET_DONT_RESOLVE);
        }

        // Initialize tx.ip_src_h and tx.ip_dst_h which are used by 'print_frame_details()'
        // in verbose mode. See 'modifications.c'.

        if (tx.ip_src_rand) { // ip_src_h already given, convert to ip_src
            dum1 = (unsigned char*) &tx.ip_src_h;
            dum2 = (unsigned char*) &tx.ip_src;
        }
        else { // ip_src already given, convert to ip_src_h
            dum1 = (unsigned char*) &tx.ip_src;
            dum2 = (unsigned char*) &tx.ip_src_h;
        }

        *dum2 = *(dum1+3);
        dum2++;
        *dum2 = *(dum1+2);
        dum2++;
        *dum2 = *(dum1+1);
        dum2++;
        *dum2 = *dum1;

        dum1 = (unsigned char*) &tx.ip_dst;
        dum2 = (unsigned char*) &tx.ip_dst_h;

        *dum2 = *(dum1+3);
        dum2++;
        *dum2 = *(dum1+2);
        dum2++;
        *dum2 = *(dum1+1);
        dum2++;
        *dum2 = *dum1;

        libnet_destroy(l);
    }

    //
    // END OF ADDRESS INITIALIZATION
    //
    //////////////////////////////////////////////////////////////////////////


    ////// retrieve interface parameters ///////

    for (i=0; i<device_list_entries; i++) {
        get_dev_params(device_list[i].dev);
    }


    //////////////////////////////////////////////////////////////////////////
    //
    //  Mausezahn CLI desired?
    if (mz_port) {
        // has port number been specified?
        if (strlen(tx.arg_string)) {
            mz_port = (int) str2int (tx.arg_string);
        }

        if (!quiet) {
            fprintf(stderr, "Mausezahn accepts incoming Telnet connections on port %i.\n", mz_port);
        }

        mz_cli_init();
        cli();
    }

    //////////////////////////////////////////////////////////////////////////
    //
    //                 Mode decision
    //
    // Consider -t and -m option (used exclusively)
    //   -t => special packet types, stateless
    //
    // If -t not present then evaluate arg_string which must
    // contain a byte-string in hexadecimal notation.
    //
    //

    // ***** NEW: MOPS TRANSITION STRATEGY *****
    if (mops_type != NULL) {

        if (mz_strcmp(mops_type,"lldp",4)==0) {
            mops_direct(tx.device, MOPS_LLDP, tx.arg_string);
        }
    }


    if (packet_type == NULL) { // raw hex string given
        mode = BYTE_STREAM;
    }
    else if (strcmp(packet_type,"arp")==0) {
        mode = ARP;
    }
    else if (strcmp(packet_type,"bpdu")==0) {
        mode = BPDU;
    }
    else if (strcmp(packet_type,"ip")==0) {
        mode = IP;
    }
    else if (strcmp(packet_type,"udp")==0) {
        mode = UDP;
    }
    else if (strcmp(packet_type,"icmp")==0) {
        mode = ICMP;
    }
    else if (strcmp(packet_type,"tcp")==0) {
        mode = TCP;
    }
    else if (strcmp(packet_type,"dns")==0) {
        mode = DNS;
    }
    else if (strcmp(packet_type,"cdp")==0) {
        mode = CDP;
    }
    else if (strcmp(packet_type,"syslog")==0) {
        mode = SYSLOG;
    }
    else if (strcmp(packet_type,"lldp")==0) {
        mode = LLDP;
        tx.packet_mode=0; // create whole frame by ourself
    }
    else if (strcmp(packet_type,"rtp")==0) {
        if (RX) {
            mode = RX_RTP;
        }
        else {
            mode = RTP;
            if (!count_set) tx.count = 0;
            if (!delay_set) tx.delay = 20000; // 20 msec inter-packet delay for RTP
        }
    }
    else if (strcmp(packet_type,"help")==0) {
        fprintf(stderr, "\n"
                MAUSEZAHN_VERSION
                "\n"
                "|  The following packet types are currently implemented:\n"
                "|\n"
                "|  arp            ... sends ARP packets\n"
                "|  bpdu           ... sends BPDU packets (STP or PVST+)\n"
                "|  cdp            ... sends CDP messages\n"
                "|  ip             ... sends IPv4 packets\n"
                "|  udp            ... sends UDP datagrams\n"
                "|  tcp            ... sends TCP segments\n"
                "|  icmp           ... sends ICMP messages\n"
                "|  dns            ... sends DNS messages\n"
                "|  rtp            ... sends RTP datagrams\n"
                "|  syslog         ... sends Syslog messages\n"
                "|\n"
                "| Of course you can build any other packet type 'manually' using the direct layer 2 mode.\n"
                "| FYI: The interactive mode supports additional protocols. (Try mz -x <port>)\n"
                "\n"
               );
        exit(1);
    }
    else {
        fprintf(stderr, " mz: you must specify a valid packet type!\n");
    }


    //////////////////////////////////////////////////////////////////////////

    // TODO: Implement macro support
    //       Check macro types here

    return 0;

}