summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Croce <mcroce@redhat.com>2018-08-21 16:38:09 +0200
committerTobias Klauser <tklauser@distanz.ch>2018-08-22 10:21:37 +0200
commitc7c176394ad2b87f56b0aed2731eb9dde29750f0 (patch)
tree1c423f98bc7ac52feb134044efeed38ccc6d0507
parent01f339a7bb170310f9dd6a389d9c89b6c62032d0 (diff)
mausezahn: improve random mac address generation
Modify -b option to generate all random MAC addresses. Improve the random generation algorithm, use nrand48() which fills the ethernet address in two calls instead of six calls to rand() and six floating point calculations. Set the locally administered bit of generated MAC addresses. Signed-off-by: Matteo Croce <mcroce@redhat.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--mausezahn.810
-rw-r--r--staging/mausezahn.c1
-rw-r--r--staging/modifications.c39
-rw-r--r--staging/mz.h6
-rw-r--r--staging/send_eth.c16
-rw-r--r--staging/tools.c8
6 files changed, 33 insertions, 47 deletions
diff --git a/mausezahn.8 b/mausezahn.8
index 1ad7667..44a76ab 100644
--- a/mausezahn.8
+++ b/mausezahn.8
@@ -105,18 +105,16 @@ higher layer packets the number of additional padding bytes are specified.
.PP
.SS -a <src-mac|keyword>
Use specified source MAC address with hexadecimal notation such as 00:00:aa:bb:cc:dd.
-By default the interface MAC address will be used. The keywords ''rand'' and
- ''own'' refer to a random MAC address (only unicast addresses are created)
+By default the interface MAC address will be used. The keywords ''rand'' and ''own''
+refer to a random MAC address (only unicast addresses are created)
and the own address, respectively. You can also use the keywords mentioned
below although broadcast-type source addresses are officially invalid.
.PP
.SS -b <dst-mac|keyword>
Use specified destination MAC address. By default, a broadcast is sent in raw
layer 2 mode or to the destination hosts or gateway interface MAC address in normal
-(IP) mode. You can use the same keywords as mentioned above, as well as
- ''bc'' or ''bcast'', ''cisco'', and ''stp''. Please note that for the destination
-MAC address the ''rand'' keyword is supported but creates a random address only
-once, even when you send multiple packets.
+(IP) mode. You can use the same keywords as mentioned above, as well as ''bc''
+or ''bcast'', ''cisco'', and ''stp''.
.PP
.SS -A <src-ip|range|rand>
Use specified source IP address, default is own interface address. Optionally, the
diff --git a/staging/mausezahn.c b/staging/mausezahn.c
index d3d037b..80bfe7d 100644
--- a/staging/mausezahn.c
+++ b/staging/mausezahn.c
@@ -339,6 +339,7 @@ int reset(void)
// Initialize random generator
time(&t);
srand((unsigned int)t);
+ srand48(t);
// Reset device_list
for (i=0; i<MZ_MAX_DEVICES; i++) {
diff --git a/staging/modifications.c b/staging/modifications.c
index 1affbbb..b105db0 100644
--- a/staging/modifications.c
+++ b/staging/modifications.c
@@ -24,7 +24,7 @@
// This sections contains functions to manipulate headers of
// Eth, MPLS, 802.1Q, IP, UDP, and TCP:
//
-// int update_Eth_SA (libnet_t *l, libnet_ptag_t t)
+// int rand_addr (u_int8_t *addr)
// int update_IP_SA (libnet_t *l, libnet_ptag_t t)
// int update_IP_DA (libnet_t *l, libnet_ptag_t t)
// int update_IP6_SA (libnet_t *l, libnet_ptag_t t)
@@ -42,36 +42,19 @@
#include "mz.h"
#include "mops.h"
-///////////////////////////////////////////////////////////////////////////
-// Applies another random Ethernet source address to a given Ethernet-PTAG.
-// (The calling function should check 'tx.eth_src_rand' whether the SA
+// Applies another random address to a given buffer.
+// (The calling function should check 'tx.eth_(dst|src)_rand' whether the address
// should be randomized.)
-//
-int update_Eth_SA(libnet_t *l, libnet_ptag_t t)
+void rand_addr(u_int8_t *addr)
{
- tx.eth_src[0] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256) & 0xFE; // keeps bcast-bit zero
- tx.eth_src[1] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- tx.eth_src[2] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- tx.eth_src[3] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- tx.eth_src[4] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- tx.eth_src[5] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
-
- t = libnet_build_ethernet (tx.eth_dst,
- tx.eth_src,
- tx.eth_type,
- NULL, // the payload
- 0,
- l,
- t);
+ nrand48((unsigned short *)addr);
+ nrand48((unsigned short *)(addr + 3));
- if (t == -1)
- {
- fprintf(stderr, " mz/update_Eth_SA: Can't build Ethernet header: %s\n",
- libnet_geterror(l));
- exit(EXIT_FAILURE);
- }
-
- return 0;
+ // Get rid of multicast addresses
+ addr[0] &= 0xfe;
+
+ // Set the locally administered bit
+ addr[0] |= 2;
}
diff --git a/staging/mz.h b/staging/mz.h
index aa2c36f..6d98ad0 100644
--- a/staging/mz.h
+++ b/staging/mz.h
@@ -726,10 +726,10 @@ int get_mpls_params(char *params);
int exists(char* str, char* ch);
-// Applies another random Ethernet source address to a given Ethernet-PTAG.
-// (The calling function should check 'tx.eth_src_rand' whether the SA
+// Applies another random address to a given buffer.
+// (The calling function should check 'tx.eth_(dst|src)_rand' whether the address
// should be randomized.)
-int update_Eth_SA(libnet_t *l, libnet_ptag_t t);
+void rand_addr(u_int8_t *addr);
// Update timestamp and sequence number in the RTP header.
diff --git a/staging/send_eth.c b/staging/send_eth.c
index ae811e8..b20fb03 100644
--- a/staging/send_eth.c
+++ b/staging/send_eth.c
@@ -55,7 +55,7 @@ libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t
u_int16_t dot1Q_eth_type=0x8100;
int bytecnt=0;
- int isdot1Q, tcp_seq_delta, dp_isrange, sp_isrange, ip_dst_isrange, ip_src_isrange, eth_src_rand, rtp_mode=0;
+ int isdot1Q, tcp_seq_delta, dp_isrange, sp_isrange, ip_dst_isrange, ip_src_isrange, eth_src_rand, eth_dst_rand, rtp_mode=0;
unsigned int delay;
@@ -341,6 +341,7 @@ libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t
count = tx.count;
delay = tx.delay;
eth_src_rand = tx.eth_src_rand;
+ eth_dst_rand = tx.eth_dst_rand;
tcp_seq_delta = tx.tcp_seq_delta;
dp_isrange = tx.dp_isrange;
sp_isrange = tx.sp_isrange;
@@ -374,7 +375,8 @@ libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t
// to libnet_adv_free_packet() should be made to free the memory packet occupies:
libnet_adv_free_packet(l, packet);
- if (eth_src_rand) update_Eth_SA(L, t);
+ if (eth_dst_rand) rand_addr(tx.eth_dst);
+ if (eth_src_rand) rand_addr(tx.eth_src);
t = libnet_build_ethernet (tx.eth_dst,
tx.eth_src,
@@ -394,7 +396,15 @@ libnet_ptag_t create_eth_frame (libnet_t *l, libnet_ptag_t t3, libnet_ptag_t
}
else // No QinQ and/or MPLS modifications => use normal 'l' context:
{
- if (eth_src_rand) update_Eth_SA(l, t);
+ if (eth_dst_rand) rand_addr(tx.eth_dst);
+ if (eth_src_rand) rand_addr(tx.eth_src);
+ t = libnet_build_ethernet (tx.eth_dst,
+ tx.eth_src,
+ tx.eth_type,
+ NULL,
+ 0,
+ l,
+ t);
if (verbose) (void) print_frame_details();
libnet_write(l);
}
diff --git a/staging/tools.c b/staging/tools.c
index 72445b6..f7c4131 100644
--- a/staging/tools.c
+++ b/staging/tools.c
@@ -687,15 +687,9 @@ int check_eth_mac_txt(int src_or_dst)
// Okay, lets check the commandline argument:
//
// Do you want a random MAC?
- // TODO: Consider enforcement of unicast addresses
if (strncmp(eth_mac_txt, "rand", 4)==0)
{
- eth_mac[0] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- eth_mac[1] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- eth_mac[2] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- eth_mac[3] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- eth_mac[4] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
- eth_mac[5] = (u_int8_t) ( ((float) rand()/RAND_MAX)*256);
+ rand_addr(eth_mac);
*eth_rand = 1;
}
// Do you want your own interface MAC?