trafgen: parser: Add 'drnd()' function for proto fields
[netsniff-ng.git] / staging / mops_ext.c
blob0a32a05c7a3d38a24815d4bd1b4b067436c09148
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 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
21 #include "mz.h"
22 #include "mops.h"
26 // Add protocol descriptor of type ptype
27 //
28 // Smart behaviour:
29 //
30 // - If the desired p_desc has been assigned already, we leave everything
31 // as it is and return to the calling function (return 0).
32 //
33 // - If a p_desc of another type has been already assigned, this function
34 // clears and frees everything before assigning another p_desc structure.
35 //
36 int mops_ext_add_pdesc (struct mops *mp, int ptype)
39 // 1. check if desired p_desc is already assigned
40 if ( (mp->p_desc != NULL) && (mp->p_desc_type == ptype) ) {
41 return 0;
44 // 2. remove older p_desc
45 if (mp->p_desc_type != MOPS_NO_PDESC) {
46 if (mops_ext_del_pdesc (mp)) return 1;
49 // 3. allocate and assign a p_desp
50 switch (ptype) {
51 case MOPS_ARP:
52 mp->p_desc = ( MOPS_EXT_ARP ) malloc ( sizeof (struct mops_ext_arp ) );
53 mp->p_desc_type = MOPS_ARP;
54 mops_init_pdesc_arp(mp);
55 break;
56 case MOPS_BPDU:
57 mp->p_desc = ( MOPS_EXT_BPDU ) malloc ( sizeof (struct mops_ext_bpdu ) );
58 mp->p_desc_type = MOPS_BPDU;
59 mops_init_pdesc_bpdu(mp);
60 break;
61 case MOPS_CDP:
62 mp->p_desc = ( MOPS_EXT_CDP ) malloc ( sizeof (struct mops_ext_cdp ) );
63 mp->p_desc_type = MOPS_CDP;
64 mops_init_pdesc_cdp(mp);
65 break;
66 case MOPS_DNS:
67 mp->p_desc = ( MOPS_EXT_DNS ) malloc ( sizeof (struct mops_ext_dns ) );
68 mp->p_desc_type = MOPS_DNS;
69 mops_init_pdesc_dns(mp);
70 break;
71 case MOPS_ICMP:
72 mp->p_desc = ( MOPS_EXT_ICMP ) malloc ( sizeof (struct mops_ext_icmp ) );
73 mp->p_desc_type = MOPS_ICMP;
74 mops_init_pdesc_icmp(mp);
75 break;
76 case MOPS_IGMP:
77 mp->p_desc = ( MOPS_EXT_IGMP ) malloc ( sizeof (struct mops_ext_igmp ) );
78 mp->p_desc_type = MOPS_IGMP;
79 mops_init_pdesc_igmp(mp);
80 break;
81 case MOPS_RTP:
82 mp->p_desc = ( MOPS_EXT_RTP ) malloc ( sizeof (struct mops_ext_rtp ) );
83 mp->p_desc_type = MOPS_RTP;
84 mops_init_pdesc_rtp(mp);
85 break;
86 case MOPS_LLDP:
87 mp->p_desc = ( MOPS_EXT_LLDP ) malloc ( sizeof (struct mops_ext_lldp ) );
88 ((struct mops_ext_lldp *)mp->p_desc)->chassis_id = NULL;
89 ((struct mops_ext_lldp *)mp->p_desc)->port_id = NULL;
90 ((struct mops_ext_lldp *)mp->p_desc)->optional_tlvs = NULL;
91 mp->p_desc_type = MOPS_LLDP;
92 mops_init_pdesc_lldp(mp);
93 break;
94 case MOPS_SYSLOG:
95 mp->p_desc = ( MOPS_EXT_SYSLOG ) malloc ( sizeof (struct mops_ext_syslog ) );
96 mp->p_desc_type = MOPS_SYSLOG;
97 mops_init_pdesc_syslog(mp);
98 break;
99 default:
100 return 1; // unknown protocol
103 if (mp->p_desc == NULL) {
104 fprintf (stderr, "mz/mops: could not allocate memory for mops element!\n");
105 mp->p_desc_type = MOPS_NO_PDESC;
106 return 1;
109 return 0;
113 // Delete any protocol descriptor
114 // 1) Free memory
115 // 2) Reset p_desc and p_desc_type
117 int mops_ext_del_pdesc (struct mops *mp)
120 mp->p_desc_type = MOPS_NO_PDESC;
121 if (mp->p_desc==NULL) return 1; // already NULL pointer, nothing to free()
123 switch (mp->p_desc_type) {
124 case MOPS_ARP:
125 free ( (MOPS_EXT_ARP) mp->p_desc );
126 break;
127 case MOPS_BPDU:
128 free ( (MOPS_EXT_BPDU) mp->p_desc );
129 break;
130 case MOPS_CDP:
131 free ( (MOPS_EXT_CDP) mp->p_desc );
132 break;
133 case MOPS_DNS:
134 free ( (MOPS_EXT_DNS) mp->p_desc );
135 break;
136 case MOPS_ICMP:
137 free ( (MOPS_EXT_ICMP) mp->p_desc );
138 break;
139 case MOPS_IGMP:
140 free ( (MOPS_EXT_IGMP) mp->p_desc );
141 break;
142 case MOPS_RTP:
143 free ( (MOPS_EXT_RTP) mp->p_desc );
144 break;
145 case MOPS_LLDP:
146 if ( ((struct mops_ext_lldp *) mp->p_desc)->chassis_id != NULL)
147 free ( ((struct mops_ext_lldp *) mp->p_desc)->chassis_id);
148 if ( ((struct mops_ext_lldp *) mp->p_desc)->port_id != NULL)
149 free ( ((struct mops_ext_lldp *) mp->p_desc)->port_id);
150 if ( ((struct mops_ext_lldp *) mp->p_desc)->optional_tlvs != NULL)
151 free ( ((struct mops_ext_lldp *) mp->p_desc)->optional_tlvs);
152 free ( (MOPS_EXT_LLDP) mp->p_desc );
153 break;
154 case MOPS_SYSLOG:
155 free ( (MOPS_EXT_SYSLOG) mp->p_desc );
156 break;
157 case MOPS_NO_PDESC: // already cleared?
158 break;
160 /* nothing */
163 mp->p_desc = NULL;
164 return 0;
168 // Create msg based on p_desc data.
169 // After that call mops_update and the frame is complete.
170 int mops_ext_update (struct mops *mp)
173 switch (mp->p_desc_type) {
174 case MOPS_ARP:
175 mops_update_arp(mp);
176 break;
177 case MOPS_BPDU:
178 mops_update_bpdu(mp);
179 break;
180 case MOPS_CDP:
181 break;
182 case MOPS_DNS:
183 break;
184 case MOPS_ICMP:
185 break;
186 case MOPS_IGMP:
187 mops_update_igmp(mp);
188 break;
189 case MOPS_RTP:
190 mops_update_rtp(mp);
191 break;
192 case MOPS_LLDP:
193 mops_update_lldp(mp);
194 break;
195 case MOPS_SYSLOG:
196 break;
197 case MOPS_NO_PDESC:
198 return 0; // OK!
199 break;
200 default:
201 return 1; // Unknown value!?
204 return 0;
208 //////// General parameter update functions - modify a single parameter of p_desc structure
210 // 'Standardized' return values:
212 // MOPS_PDESC_LOW Value smaller than lower bound - but will set
213 // MOPS_PDESC_HIGH Value larger than upper bound - but will set
215 // MOPS_PDESC_OVERFLOW Value exceeded possible range
217 // MOPS_PDESC_NO_MAC Invalid MAC address
218 // MOPS_PDESC_NO_IP Invalid IP address
220 // MOPS_PDESC_FAILURE Unspecified problem
221 // MOPS_PDESC_SUCCESS = 0 Value assigned properly
223 // 'Standardized' format:
225 // mops_pdesc_function ( *PDESC_VAR , USER_STRING , LIMITS )
230 // Assign one or more strings to a single string
231 // Practical example: Concatenate multiple tokens from the CLI
232 // Will never copy more than 'max' bytes to 'dst'
234 // EXAMPLE:
236 // mops_pdesc_mstrings (clipkt->description, argv, argc, 20);
238 int mops_pdesc_mstrings (char *dst, char* argv[], int argc, int max)
240 int i;
241 char tmp[10000]; // should be sufficient for all purposes here
243 dst[0]=0x00;
244 tmp[0]=0x00;
246 for (i=0; i<argc; i++)
247 { // check if next word would exceed tmp:
248 if ((1+strlen(argv[i]))>(10000-strlen(tmp))) // The '1+' counts for the additional space
249 return MOPS_PDESC_OVERFLOW;
250 else
252 strncat(tmp, argv[i], 80); // Enforcing a maximum word length
253 strcat(tmp, " "); // We get only the tokens, not the spaces inbetween
257 strncpy(dst, tmp, max);
258 if (strlen(tmp)>max) return MOPS_PDESC_OVERFLOW;
260 return MOPS_PDESC_SUCCESS;
267 // Assign decimal or hexadecimal u_int8_t value, depending on spec
268 // spec can be 0=dec or 1=hex
269 int mops_pdesc_1byte (u_int8_t *dst, char* usr, int spec, int min, int max)
271 u_int32_t i;
272 int retval = MOPS_PDESC_SUCCESS;
274 if ((max>255)||(min>255)) return MOPS_PDESC_FAILURE;
276 if (spec==0)
278 i = (u_int32_t) str2int (usr);
280 else
282 i = (u_int32_t) xstr2int (usr);
285 if (i>255) return MOPS_PDESC_OVERFLOW;
286 if (i<min)
287 retval = MOPS_PDESC_LOW;
288 else if (i>max)
289 retval = MOPS_PDESC_HIGH;
291 *dst = (u_int8_t) i;
293 return retval;
298 // Assign decimal or hexadecimal u_int16_t value, depending on spec
299 // spec can be 0=dec or 1=hex
300 int mops_pdesc_2byte (u_int16_t *dst, char* usr, int spec, int min, int max)
302 u_int32_t i;
303 int retval = MOPS_PDESC_SUCCESS;
305 if ((max>0xffff)||(min>0xffff)) return MOPS_PDESC_FAILURE;
307 if (spec==0)
309 i = (u_int32_t) str2int (usr);
311 else
313 i = (u_int32_t) xstr2int (usr);
316 if (i>0xffff) return MOPS_PDESC_OVERFLOW;
317 if (i<min)
318 retval = MOPS_PDESC_LOW;
319 else if (i>max)
320 retval = MOPS_PDESC_HIGH;
322 *dst = (u_int16_t) i;
324 return retval;
328 // Assign decimal or hexadecimal u_int32_t value, depending on spec
329 // spec can be 0=dec or 1=hex
330 int mops_pdesc_4byte (u_int32_t *dst, char* usr, int spec, unsigned long int min, unsigned long int max)
332 unsigned long int i;
333 int retval = MOPS_PDESC_SUCCESS;
335 if ((max>0xffffffff)||(min>0xffffffff)) return MOPS_PDESC_FAILURE;
337 if (spec==0)
339 i = str2int (usr);
341 else
343 i = xstr2int (usr);
346 if (i>0xffffffff) return MOPS_PDESC_OVERFLOW;
347 if (i<min)
348 retval = MOPS_PDESC_LOW;
349 else if (i>max)
350 retval = MOPS_PDESC_HIGH;
352 *dst = (u_int32_t) i;
354 return retval;
359 // Maps MAC address given in 'usr' (e. g. 00:11:22:aa:bb:cc) into 'dst'
360 // which is an u_int8_t array.
362 // Returns MOPS_PDESC_FAILURE (=1) upon invalid MAC address
364 int mops_pdesc_mac (u_int8_t *dst, char* usr)
366 u_int8_t tmp[6];
368 // temporarily backup current value
369 memcpy ((void*) tmp, (void*) dst, 6);
371 if (str2hex_mac (usr, dst))
373 // restore original value
374 memcpy ((void*) dst, (void*) tmp, 6);
375 return MOPS_PDESC_FAILURE;
378 return MOPS_PDESC_SUCCESS;
382 // Maps an IP address string into an byte-array u_int8_t ip[4]
383 // Note: the destination is NOT an u_int32_t !!!
384 int mops_pdesc_ip (u_int8_t *dst, char* usr)
386 u_int8_t tmp[4];
387 int i, len, j=0;
389 // Check if format is correct IPv4:
390 len = strlen(usr);
391 for (i=0; i<len; i++)
393 if (usr[i]=='.')
394 j++;
395 else if (!isdigit(usr[i]))
396 return MOPS_PDESC_FAILURE;
398 if (j!=3) return MOPS_PDESC_FAILURE;
400 // temporarily backup current value
401 memcpy ((void*) tmp, (void*) dst, 4);
403 if (num2hex (usr, dst)!=4)
405 // restore original value
406 memcpy ((void*) dst, (void*) tmp, 4);
407 return MOPS_PDESC_FAILURE;
410 return MOPS_PDESC_SUCCESS;
418 //////// Initialization functions for each protocol descriptor ///////////
419 //// Each function expects that an appropriate p_desc is already assigned
420 //// Also the p_desc_type should be set already.
427 int mops_init_pdesc_cdp(struct mops *mp)
429 if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
432 return 0;
436 int mops_init_pdesc_dns(struct mops *mp)
438 if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
441 return 0;
445 int mops_init_pdesc_icmp(struct mops *mp)
447 if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
450 return 0;
455 int mops_init_pdesc_syslog(struct mops *mp)
457 if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
459 return 0;