summaryrefslogtreecommitdiff
path: root/staging/mops_ext.c
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-05-13 13:53:27 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-05-13 15:10:16 +0200
commitd0009856814c13d13770db5aadd7b2fabf947776 (patch)
tree6d18a94439f27f3c2685f05c57435116673f40cc /staging/mops_ext.c
parent2b100f7515dbd01032967c2d1b81d2f8d63bf9b5 (diff)
staging: add mausezahn staging directory
After some back and forth, we decided that it is easier to maintain mausezahn in a staging directory until it is fully reworked and cleaned up to be ready to be fully integrated. This way, it is better than having it in a separate branch, and we can also accept patches from outside more easily. Also, while at it, fix up some function mismatches with libcli. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'staging/mops_ext.c')
-rw-r--r--staging/mops_ext.c466
1 files changed, 466 insertions, 0 deletions
diff --git a/staging/mops_ext.c b/staging/mops_ext.c
new file mode 100644
index 0000000..0a32a05
--- /dev/null
+++ b/staging/mops_ext.c
@@ -0,0 +1,466 @@
+/*
+ * Mausezahn - A fast versatile traffic generator
+ * Copyright (C) 2008-2010 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
+ *
+*/
+
+
+
+#include "mz.h"
+#include "mops.h"
+
+
+
+// Add protocol descriptor of type ptype
+//
+// Smart behaviour:
+//
+// - If the desired p_desc has been assigned already, we leave everything
+// as it is and return to the calling function (return 0).
+//
+// - If a p_desc of another type has been already assigned, this function
+// clears and frees everything before assigning another p_desc structure.
+//
+int mops_ext_add_pdesc (struct mops *mp, int ptype)
+{
+
+ // 1. check if desired p_desc is already assigned
+ if ( (mp->p_desc != NULL) && (mp->p_desc_type == ptype) ) {
+ return 0;
+ }
+
+ // 2. remove older p_desc
+ if (mp->p_desc_type != MOPS_NO_PDESC) {
+ if (mops_ext_del_pdesc (mp)) return 1;
+ }
+
+ // 3. allocate and assign a p_desp
+ switch (ptype) {
+ case MOPS_ARP:
+ mp->p_desc = ( MOPS_EXT_ARP ) malloc ( sizeof (struct mops_ext_arp ) );
+ mp->p_desc_type = MOPS_ARP;
+ mops_init_pdesc_arp(mp);
+ break;
+ case MOPS_BPDU:
+ mp->p_desc = ( MOPS_EXT_BPDU ) malloc ( sizeof (struct mops_ext_bpdu ) );
+ mp->p_desc_type = MOPS_BPDU;
+ mops_init_pdesc_bpdu(mp);
+ break;
+ case MOPS_CDP:
+ mp->p_desc = ( MOPS_EXT_CDP ) malloc ( sizeof (struct mops_ext_cdp ) );
+ mp->p_desc_type = MOPS_CDP;
+ mops_init_pdesc_cdp(mp);
+ break;
+ case MOPS_DNS:
+ mp->p_desc = ( MOPS_EXT_DNS ) malloc ( sizeof (struct mops_ext_dns ) );
+ mp->p_desc_type = MOPS_DNS;
+ mops_init_pdesc_dns(mp);
+ break;
+ case MOPS_ICMP:
+ mp->p_desc = ( MOPS_EXT_ICMP ) malloc ( sizeof (struct mops_ext_icmp ) );
+ mp->p_desc_type = MOPS_ICMP;
+ mops_init_pdesc_icmp(mp);
+ break;
+ case MOPS_IGMP:
+ mp->p_desc = ( MOPS_EXT_IGMP ) malloc ( sizeof (struct mops_ext_igmp ) );
+ mp->p_desc_type = MOPS_IGMP;
+ mops_init_pdesc_igmp(mp);
+ break;
+ case MOPS_RTP:
+ mp->p_desc = ( MOPS_EXT_RTP ) malloc ( sizeof (struct mops_ext_rtp ) );
+ mp->p_desc_type = MOPS_RTP;
+ mops_init_pdesc_rtp(mp);
+ break;
+ case MOPS_LLDP:
+ mp->p_desc = ( MOPS_EXT_LLDP ) malloc ( sizeof (struct mops_ext_lldp ) );
+ ((struct mops_ext_lldp *)mp->p_desc)->chassis_id = NULL;
+ ((struct mops_ext_lldp *)mp->p_desc)->port_id = NULL;
+ ((struct mops_ext_lldp *)mp->p_desc)->optional_tlvs = NULL;
+ mp->p_desc_type = MOPS_LLDP;
+ mops_init_pdesc_lldp(mp);
+ break;
+ case MOPS_SYSLOG:
+ mp->p_desc = ( MOPS_EXT_SYSLOG ) malloc ( sizeof (struct mops_ext_syslog ) );
+ mp->p_desc_type = MOPS_SYSLOG;
+ mops_init_pdesc_syslog(mp);
+ break;
+ default:
+ return 1; // unknown protocol
+ }
+
+ if (mp->p_desc == NULL) {
+ fprintf (stderr, "mz/mops: could not allocate memory for mops element!\n");
+ mp->p_desc_type = MOPS_NO_PDESC;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+// Delete any protocol descriptor
+// 1) Free memory
+// 2) Reset p_desc and p_desc_type
+//
+int mops_ext_del_pdesc (struct mops *mp)
+{
+
+ mp->p_desc_type = MOPS_NO_PDESC;
+ if (mp->p_desc==NULL) return 1; // already NULL pointer, nothing to free()
+
+ switch (mp->p_desc_type) {
+ case MOPS_ARP:
+ free ( (MOPS_EXT_ARP) mp->p_desc );
+ break;
+ case MOPS_BPDU:
+ free ( (MOPS_EXT_BPDU) mp->p_desc );
+ break;
+ case MOPS_CDP:
+ free ( (MOPS_EXT_CDP) mp->p_desc );
+ break;
+ case MOPS_DNS:
+ free ( (MOPS_EXT_DNS) mp->p_desc );
+ break;
+ case MOPS_ICMP:
+ free ( (MOPS_EXT_ICMP) mp->p_desc );
+ break;
+ case MOPS_IGMP:
+ free ( (MOPS_EXT_IGMP) mp->p_desc );
+ break;
+ case MOPS_RTP:
+ free ( (MOPS_EXT_RTP) mp->p_desc );
+ break;
+ case MOPS_LLDP:
+ if ( ((struct mops_ext_lldp *) mp->p_desc)->chassis_id != NULL)
+ free ( ((struct mops_ext_lldp *) mp->p_desc)->chassis_id);
+ if ( ((struct mops_ext_lldp *) mp->p_desc)->port_id != NULL)
+ free ( ((struct mops_ext_lldp *) mp->p_desc)->port_id);
+ if ( ((struct mops_ext_lldp *) mp->p_desc)->optional_tlvs != NULL)
+ free ( ((struct mops_ext_lldp *) mp->p_desc)->optional_tlvs);
+ free ( (MOPS_EXT_LLDP) mp->p_desc );
+ break;
+ case MOPS_SYSLOG:
+ free ( (MOPS_EXT_SYSLOG) mp->p_desc );
+ break;
+ case MOPS_NO_PDESC: // already cleared?
+ break;
+
+ /* nothing */
+ }
+
+ mp->p_desc = NULL;
+ return 0;
+}
+
+
+// Create msg based on p_desc data.
+// After that call mops_update and the frame is complete.
+int mops_ext_update (struct mops *mp)
+{
+
+ switch (mp->p_desc_type) {
+ case MOPS_ARP:
+ mops_update_arp(mp);
+ break;
+ case MOPS_BPDU:
+ mops_update_bpdu(mp);
+ break;
+ case MOPS_CDP:
+ break;
+ case MOPS_DNS:
+ break;
+ case MOPS_ICMP:
+ break;
+ case MOPS_IGMP:
+ mops_update_igmp(mp);
+ break;
+ case MOPS_RTP:
+ mops_update_rtp(mp);
+ break;
+ case MOPS_LLDP:
+ mops_update_lldp(mp);
+ break;
+ case MOPS_SYSLOG:
+ break;
+ case MOPS_NO_PDESC:
+ return 0; // OK!
+ break;
+ default:
+ return 1; // Unknown value!?
+ }
+
+ return 0;
+}
+
+
+//////// General parameter update functions - modify a single parameter of p_desc structure
+//
+// 'Standardized' return values:
+//
+// MOPS_PDESC_LOW Value smaller than lower bound - but will set
+// MOPS_PDESC_HIGH Value larger than upper bound - but will set
+//
+// MOPS_PDESC_OVERFLOW Value exceeded possible range
+//
+// MOPS_PDESC_NO_MAC Invalid MAC address
+// MOPS_PDESC_NO_IP Invalid IP address
+//
+// MOPS_PDESC_FAILURE Unspecified problem
+// MOPS_PDESC_SUCCESS = 0 Value assigned properly
+//
+// 'Standardized' format:
+//
+// mops_pdesc_function ( *PDESC_VAR , USER_STRING , LIMITS )
+
+
+
+
+// Assign one or more strings to a single string
+// Practical example: Concatenate multiple tokens from the CLI
+// Will never copy more than 'max' bytes to 'dst'
+//
+// EXAMPLE:
+//
+// mops_pdesc_mstrings (clipkt->description, argv, argc, 20);
+//
+int mops_pdesc_mstrings (char *dst, char* argv[], int argc, int max)
+{
+ int i;
+ char tmp[10000]; // should be sufficient for all purposes here
+
+ dst[0]=0x00;
+ tmp[0]=0x00;
+
+ for (i=0; i<argc; i++)
+ { // check if next word would exceed tmp:
+ if ((1+strlen(argv[i]))>(10000-strlen(tmp))) // The '1+' counts for the additional space
+ return MOPS_PDESC_OVERFLOW;
+ else
+ {
+ strncat(tmp, argv[i], 80); // Enforcing a maximum word length
+ strcat(tmp, " "); // We get only the tokens, not the spaces inbetween
+ }
+ }
+
+ strncpy(dst, tmp, max);
+ if (strlen(tmp)>max) return MOPS_PDESC_OVERFLOW;
+
+ return MOPS_PDESC_SUCCESS;
+}
+
+
+
+
+
+// Assign decimal or hexadecimal u_int8_t value, depending on spec
+// spec can be 0=dec or 1=hex
+int mops_pdesc_1byte (u_int8_t *dst, char* usr, int spec, int min, int max)
+{
+ u_int32_t i;
+ int retval = MOPS_PDESC_SUCCESS;
+
+ if ((max>255)||(min>255)) return MOPS_PDESC_FAILURE;
+
+ if (spec==0)
+ {
+ i = (u_int32_t) str2int (usr);
+ }
+ else
+ {
+ i = (u_int32_t) xstr2int (usr);
+ }
+
+ if (i>255) return MOPS_PDESC_OVERFLOW;
+ if (i<min)
+ retval = MOPS_PDESC_LOW;
+ else if (i>max)
+ retval = MOPS_PDESC_HIGH;
+
+ *dst = (u_int8_t) i;
+
+ return retval;
+}
+
+
+
+// Assign decimal or hexadecimal u_int16_t value, depending on spec
+// spec can be 0=dec or 1=hex
+int mops_pdesc_2byte (u_int16_t *dst, char* usr, int spec, int min, int max)
+{
+ u_int32_t i;
+ int retval = MOPS_PDESC_SUCCESS;
+
+ if ((max>0xffff)||(min>0xffff)) return MOPS_PDESC_FAILURE;
+
+ if (spec==0)
+ {
+ i = (u_int32_t) str2int (usr);
+ }
+ else
+ {
+ i = (u_int32_t) xstr2int (usr);
+ }
+
+ if (i>0xffff) return MOPS_PDESC_OVERFLOW;
+ if (i<min)
+ retval = MOPS_PDESC_LOW;
+ else if (i>max)
+ retval = MOPS_PDESC_HIGH;
+
+ *dst = (u_int16_t) i;
+
+ return retval;
+}
+
+
+// Assign decimal or hexadecimal u_int32_t value, depending on spec
+// spec can be 0=dec or 1=hex
+int mops_pdesc_4byte (u_int32_t *dst, char* usr, int spec, unsigned long int min, unsigned long int max)
+{
+ unsigned long int i;
+ int retval = MOPS_PDESC_SUCCESS;
+
+ if ((max>0xffffffff)||(min>0xffffffff)) return MOPS_PDESC_FAILURE;
+
+ if (spec==0)
+ {
+ i = str2int (usr);
+ }
+ else
+ {
+ i = xstr2int (usr);
+ }
+
+ if (i>0xffffffff) return MOPS_PDESC_OVERFLOW;
+ if (i<min)
+ retval = MOPS_PDESC_LOW;
+ else if (i>max)
+ retval = MOPS_PDESC_HIGH;
+
+ *dst = (u_int32_t) i;
+
+ return retval;
+}
+
+
+
+// Maps MAC address given in 'usr' (e. g. 00:11:22:aa:bb:cc) into 'dst'
+// which is an u_int8_t array.
+//
+// Returns MOPS_PDESC_FAILURE (=1) upon invalid MAC address
+//
+int mops_pdesc_mac (u_int8_t *dst, char* usr)
+{
+ u_int8_t tmp[6];
+
+ // temporarily backup current value
+ memcpy ((void*) tmp, (void*) dst, 6);
+
+ if (str2hex_mac (usr, dst))
+ {
+ // restore original value
+ memcpy ((void*) dst, (void*) tmp, 6);
+ return MOPS_PDESC_FAILURE;
+ };
+
+ return MOPS_PDESC_SUCCESS;
+}
+
+
+// Maps an IP address string into an byte-array u_int8_t ip[4]
+// Note: the destination is NOT an u_int32_t !!!
+int mops_pdesc_ip (u_int8_t *dst, char* usr)
+{
+ u_int8_t tmp[4];
+ int i, len, j=0;
+
+ // Check if format is correct IPv4:
+ len = strlen(usr);
+ for (i=0; i<len; i++)
+ {
+ if (usr[i]=='.')
+ j++;
+ else if (!isdigit(usr[i]))
+ return MOPS_PDESC_FAILURE;
+ }
+ if (j!=3) return MOPS_PDESC_FAILURE;
+
+ // temporarily backup current value
+ memcpy ((void*) tmp, (void*) dst, 4);
+
+ if (num2hex (usr, dst)!=4)
+ {
+ // restore original value
+ memcpy ((void*) dst, (void*) tmp, 4);
+ return MOPS_PDESC_FAILURE;
+ };
+
+ return MOPS_PDESC_SUCCESS;
+}
+
+
+
+
+
+
+//////// Initialization functions for each protocol descriptor ///////////
+//// Each function expects that an appropriate p_desc is already assigned
+//// Also the p_desc_type should be set already.
+
+
+
+
+
+
+int mops_init_pdesc_cdp(struct mops *mp)
+{
+ if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
+
+
+ return 0;
+}
+
+
+int mops_init_pdesc_dns(struct mops *mp)
+{
+ if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
+
+
+ return 0;
+}
+
+
+int mops_init_pdesc_icmp(struct mops *mp)
+{
+ if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
+
+
+ return 0;
+}
+
+
+
+int mops_init_pdesc_syslog(struct mops *mp)
+{
+ if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
+
+ return 0;
+}
+
+
+
+
+
+