/* * 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 * */ /////////////////////////////////////////////////////////////////////////////////////////// // // Contains various tools for hex-based conversions and manipulation of bytestrings // // str2hex_mac ..... converts "00:01:02:0a:ff:ff" into u_int8_t dst[6] // str2hex ..... converts "1a 00:00-2f" into u_int8_t dst[n] (any length) // num2hex ..... converts "192.16.1.1" into u_int8_t dst[4] // bs2str ..... converts {0,1,10} into "00-01-0A" // getbytes ..... a stupid implementation of memcpy - prefer memcpy instead !!! // str2ip32 ..... converts "192.168.0.1" into 3232235521 (u_int32_t) // str2ip32_rev ..... same but assumes network byte order // type2str ..... converts a u_int16_t into a string, e. g. 0x800 into "08:00" // //////////////////////////////////////////////////////////////////////////////////////////// #include "mz.h" // converts MAC address specified in str into u_int8_t array // Usage: str2hex_mac ( "00:01:02:aa:ff:ee", src_addr ) // Returns 1 if specified MAC address string is invalid, 0 upon success. int str2hex_mac(char* str, u_int8_t *addr) { char *hs; int i; unsigned int test; char tmp[32]; strcpy(tmp,str); // necessary because strtok cannot operate on fixed strings hs=(char*)strtok(tmp,"-:., "); for (i=0; i<6; i++) { test = (unsigned int) strtol (hs, NULL, 16); if (test>0xff) return 1; addr[i]=(u_int8_t) strtol (hs, NULL, 16); hs = strtok(NULL,"-:., "); if ( (hs == NULL ) && (i!=5) ) { // Not a valid MAC address return 1; } } if (hs!=NULL) return 1; // more than 6 bytes return 0; } // Converts ascii hex values (string) into integer array // For example "1a 00:00-2f" will be converted to {26, 0, 0, 47} // // NOTE: n ist the max number of bytes to be converted // // RETURN VALUE: number of bytes converted // or -1 upon failure // int str2hex(char* str, u_int8_t *hp, int n) { char *hs; int curval,i; if (strlen(str)==0) return 0; char tmp[8192]=""; //for very long payloads strncpy(tmp,str,8191); // necessary because strtok cannot operate on fixed strings hs=(char*)strtok(tmp,"-:., "); i=0; do { n--; curval=strtol(hs,NULL,16); if (curval>0xff) return -1; hp[i]=(u_int8_t) curval; i++; } while ((n) && ((hs=(char*)strtok(NULL,"-:., "))!= NULL)); return i; // return the length of the array } // Converts ascii numbers (terminated string) into integer array // Every byte can be specified as integers {0..255} // For example "192.16.1.1" will be converted to {C0, 10, 01, 01} // // NOTE: Returns the number of converted bytes! int num2hex(char* str, u_int8_t *hp) { char *hs; int i; unsigned int curval; if (strlen(str)==0) return 0; char tmp[8192]=""; //for very long payloads strncpy(tmp,str,8192); // necessary because strtok cannot operate on fixed strings hs = (char*) strtok (tmp,"-:., "); i=0; do { curval = (unsigned int) str2int(hs); if (curval<256) { hp[i] = (u_int8_t) curval; i++; } } while ((hs=(char*)strtok(NULL,"-:., "))!= NULL); //hp[i]='\0'; // termination not necessary return i; } // Convert array of integers into string of hex // E.g. {0,1,10} => "00-01-0A" // Useful for verification messages. int bs2str(u_int8_t *bs, char* str, int len) { int i; char t[4]; str[0]='\0'; for (i=0; i 3232235521 u_int32_t str2ip32 (char* str) { u_int32_t ip = 0; unsigned int a,b,c,d; int r; // check whether str really contains an IP address if (strlen(str)<3) return 0; if (str==NULL) return 0; if ((r=sscanf(str,"%i.%i.%i.%i",&a,&b,&c,&d))==0) return 0; if (r==EOF) return 0; /* or an alternative method... // these are the four bytes of a dotted decimal notation IP address: a = (unsigned int) strtol(strtok(str,"."), (char **)NULL, 10); b = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); c = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); d = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); */ if ((a>255)||(b>255)||(c>255)||(d>255)) return 0; ip = d + 256*c + 256*256*b + 256*256*256*a; //check with: //printf("str2ip32 got 4 bytes: %i %i %i %i\n",a,b,c,d); //printf("str2ip32 returned %u\n",ip); return ip; } // Converts an IP address given in 'dotted decimal' into an unsigned 32-bit integer // This version does the same as str2ip32() but in 'network byte order' u_int32_t str2ip32_rev (char* str) { u_int32_t ip = 0; unsigned int a,b,c,d; int r; // check whether str really contains an IP address if (strlen(str)<3) return 0; if (str==NULL) return 0; if ((r=sscanf(str,"%i.%i.%i.%i",&a,&b,&c,&d))==0) return 0; if (r==EOF) return 0; /* or an alternative method... // these are the four bytes of a dotted decimal notation IP address: a = (unsigned int) strtol(strtok(str,"."), (char **)NULL, 10); b = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); c = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); d = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10); */ if ((a>255)||(b>255)||(c>255)||(d>255)) return 0; ip = a + b*256 + c*256*256 + d*256*256*256; //check with: //printf("str2ip32 got 4 bytes: %i %i %i %i\n",a,b,c,d); //printf("str2ip32 returned %u\n",ip); return ip; } // Converts a 2-byte value (e. g. a EtherType field) // into a nice string using hex notation. // Useful for verification messages. // Example: type2str (tx.eth_type, msg) may result in msg="08:00" // Return value: how many hex digits have been found. int type2str(u_int16_t type, char *str) { char hex[8]; int i=0; (void) sprintf (hex, "%x",type); i=strlen(hex); switch (i) { case 1: str[0]='0'; str[1]='0'; str[2]=':'; str[3]='0'; str[4]=hex[0]; str[5]='\0'; break; case 2: str[0]='0'; str[1]='0'; str[2]=':'; str[3]=hex[0]; str[4]=hex[1]; str[5]='\0'; break; case 3: str[0]='0'; str[1]=hex[0]; str[2]=':'; str[3]=hex[1]; str[4]=hex[2]; str[5]='\0'; break; case 4: str[0]=hex[0]; str[1]=hex[1]; str[2]=':'; str[3]=hex[2]; str[4]=hex[3]; str[5]='\0'; break; } return i; }