summaryrefslogtreecommitdiff
path: root/staging/mops_tools.c
diff options
context:
space:
mode:
Diffstat (limited to 'staging/mops_tools.c')
-rw-r--r--staging/mops_tools.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/staging/mops_tools.c b/staging/mops_tools.c
new file mode 100644
index 0000000..022f45b
--- /dev/null
+++ b/staging/mops_tools.c
@@ -0,0 +1,259 @@
+/*
+ * Mausezahn - A fast versatile traffic generator
+ * Copyright (C) 2008,2009 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"
+
+// Inserts value in 'flag' (up to 7 bits are useful) into the target
+// with an optional left-shift. For example if flag contains a 4-bit value
+// and should be placed within the target in bit positions 3-6 like:
+//
+// 7 6 5 4 3 2 1 0
+// +--+--+--+--+--+--+--+--+
+// | | FLAGS | | | |
+// +--+--+--+--+--+--+--+--+
+//
+// then simply call:
+//
+// (void) mops_flags ( &target, &flag, 3 );
+//
+// Note that shift=0 means no shift.
+inline void mops_flags (u_int8_t *target, u_int8_t *flag, int shift)
+{
+ *target |= (*flag << shift);
+}
+
+
+
+inline void mops_hton2 (u_int16_t *host16, u_int8_t *net16)
+{
+ char *x;
+
+ x = (char*) host16;
+
+ *(net16++) = *(x+1);
+ *net16 = *x;
+}
+
+
+inline void mops_hton4 (u_int32_t *host32, u_int8_t *net32)
+{
+ char *x;
+
+ x = (char*) host32;
+
+ *(net32++) = *(x+3);
+ *(net32++) = *(x+2);
+ *(net32++) = *(x+1);
+ *(net32) = *x;
+}
+
+
+
+
+// returns new counter index for given packet
+// or -1 if all counters used already
+int mops_get_counter (struct mops *mp)
+{
+ int i=0;
+
+ while (mp->counter[i].offset)
+ {
+ i++;
+ if (i==MAX_MOPS_COUNTERS_PER_PACKET) // exceeded range
+ return -1;
+ }
+ return i;
+}
+
+
+// Adds single byte to msg
+int mops_msg_add_byte (struct mops *mp, u_int8_t data)
+{
+ mp->msg[mp->msg_s++] = data;
+ return 0;
+}
+
+
+// Adds bit field in *previous* msg-byte using optional left-shift
+int mops_msg_add_field (struct mops *mp, u_int8_t data, int shift)
+{
+ mp->msg[mp->msg_s -1] |= (data << shift);
+ return 0;
+}
+
+
+// Adds two bytes in network byte order to msg
+int mops_msg_add_2bytes (struct mops *mp, u_int16_t data)
+{
+ char *x;
+ x = (char*) &data;
+ mp->msg[mp->msg_s++] = *(x+1);
+ mp->msg[mp->msg_s++] = *(x);
+ return 0;
+}
+
+
+// Adds four bytes in network byte order to msg
+int mops_msg_add_4bytes (struct mops *mp, u_int32_t data)
+{
+ char *x;
+ x = (char*) &data;
+ mp->msg[mp->msg_s++] = *(x+3);
+ mp->msg[mp->msg_s++] = *(x+2);
+ mp->msg[mp->msg_s++] = *(x+1);
+ mp->msg[mp->msg_s++] = *(x);
+ return 0;
+}
+
+// Adds string of bytes with lenght len
+int mops_msg_add_string (struct mops *mp, u_int8_t *str, int len)
+{
+ memcpy((void *) &mp->msg[mp->msg_s], (void *) str, len);
+ mp->msg_s += len;
+
+ return 0;
+}
+
+
+
+// Add counter to message
+int mops_msg_add_counter (struct mops *mp,
+ int random, // 1=random, 0=use start/stop/step
+ u_int32_t start, // HOST BYTE ORDER
+ u_int32_t stop, // HOST BYTE ORDER
+ u_int32_t step, // HOST BYTE ORDER
+ int bytes // number of bytes used (1|2|4) - selects hton2 or hton4
+ )
+{
+
+ int i;
+
+ // check if unsupported byte count
+ if ( (bytes!=1) &&
+ (bytes!=2) &&
+ (bytes!=4) )
+ return 1;
+
+ // get new counter
+ i = mops_get_counter(mp);
+ if (i==-1) return 1;
+
+ // configure counter values
+ mp->counter[i].offset = mp->msg_s;
+ mp->counter[i].random = random;
+ mp->counter[i].start = start;
+ mp->counter[i].stop = stop;
+ mp->counter[i].step = step;
+ mp->counter[i].bytes = bytes;
+ mp->counter[i].cur = start;
+ mp->counter[i].use = 1;
+
+
+ // configure first pointer value
+ switch (bytes)
+ {
+ case 1:
+ mops_msg_add_byte(mp, (u_int8_t) start);
+ break;
+ case 2:
+ mops_msg_add_2bytes(mp, (u_int16_t) start);
+ break;
+ case 4:
+ mops_msg_add_4bytes(mp, start);
+ break;
+ default: // never be reached
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+// Compares two IP addresses byte by byte
+// returns 0 if identical, 1 if different
+//
+// Note that this works independent of endianess
+// as long as both addresses have same endianess.
+//
+int compare_ip (u_int8_t *ip1, u_int8_t *ip2)
+{
+ if (*ip1 != *ip2) return 1;
+ if (*(ip1+1) != *(ip2+1)) return 1;
+ if (*(ip1+2) != *(ip2+2)) return 1;
+ if (*(ip1+3) != *(ip2+3)) return 1;
+
+ return 0;
+}
+
+
+// Compares two MAC addresses byte by byte
+// returns 0 if identical, 1 if different
+int compare_mac (u_int8_t *mac1, u_int8_t *mac2)
+{
+ if (*mac1 != *mac2) return 1;
+ if (*(mac1+1) != *(mac2+1)) return 1;
+ if (*(mac1+2) != *(mac2+2)) return 1;
+ if (*(mac1+3) != *(mac2+3)) return 1;
+ if (*(mac1+4) != *(mac2+4)) return 1;
+ if (*(mac1+5) != *(mac2+5)) return 1;
+
+ return 0;
+}
+
+
+// Converts a 'struct timespec' value into a human readable string
+// This stringt is written into 'str' which must be at least a 32 byte
+// array.
+int timespec2str(struct timespec *t, char *str)
+{
+ unsigned int d=0, h, m, s;
+
+ // zero delay
+ if ((t->tv_sec==0) && (t->tv_nsec==0)) {
+ sprintf(str, "(none)");
+ return 0;
+ }
+
+ h = t->tv_sec/3600;
+ m = (t->tv_sec - h*3600)/60;
+ s = t->tv_sec - h*3600 - m*60;
+
+ if (h>24) {
+ d = h/24;
+ h = h - d*24;
+ sprintf(str, "%u days %02u:%02u:%02u", d, h, m, s);
+ return 0;
+ }
+
+ if (h|m)
+ sprintf(str, "%02u:%02u:%02u", h, m, s); // ignore nanoseconds if delay is in order of hours
+ else if (s)
+ sprintf(str, "%u%s sec", s, (t->tv_nsec>1000000) ? "+" : "");
+ else if (t->tv_nsec>1000000)
+ sprintf(str, "%u msec", (unsigned int) t->tv_nsec/1000000);
+ else if (t->tv_nsec>1000)
+ sprintf(str, "%u usec", (unsigned int) t->tv_nsec/1000);
+ else
+ sprintf(str, "%lu nsec", t->tv_nsec);
+
+ return 0;
+}
+