trafgen: print seed on smoke-test, set seed manually
[netsniff-ng.git] / src / hextools.c
blob0328600281563522950b6df6dd21b4a66d300721
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008 Herbert Haas
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
23 ///////////////////////////////////////////////////////////////////////////////////////////
25 // Contains various tools for hex-based conversions and manipulation of bytestrings
26 //
27 // str2hex_mac ..... converts "00:01:02:0a:ff:ff" into u_int8_t dst[6]
28 // str2hex ..... converts "1a 00:00-2f" into u_int8_t dst[n] (any length)
29 // num2hex ..... converts "192.16.1.1" into u_int8_t dst[4]
30 // bs2str ..... converts {0,1,10} into "00-01-0A"
31 // getbytes ..... a stupid implementation of memcpy - prefer memcpy instead !!!
32 // str2ip32 ..... converts "192.168.0.1" into 3232235521 (u_int32_t)
33 // str2ip32_rev ..... same but assumes network byte order
34 // type2str ..... converts a u_int16_t into a string, e. g. 0x800 into "08:00"
35 //
36 ////////////////////////////////////////////////////////////////////////////////////////////
39 #include "mz.h"
43 // converts MAC address specified in str into u_int8_t array
44 // Usage: str2hex_mac ( "00:01:02:aa:ff:ee", src_addr )
45 // Returns 1 if specified MAC address string is invalid, 0 upon success.
46 int str2hex_mac(char* str, u_int8_t *addr)
48 char *hs;
49 int i;
50 unsigned int test;
51 char tmp[32];
53 strcpy(tmp,str); // necessary because strtok cannot operate on fixed strings
55 hs=(char*)strtok(tmp,"-:., ");
57 for (i=0; i<6; i++)
59 test = (unsigned int) strtol (hs, NULL, 16);
60 if (test>0xff) return 1;
61 addr[i]=(u_int8_t) strtol (hs, NULL, 16);
62 hs = strtok(NULL,"-:., ");
63 if ( (hs == NULL ) && (i!=5) )
65 // Not a valid MAC address
66 return 1;
70 if (hs!=NULL) return 1; // more than 6 bytes
72 return 0;
78 // Converts ascii hex values (string) into integer array
79 // For example "1a 00:00-2f" will be converted to {26, 0, 0, 47}
80 //
81 // NOTE: n ist the max number of bytes to be converted
82 //
83 // RETURN VALUE: number of bytes converted
84 // or -1 upon failure
85 //
86 int str2hex(char* str, u_int8_t *hp, int n)
88 char *hs;
89 int curval,i;
92 if (strlen(str)==0) return 0;
94 char tmp[8192]=""; //for very long payloads
96 strncpy(tmp,str,8191); // necessary because strtok cannot operate on fixed strings
98 hs=(char*)strtok(tmp,"-:., ");
100 i=0;
102 { n--;
103 curval=strtol(hs,NULL,16);
104 if (curval>0xff) return -1;
105 hp[i]=(u_int8_t) curval;
106 i++;
108 while ((n) && ((hs=(char*)strtok(NULL,"-:., "))!= NULL));
110 return i; // return the length of the array
115 // Converts ascii numbers (terminated string) into integer array
116 // Every byte can be specified as integers {0..255}
117 // For example "192.16.1.1" will be converted to {C0, 10, 01, 01}
119 // NOTE: Returns the number of converted bytes!
120 int num2hex(char* str, u_int8_t *hp)
122 char *hs;
123 int i;
124 unsigned int curval;
126 if (strlen(str)==0) return 0;
128 char tmp[8192]=""; //for very long payloads
130 strncpy(tmp,str,8192); // necessary because strtok cannot operate on fixed strings
132 hs = (char*) strtok (tmp,"-:., ");
134 i=0;
137 curval = (unsigned int) str2int(hs);
138 if (curval<256)
140 hp[i] = (u_int8_t) curval;
141 i++;
144 while ((hs=(char*)strtok(NULL,"-:., "))!= NULL);
145 //hp[i]='\0'; // termination not necessary
147 return i;
152 // Convert array of integers into string of hex
153 // E.g. {0,1,10} => "00-01-0A"
154 // Useful for verification messages.
155 int bs2str(u_int8_t *bs, char* str, int len)
157 int i;
158 char t[4];
160 str[0]='\0';
162 for (i=0; i<len; i++)
164 // if (bs[i]<16) strcat(str,"0"); // enforce two hex digits (e.g. "0a")
166 sprintf(t,"%02x:",bs[i]);
167 strcat(str,t);
169 str[strlen(str)-1]='\0'; //remove the last ":"
170 return 1;
174 // Extract contiguous sequence of bytes from an array
175 // NOTE: first element has number 1 !!!
176 // THIS IS DEPRECATED: PREFER memcpy INSTEAD !!!
177 int getbytes(u_int8_t *source,
178 u_int8_t *target,
179 int from,
180 int to)
183 int i;
185 // Check wrong arguments
186 if (from<1)
188 return -1;
191 // copy bytes
192 for (i=0; i<(to-from+1); i++)
194 target[i]=source[from-1+i];
197 return 1;
201 // Converts an IP address given in 'dotted decimal' into an unsigned 32-bit integer
202 // Example: "192.168.0.1" => 3232235521
203 u_int32_t str2ip32 (char* str)
205 u_int32_t ip = 0;
206 unsigned int a,b,c,d;
207 int r;
209 // check whether str really contains an IP address
210 if (strlen(str)<3) return 0;
211 if (str==NULL) return 0;
213 if ((r=sscanf(str,"%i.%i.%i.%i",&a,&b,&c,&d))==0) return 0;
214 if (r==EOF) return 0;
216 /* or an alternative method...
217 // these are the four bytes of a dotted decimal notation IP address:
218 a = (unsigned int) strtol(strtok(str,"."), (char **)NULL, 10);
219 b = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
220 c = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
221 d = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
224 if ((a>255)||(b>255)||(c>255)||(d>255)) return 0;
226 ip = d + 256*c + 256*256*b + 256*256*256*a;
228 //check with:
229 //printf("str2ip32 got 4 bytes: %i %i %i %i\n",a,b,c,d);
230 //printf("str2ip32 returned %u\n",ip);
232 return ip;
236 // Converts an IP address given in 'dotted decimal' into an unsigned 32-bit integer
237 // This version does the same as str2ip32() but in 'network byte order'
238 u_int32_t str2ip32_rev (char* str)
240 u_int32_t ip = 0;
241 unsigned int a,b,c,d;
242 int r;
244 // check whether str really contains an IP address
245 if (strlen(str)<3) return 0;
246 if (str==NULL) return 0;
248 if ((r=sscanf(str,"%i.%i.%i.%i",&a,&b,&c,&d))==0) return 0;
249 if (r==EOF) return 0;
251 /* or an alternative method...
252 // these are the four bytes of a dotted decimal notation IP address:
253 a = (unsigned int) strtol(strtok(str,"."), (char **)NULL, 10);
254 b = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
255 c = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
256 d = (unsigned int) strtol(strtok(NULL,"."), (char **)NULL, 10);
259 if ((a>255)||(b>255)||(c>255)||(d>255)) return 0;
261 ip = a + b*256 + c*256*256 + d*256*256*256;
263 //check with:
264 //printf("str2ip32 got 4 bytes: %i %i %i %i\n",a,b,c,d);
265 //printf("str2ip32 returned %u\n",ip);
267 return ip;
271 // Converts a 2-byte value (e. g. a EtherType field)
272 // into a nice string using hex notation.
273 // Useful for verification messages.
274 // Example: type2str (tx.eth_type, msg) may result in msg="08:00"
275 // Return value: how many hex digits have been found.
276 int type2str(u_int16_t type, char *str)
278 char hex[8];
279 int i=0;
281 (void) sprintf (hex, "%x",type);
282 i=strlen(hex);
284 switch (i)
286 case 1:
287 str[0]='0';
288 str[1]='0';
289 str[2]=':';
290 str[3]='0';
291 str[4]=hex[0];
292 str[5]='\0';
293 break;
294 case 2:
295 str[0]='0';
296 str[1]='0';
297 str[2]=':';
298 str[3]=hex[0];
299 str[4]=hex[1];
300 str[5]='\0';
301 break;
302 case 3:
303 str[0]='0';
304 str[1]=hex[0];
305 str[2]=':';
306 str[3]=hex[1];
307 str[4]=hex[2];
308 str[5]='\0';
309 break;
310 case 4:
311 str[0]=hex[0];
312 str[1]=hex[1];
313 str[2]=':';
314 str[3]=hex[2];
315 str[4]=hex[3];
316 str[5]='\0';
317 break;
320 return i;