2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
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.
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
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
26 // Add protocol descriptor of type ptype
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).
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.
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
) ) {
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
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
;
113 // Delete any protocol descriptor
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
) {
125 free ( (MOPS_EXT_ARP
) mp
->p_desc
);
128 free ( (MOPS_EXT_BPDU
) mp
->p_desc
);
131 free ( (MOPS_EXT_CDP
) mp
->p_desc
);
134 free ( (MOPS_EXT_DNS
) mp
->p_desc
);
137 free ( (MOPS_EXT_ICMP
) mp
->p_desc
);
140 free ( (MOPS_EXT_IGMP
) mp
->p_desc
);
143 free ( (MOPS_EXT_RTP
) mp
->p_desc
);
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
);
155 free ( (MOPS_EXT_SYSLOG
) mp
->p_desc
);
157 case MOPS_NO_PDESC
: // already cleared?
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
) {
178 mops_update_bpdu(mp
);
187 mops_update_igmp(mp
);
193 mops_update_lldp(mp
);
201 return 1; // Unknown value!?
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'
236 // mops_pdesc_mstrings (clipkt->description, argv, argc, 20);
238 int mops_pdesc_mstrings (char *dst
, char* argv
[], int argc
, int max
)
241 char tmp
[10000]; // should be sufficient for all purposes here
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
;
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
)
272 int retval
= MOPS_PDESC_SUCCESS
;
274 if ((max
>255)||(min
>255)) return MOPS_PDESC_FAILURE
;
278 i
= (u_int32_t
) str2int (usr
);
282 i
= (u_int32_t
) xstr2int (usr
);
285 if (i
>255) return MOPS_PDESC_OVERFLOW
;
287 retval
= MOPS_PDESC_LOW
;
289 retval
= MOPS_PDESC_HIGH
;
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
)
303 int retval
= MOPS_PDESC_SUCCESS
;
305 if ((max
>0xffff)||(min
>0xffff)) return MOPS_PDESC_FAILURE
;
309 i
= (u_int32_t
) str2int (usr
);
313 i
= (u_int32_t
) xstr2int (usr
);
316 if (i
>0xffff) return MOPS_PDESC_OVERFLOW
;
318 retval
= MOPS_PDESC_LOW
;
320 retval
= MOPS_PDESC_HIGH
;
322 *dst
= (u_int16_t
) i
;
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
)
333 int retval
= MOPS_PDESC_SUCCESS
;
335 if ((max
>0xffffffff)||(min
>0xffffffff)) return MOPS_PDESC_FAILURE
;
346 if (i
>0xffffffff) return MOPS_PDESC_OVERFLOW
;
348 retval
= MOPS_PDESC_LOW
;
350 retval
= MOPS_PDESC_HIGH
;
352 *dst
= (u_int32_t
) i
;
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
)
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
)
389 // Check if format is correct IPv4:
391 for (i
=0; i
<len
; i
++)
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
436 int mops_init_pdesc_dns(struct mops
*mp
)
438 if (mp
->p_desc
== NULL
) return 1; // p_desc not properly assigned
445 int mops_init_pdesc_icmp(struct mops
*mp
)
447 if (mp
->p_desc
== NULL
) return 1; // p_desc not properly assigned
455 int mops_init_pdesc_syslog(struct mops
*mp
)
457 if (mp
->p_desc
== NULL
) return 1; // p_desc not properly assigned