/* * Mausezahn - A fast versatile traffic generator * Copyright (C) 2008 Herbert Haas * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html * */ // **************************************************************************** // // This section contains functions to send an arbitrary byte stream out of // the network card. Currently it works perfect for Ethernet cards. // // TODO: Access to the 802.11 header // // **************************************************************************** #include "mz.h" #include "cli.h" int send_eth(void) { // Tasks: // 1. Check 'eth_src_txt' and 'eth_dst_txt' which contain either a MAC address or a keyword // 'eth_dst' can be set without having 'eth_src_txt' specified (the next 6 bytes of the // 'arg_string' will be used). But if 'eth_src_txt' is given then also 'eth_dst_txt' // should have been specified, otherwise a default (ff-ff-ff-ff-ff-ff) will be used. // 2. Check whether 'arg_string' contains a hex-string. If YES then convert it into an // 'eth_payload' and extract eth_type. // 3. Apply 'padding' if specified // 4. Check if frame has at least minimum length (14 Bytes). // 5. Send frame 'count' times and // 6. Apply 'delay' (make precautions for better delay functions) int src, // flag telling whether user has specified a source address dst, // flag telling whether user has specified a destination address src_random=0, dst_random=0, byte_ptr=1, bytestring_s=0, min_size=15, pad=0, repeat, loop, update, i=0, j=0; char err_buf[LIBNET_ERRBUF_SIZE], message[MAX_PAYLOAD_SIZE*3], argval[MAX_PAYLOAD_SIZE*2]; u_int8_t bytestring[MAX_PAYLOAD_SIZE]; libnet_ptag_t t; libnet_t *l; if (tx.dot1Q) { fprintf(stderr," Note: raw layer 2 mode does not support 802.1Q builder.\n" " If you want to create VLAN tags then you must do it by hand.\n"); exit(1); } if (tx.mpls) { fprintf(stderr," Note: raw layer 2 mode does not support MPLS builder.\n" " If you want to create MPLS labels then you must do it by hand.\n"); exit(1); } // So other functions can use this function for sending Ethernet frames // These other functions must set dst, src, type and payload! if (tx.eth_params_already_set) goto ALL_SPECIFIED; if ((tx.padding) && (tx.padding<15)) // Note: ignored if padding==0 { tx.padding=15; if (mz_port) { cli_print(gcli, "Note: Set padding to 15 bytes (total length)\n"); } else fprintf(stderr, " mz/send_eth: [Note] adjusted minimum frame size to 15 bytes.\n"); } // Create a temporal, local bytestring: // for (i=0; i=6) { (void) getbytes (bytestring, tx.eth_src, byte_ptr, byte_ptr+5); byte_ptr=7; // now points to eth_type within bytestring } } // FINALLY: If both dst and src have NOT been specified: // if ((!dst) && (!src)) { if (bytestring_s>=6) { (void) getbytes (bytestring, tx.eth_dst, byte_ptr, byte_ptr+5); byte_ptr=7; } if (bytestring_s>=12) { (void) getbytes (bytestring, tx.eth_src, byte_ptr, byte_ptr+5); byte_ptr=13; // points to eth_type } } // Set eth_type: // if (bytestring_s>=2) { tx.eth_type = 256 * bytestring[byte_ptr-1] + bytestring[byte_ptr]; // don't forget: byte_ptr counts from 1 not 0 byte_ptr+=2; // points to first payload byte (if available) } // Get remaining payload: // if ( (tx.eth_payload_s = bytestring_s - byte_ptr +1) > 0 ) // if there are any remaining bytes { (void) getbytes (bytestring, tx.eth_payload, byte_ptr, bytestring_s); } // Add padding if desired. // Note: padding means 'extend to given length' (not 'add these number of bytes') if (tx.padding) { pad = tx.padding - (14 + tx.eth_payload_s); // number of additonal pad bytes required for (i=0; i