/* * 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 sections contains (as alternative to 'send_frame' in send.c) // a layer-2 based flexible sending function. // // Layer-2 modifications such as 802.1Q and MPLS is considered here! // // *************************************************************************** #include "mz.h" libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t t4) { libnet_t *L=NULL; char errbuf[LIBNET_ERRBUF_SIZE]; libnet_ptag_t t=0, tmpls; char argval[128]; u_int8_t et[2]; int et_len; int i=0, j, mlen, mkomma, len, count, offset=0, found_colon=0; char *left, *right; char *f, mtag[64]; char verbose_mpls_string[128]; u_int8_t *packet; u_int32_t packet_s; char *saveptr, *ptrsubstring, substring[16], tmp[4*MAX_8021Q_TAGS]; u_int8_t CoS; // 0..7 u_int16_t vlan; // 12 bit value (0..4095) u_int8_t dot1Q[4*MAX_8021Q_TAGS], *ptr; u_int16_t dot1Q_eth_type=0x8100; int bytecnt=0; int isdot1Q, tcp_seq_delta, dp_isrange, sp_isrange, ip_dst_isrange, ip_src_isrange, eth_src_rand, eth_dst_rand, rtp_mode=0; unsigned int delay; //////////////////////////////////////////////////// // Prepare MPLS header if required if (tx.mpls) { // first check how many labels have been specified: mlen = strlen (tx.mpls_txt); mkomma=0; for (i=0; i 7) { fprintf(stderr, " mz/create_eth_frame: CoS too high, adjusted to 7\n"); CoS = 7; } if (vlan > 4095) { fprintf(stderr, " mz/create_eth_frame: VLAN number too high, adjusted to 4095\n"); vlan = 4095; } // create 4 byte 802.1Q header: dot1Q[bytecnt+0]=0x81; dot1Q[bytecnt+1]=0x00; ptr = (u_int8_t*) &vlan; dot1Q[bytecnt+3]=*ptr; ptr++; *ptr = *ptr ^ (CoS<<5); // add CoS dot1Q[bytecnt+2]=*ptr; //check: //printf("%02x %02x %02x %02x\n",dot1Q[bytecnt+0],dot1Q[bytecnt+1],dot1Q[bytecnt+2],dot1Q[bytecnt+3]); bytecnt+=4; // next tag (note that bytecnt will finally hold the number of used bytes!) } while ( (ptrsubstring = strtok_r(NULL, ",.", &saveptr)) !=NULL); //get all VLAN tags // now create the whole packet: dot1Q_eth_type = 0x8100; //these are also the first two bytes of dot1Q[] bytecnt = bytecnt-2; for (i=0;i use normal 'l' context: { if (eth_dst_rand) rand_addr(tx.eth_dst); if (eth_src_rand) rand_addr(tx.eth_src); t = libnet_build_ethernet (tx.eth_dst, tx.eth_src, tx.eth_type, NULL, 0, l, t); if (verbose) (void) print_frame_details(); libnet_write(l); } // if (verbose) (void) print_frame_details(); if (delay) SLEEP (delay); if (tcp_seq_delta) { if (update_TCP_SQNR(l, t4)==0) // end of range not yet reached { goto AGAIN; } } if (dp_isrange) { if (update_DPORT(l, t4)==0) // end of range not yet reached { goto AGAIN; } } if (sp_isrange) { if (update_SPORT(l, t4)==0) // end of range not yet reached { goto AGAIN; } } if (ip_dst_isrange) { if (update_IP_DA(l, t3)==0) // end of range not yet reached { goto AGAIN; } } if (ip_src_isrange) { if (update_IP_SA(l, t3)==0) // end of range not yet reached { goto AGAIN; } } if (rtp_mode) // update SQNR and Timestamps in RTP header and payload { update_RTP(l, t4); } if (!count) goto AGAIN; } libnet_destroy(l); if (isdot1Q) libnet_destroy(L); return t; } void print_dot1Q_help(void) { fprintf(stderr,"\n" MAUSEZAHN_VERSION "\n" "| 802.1Q header Syntax: -Q tag[,tag[,tag[,...]]]\n" "| where each tag may consist of a CoS value using the syntax:\n" "|\n" "| :\n" "|\n" "| Examples:\n" "|\n" "| # mz -Q 100\n" "| # mz -Q 5:100\n" "| # mz -Q 5:100,200\n" "| # mz -Q 5:100,7:200\n" "| # mz -Q 100,200,300,5:400\n" "\n\n"); exit(0); }