diff options
Diffstat (limited to 'staging/hextools.c')
-rw-r--r-- | staging/hextools.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/staging/hextools.c b/staging/hextools.c new file mode 100644 index 0000000..0328600 --- /dev/null +++ b/staging/hextools.c @@ -0,0 +1,322 @@ +/* + * 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<len; i++) + { +// if (bs[i]<16) strcat(str,"0"); // enforce two hex digits (e.g. "0a") + + sprintf(t,"%02x:",bs[i]); + strcat(str,t); + } + str[strlen(str)-1]='\0'; //remove the last ":" + return 1; +} + + +// Extract contiguous sequence of bytes from an array +// NOTE: first element has number 1 !!! +// THIS IS DEPRECATED: PREFER memcpy INSTEAD !!! +int getbytes(u_int8_t *source, + u_int8_t *target, + int from, + int to) + +{ + int i; + + // Check wrong arguments + if (from<1) + { + return -1; + } + + // copy bytes + for (i=0; i<(to-from+1); i++) + { + target[i]=source[from-1+i]; + } + + return 1; +} + + +// Converts an IP address given in 'dotted decimal' into an unsigned 32-bit integer +// Example: "192.168.0.1" => 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; +} + |