2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008,2009 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
23 // Inserts value in 'flag' (up to 7 bits are useful) into the target
24 // with an optional left-shift. For example if flag contains a 4-bit value
25 // and should be placed within the target in bit positions 3-6 like:
28 // +--+--+--+--+--+--+--+--+
30 // +--+--+--+--+--+--+--+--+
34 // (void) mops_flags ( &target, &flag, 3 );
36 // Note that shift=0 means no shift.
37 inline void mops_flags (u_int8_t
*target
, u_int8_t
*flag
, int shift
)
39 *target
|= (*flag
<< shift
);
44 inline void mops_hton2 (u_int16_t
*host16
, u_int8_t
*net16
)
55 inline void mops_hton4 (u_int32_t
*host32
, u_int8_t
*net32
)
70 // returns new counter index for given packet
71 // or -1 if all counters used already
72 int mops_get_counter (struct mops
*mp
)
76 while (mp
->counter
[i
].offset
)
79 if (i
==MAX_MOPS_COUNTERS_PER_PACKET
) // exceeded range
86 // Adds single byte to msg
87 int mops_msg_add_byte (struct mops
*mp
, u_int8_t data
)
89 mp
->msg
[mp
->msg_s
++] = data
;
94 // Adds bit field in *previous* msg-byte using optional left-shift
95 int mops_msg_add_field (struct mops
*mp
, u_int8_t data
, int shift
)
97 mp
->msg
[mp
->msg_s
-1] |= (data
<< shift
);
102 // Adds two bytes in network byte order to msg
103 int mops_msg_add_2bytes (struct mops
*mp
, u_int16_t data
)
107 mp
->msg
[mp
->msg_s
++] = *(x
+1);
108 mp
->msg
[mp
->msg_s
++] = *(x
);
113 // Adds four bytes in network byte order to msg
114 int mops_msg_add_4bytes (struct mops
*mp
, u_int32_t data
)
118 mp
->msg
[mp
->msg_s
++] = *(x
+3);
119 mp
->msg
[mp
->msg_s
++] = *(x
+2);
120 mp
->msg
[mp
->msg_s
++] = *(x
+1);
121 mp
->msg
[mp
->msg_s
++] = *(x
);
125 // Adds string of bytes with lenght len
126 int mops_msg_add_string (struct mops
*mp
, u_int8_t
*str
, int len
)
128 memcpy((void *) &mp
->msg
[mp
->msg_s
], (void *) str
, len
);
136 // Add counter to message
137 int mops_msg_add_counter (struct mops
*mp
,
138 int random
, // 1=random, 0=use start/stop/step
139 u_int32_t start
, // HOST BYTE ORDER
140 u_int32_t stop
, // HOST BYTE ORDER
141 u_int32_t step
, // HOST BYTE ORDER
142 int bytes
// number of bytes used (1|2|4) - selects hton2 or hton4
148 // check if unsupported byte count
155 i
= mops_get_counter(mp
);
158 // configure counter values
159 mp
->counter
[i
].offset
= mp
->msg_s
;
160 mp
->counter
[i
].random
= random
;
161 mp
->counter
[i
].start
= start
;
162 mp
->counter
[i
].stop
= stop
;
163 mp
->counter
[i
].step
= step
;
164 mp
->counter
[i
].bytes
= bytes
;
165 mp
->counter
[i
].cur
= start
;
166 mp
->counter
[i
].use
= 1;
169 // configure first pointer value
173 mops_msg_add_byte(mp
, (u_int8_t
) start
);
176 mops_msg_add_2bytes(mp
, (u_int16_t
) start
);
179 mops_msg_add_4bytes(mp
, start
);
181 default: // never be reached
190 // Compares two IP addresses byte by byte
191 // returns 0 if identical, 1 if different
193 // Note that this works independent of endianess
194 // as long as both addresses have same endianess.
196 int compare_ip (u_int8_t
*ip1
, u_int8_t
*ip2
)
198 if (*ip1
!= *ip2
) return 1;
199 if (*(ip1
+1) != *(ip2
+1)) return 1;
200 if (*(ip1
+2) != *(ip2
+2)) return 1;
201 if (*(ip1
+3) != *(ip2
+3)) return 1;
207 // Compares two MAC addresses byte by byte
208 // returns 0 if identical, 1 if different
209 int compare_mac (u_int8_t
*mac1
, u_int8_t
*mac2
)
211 if (*mac1
!= *mac2
) return 1;
212 if (*(mac1
+1) != *(mac2
+1)) return 1;
213 if (*(mac1
+2) != *(mac2
+2)) return 1;
214 if (*(mac1
+3) != *(mac2
+3)) return 1;
215 if (*(mac1
+4) != *(mac2
+4)) return 1;
216 if (*(mac1
+5) != *(mac2
+5)) return 1;
222 // Converts a 'struct timespec' value into a human readable string
223 // This stringt is written into 'str' which must be at least a 32 byte
225 int timespec2str(struct timespec
*t
, char *str
)
227 unsigned int d
=0, h
, m
, s
;
230 if ((t
->tv_sec
==0) && (t
->tv_nsec
==0)) {
231 sprintf(str
, "(none)");
236 m
= (t
->tv_sec
- h
*3600)/60;
237 s
= t
->tv_sec
- h
*3600 - m
*60;
242 sprintf(str
, "%u days %02u:%02u:%02u", d
, h
, m
, s
);
247 sprintf(str
, "%02u:%02u:%02u", h
, m
, s
); // ignore nanoseconds if delay is in order of hours
249 sprintf(str
, "%u%s sec", s
, (t
->tv_nsec
>1000000) ? "+" : "");
250 else if (t
->tv_nsec
>1000000)
251 sprintf(str
, "%u msec", (unsigned int) t
->tv_nsec
/1000000);
252 else if (t
->tv_nsec
>1000)
253 sprintf(str
, "%u usec", (unsigned int) t
->tv_nsec
/1000);
255 sprintf(str
, "%lu nsec", t
->tv_nsec
);