aboutsummaryrefslogtreecommitdiff
path: root/net/tcpreplay
diff options
context:
space:
mode:
authorScott Mace <smace@FreeBSD.org>2002-05-31 17:06:25 +0000
committerScott Mace <smace@FreeBSD.org>2002-05-31 17:06:25 +0000
commit74254aff4cbe024c4f84c599408b2a8515f913a8 (patch)
treedf8c3431faf6608cbf91b7f4034027c424d6ad6a /net/tcpreplay
parent8a5876ded13e7a512a6d8b4d09865fb0bafc7d89 (diff)
downloadports-74254aff4cbe024c4f84c599408b2a8515f913a8.tar.gz
ports-74254aff4cbe024c4f84c599408b2a8515f913a8.zip
Fix multi-nic support for freebsd
Make several features actually work This generation of tcpreplay is being obsoleted and the author is no longer maintaining it. A new development effort has been started at sourceforge.
Notes
Notes: svn path=/head/; revision=60393
Diffstat (limited to 'net/tcpreplay')
-rw-r--r--net/tcpreplay/files/patch-Makefile.in26
-rw-r--r--net/tcpreplay/files/patch-tcpreplay.883
-rw-r--r--net/tcpreplay/files/patch-tcpreplay.c268
-rw-r--r--net/tcpreplay/pkg-messages3
4 files changed, 377 insertions, 3 deletions
diff --git a/net/tcpreplay/files/patch-Makefile.in b/net/tcpreplay/files/patch-Makefile.in
index e8b98ef6efc1..ef32a8a017bc 100644
--- a/net/tcpreplay/files/patch-Makefile.in
+++ b/net/tcpreplay/files/patch-Makefile.in
@@ -1,6 +1,6 @@
---- Makefile.in.orig Mon Apr 15 14:13:06 2002
-+++ Makefile.in Mon Apr 15 14:15:49 2002
-@@ -10,10 +10,11 @@
+--- Makefile.in.orig Sat May 11 12:07:44 2002
++++ Makefile.in Sat May 11 13:11:51 2002
+@@ -10,15 +10,16 @@
CFLAGS = @CFLAGS@
#CFLAGS = -ggdb -pipe -Wall
LDFLAGS = @LDFLAGS@
@@ -13,6 +13,26 @@
INCS = @LNETINC@ @REDBLACKINC@ @PCAPINC@
LIBRARIES = tree cache cidr
+ # tcpreplay objects
+-ROBJ = cache.o
++ROBJ = cache.o cidr.o
+
+ # tcpprep objects
+ POBJ = cache.o tree.o cidr.o
+@@ -40,11 +41,11 @@
+
+ tcpreplay: $(PCAPDEP) $(LNETDEP) tcpreplay.c
+ rm -f tcpreplay
+- $(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ tcpreplay.c $(LDFLAGS) $(LIBS) $(ROBJ)
++ $(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ tcpreplay.c $(ROBJ) $(LDFLAGS) $(LIBS)
+
+ tcpprep: $(PCAPDEP) tcpprep.c
+ rm -f tcpprep
+- $(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ tcpprep.c $(LDFLAGS) $(LIBS) $(POBJ)
++ $(CC) $(CFLAGS) $(DEFS) $(INCS) -o $@ tcpprep.c $(POBJ) $(LDFLAGS) $(LIBS)
+
+ clean:
+ rm -f *~ *.o *core $(PROGRAMS)
@@ -53,12 +54,10 @@
rm -f Makefile config.h config.status config.cache config.log
diff --git a/net/tcpreplay/files/patch-tcpreplay.8 b/net/tcpreplay/files/patch-tcpreplay.8
new file mode 100644
index 000000000000..79af4476e296
--- /dev/null
+++ b/net/tcpreplay/files/patch-tcpreplay.8
@@ -0,0 +1,83 @@
+--- tcpreplay.8.orig Fri May 17 17:55:47 2002
++++ tcpreplay.8 Fri May 31 11:49:46 2002
+@@ -1,5 +1,5 @@
+ .\" yo there.
+-.TH TCPREPLAY 8 "2 December 20001"
++.TH TCPREPLAY 8 "2 December 2001"
+ .SH NAME
+ tcpreplay \- replay traffic from a saved tcpdump file
+ .SH SYNOPSIS
+@@ -30,6 +30,9 @@
+ .B \-l
+ .I loop count
+ ] [
++.B \-n
++.I nomartian
++] [
+ .B \-m
+ .I multiplier
+ |
+@@ -39,6 +42,9 @@
+ .B \-R
+ .I regex
+ ]
++.B \-C
++.I cidr1[,cidr2,cidr3]
++]
+ .I file
+ .br
+ .ad
+@@ -67,11 +73,14 @@
+ .LP
+ This version of
+ .I tcpreplay
+-supports sending packets out two interfaces. Packets matching the \fIregex\fP
+-are sent out the \fIprimary interface\fP and all other packets are sent out the
+-\fIsecondary interface\fP. For improved performance, a tcpprep \fIcache file\fP
+-can be used instead. Also supported is rewriting of the destination \fIMAC
+-addresses\fP to allow routers to forward packets between interfaces. Additionally, a slice of packets matching a \fIbegin\fP and \fIend\fP range can be sent from the tcpdump file.
++supports sending packets out two interfaces. Packets are matched by using either
++a \fIregex\fP, \fICIDR list\fP, or by using the tcpprep pre-processor and associated
++\fIcache file\fP. Matching packets are sent out the \fIprimary interface\fP and all
++other packets are sent out the \fIsecondary interface\fP. For improved performance,
++use either \fICIDR list\fP matching or a tcpprep \fIcache file\fP. Also supported
++is rewriting of the destination \fIMAC addresses\fP to allow routers to forward packets
++between interfaces. Additionally, a slice of packets matching a \fIbegin\fP and \fIend\fP
++range can be sent from the tcpdump file.
+ .SH OPTIONS
+ .LP
+ .TP
+@@ -103,6 +112,9 @@
+ Resend the packets at a \fImultiple\fR of the speed at which they were
+ recorded.
+ .TP
++.B \-n
++Drop packets with \fImartian\fR destination addresses.
++.TP
+ .B \-r
+ Resend the packets at the \fIrate\fR specified (in Mbps).
+ .TP
+@@ -111,6 +123,10 @@
+ that match this regex are sent via the primary interface. Packets that do not
+ match this regex are sent via the secondary interface.
+ .TP
++.B \-C
++Specify a comma serpated list of net/masklen to match against the source IP of packets.
++Works similar to regex, but is significantly faster.
++.TP
+ .SH "SEE ALSO"
+ tcpdump(8) tcpprep(8)
+ .SH AUTHOR
+@@ -125,8 +141,10 @@
+ .I tcpreplay
+ can only send packets as fast as your machine's interface,
+ processor, and disk will allow. Use of the -R flag will \fIsignificantly\fP
+-slow it down. Those worrying about peformance should use \fItcpprep\fP with the
+--c flag instead.
++slow it down. Use of the -C flag will work for most systems with a fast
++processor. Those worrying about peformance should use \fItcpprep\fP with the
++-c flag instead, however, processesing time may be extremely slow for large
++capture files.
+ .LP
+ ``\fIN\fR write attempts failed from full buffers and were repeated''
+ does not indicate that these packets were not sent, but that the send
diff --git a/net/tcpreplay/files/patch-tcpreplay.c b/net/tcpreplay/files/patch-tcpreplay.c
new file mode 100644
index 000000000000..421f62f7ff50
--- /dev/null
+++ b/net/tcpreplay/files/patch-tcpreplay.c
@@ -0,0 +1,268 @@
+--- tcpreplay.c.orig Fri May 17 17:55:47 2002
++++ tcpreplay.c Fri May 31 11:42:37 2002
+@@ -65,6 +65,7 @@
+ #include <regex.h>
+ #include <math.h>
+ #include "cache.h"
++#include "cidr.h"
+
+ #define TCPREPLAY_VERSION "1.0.1-adt9"
+
+@@ -85,6 +86,10 @@
+ u_int start = 0;
+ u_int stop = 0;
+ int mode;
++int regex_mode;
++int cidr_mode;
++int cache_mode;
++int nomartians = 0;
+ int rate;
+ int debug;
+ float multiplier;
+@@ -101,6 +106,9 @@
+ CACHE * cachedata = NULL;
+ int cache_bit = 0;
+ int cache_byte = 0;
++struct libnet_link_int * write_if; // Primary interface -i
++struct libnet_link_int * write_if2; // Secondary interface -j
++CIDR * cidrdata = NULL;
+
+ void usage(){
+ fprintf(stderr, "Version: " TCPREPLAY_VERSION "\nUsage: tcpreplay "
+@@ -244,6 +252,7 @@
+ struct libnet_ethernet_hdr * eth_hdr;
+ #ifdef DEBUG
+ int regex_match = -1;
++ int cache_match = -1;
+ int cidr_match = -1;
+ #endif
+ size_t nmatch = 0;
+@@ -257,7 +266,7 @@
+ make sure we're inside that slice, or increment the cache
+ pointers, and return without further processing
+ */
+- if (start != 0) {
++ if ((start != 0) && cache_mode) {
+ if (!((start <= packet_num) && (packet_num <= stop))) {
+ if (cache_bit == 7) {
+ cache_bit = 0;
+@@ -359,14 +368,22 @@
+ if (interface2 == NULL) {
+ /* we're not using a second NIC so just write the packet all normal like */
+
+- write_status = libnet_write_link_layer((struct libnet_link_int *)user,
++ write_status = libnet_write_link_layer((struct libnet_link_int *)write_if,
+ interface, data, pcap_hdr->caplen);
+ }
+
+ else { /* we're in multi-nic mode, and have to figure things out */
+- if (mode == REGEX_MODE) {
++ if (regex_mode == 1) {
+ /* put the source ip of the packet into src_ip in x.x.x.x format */
+ ip_hdr = (struct libnet_ip_hdr *) (data + LIBNET_ETH_H);
++ /* drop martians */
++ if (nomartians == 1) {
++ switch ((ntohl(ip_hdr->ip_dst.s_addr) & 0xff000000) >> 24) {
++ case 0: case 127: case 255:
++ write_status=1;
++ continue;
++ }
++ }
+ memset (src_ip, '\0', 16);
+ strncat (src_ip, libnet_host_lookup(ip_hdr->ip_src.s_addr, RESOLVE), 15);
+
+@@ -384,7 +401,7 @@
+ if (primary_mac != NULL)
+ memcpy(eth_hdr->ether_dhost, primary_mac, ETHER_ADDR_LEN);
+
+- write_status = libnet_write_link_layer((struct libnet_link_int *)user,
++ write_status = libnet_write_link_layer((struct libnet_link_int *)write_if,
+ interface, data, pcap_hdr->caplen);
+ }
+
+@@ -396,11 +413,53 @@
+ if (secondary_mac != NULL)
+ memcpy(eth_hdr->ether_dhost, secondary_mac, ETHER_ADDR_LEN);
+
+- write_status = libnet_write_link_layer((struct libnet_link_int *)user,
++ write_status = libnet_write_link_layer((struct libnet_link_int *)write_if2,
+ interface2, data, pcap_hdr->caplen);
+ }
+ }
+-
++
++ else if (cidr_mode == 1) {
++ /* put the source ip of the packet into src_ip in x.x.x.x format */
++ ip_hdr = (struct libnet_ip_hdr *) (data + LIBNET_ETH_H);
++ /* drop martians */
++ if (nomartians == 1) {
++ switch ((ntohl(ip_hdr->ip_dst.s_addr) & 0xff000000) >> 24) {
++ case 0: case 127: case 255:
++ write_status=1;
++ continue;
++ }
++ }
++ /* we are using a cidr match */
++ if (check_ip_CIDR(ip_hdr->ip_src.s_addr)) {
++#ifdef DEBUG
++ /* in debug mode we need to set this flag */
++ cidr_match = 1;
++#endif
++ /*
++ To support routing packets through a device on either side
++ of the interfaces, we need to rewrite the dst MAC address
++ so that the router will pick them off the wire.
++ */
++ if (primary_mac != NULL)
++ memcpy(eth_hdr->ether_dhost, primary_mac, ETHER_ADDR_LEN);
++
++ write_status = libnet_write_link_layer((struct libnet_link_int *)write_if,
++ interface, data, pcap_hdr->caplen);
++ }
++
++ else {
++#ifdef DEBUG
++ cidr_match = 0;
++#endif
++ /* do the mac rewrite thingy */
++ if (secondary_mac != NULL)
++ memcpy(eth_hdr->ether_dhost, secondary_mac, ETHER_ADDR_LEN);
++
++ write_status = libnet_write_link_layer((struct libnet_link_int *)write_if2,
++ interface2, data, pcap_hdr->caplen);
++ }
++ }
++
+ else { /* looks like we're using a cache file */
+ /*
+ test to see if we have a match by applying a mask to the current byte
+@@ -408,7 +467,7 @@
+ */
+ if (cachedata->data[cache_byte] & (char)pow((long)2, (long)cache_bit) ) {
+ #ifdef DEBUG
+- cidr_match = 1;
++ cache_match = 1;
+ #endif
+ /* do the mac rewrite thingy */
+ if (primary_mac != NULL)
+@@ -420,7 +479,7 @@
+
+ else {
+ #ifdef DEBUG
+- cidr_match = 0;
++ cache_match = 0;
+ #endif
+ /* do the mac rewrite thingy */
+ if (secondary_mac != NULL)
+@@ -456,20 +515,30 @@
+
+ if (regex_match == 0) {
+ fprintf(stderr, "Regex: No Match (%s)\n", regex);
+- fprintf(stderr, "Interface: %s\n", interface);
++ fprintf(stderr, "Interface: %s\n", interface2);
+ } else if (regex_match == 1) {
+ fprintf(stderr, "Regex: Match (%s)\n", regex);
+- fprintf(stderr, "Interface: %s\n", interface2);
+- } else if (cidr_match == 1) {
+- fprintf(stderr, "CIDR: Match\n");
++ fprintf(stderr, "Interface: %s\n", interface);
++ } else if (cache_match == 1) {
++ fprintf(stderr, "Cache: Match\n");
+ fprintf(stderr, "Byte/Bit: %d/%d -> primary\n", cache_byte, cache_bit);
+- } else if (cidr_match == 0) {
+- fprintf(stderr, "CIDR: No Match\n");
++ } else if (cache_match == 0) {
++ fprintf(stderr, "Cache: No Match\n");
+ fprintf(stderr, "Byte/Bit: %d/%d -> secondary\n", cache_byte, cache_bit);
+- } else {
++ } else if (cidr_match == 0) {
++ fprintf(stderr, "CIDR: No Match\n");
++ fprintf(stderr, "Interface: %s\n", interface2);
++ } else if (cidr_match == 1) {
++ fprintf(stderr, "CIDR: Match\n");
++ fprintf(stderr, "Interface: %s\n", interface);
++ } else {
+ fprintf(stderr, "No CIDR/Regex Match Attempted\n");
+ }
+-
++
++ if (cidr_mode == 1) {
++ memset (src_ip, '\0', 16);
++ strncat (src_ip, libnet_host_lookup(ip_hdr->ip_src.s_addr, RESOLVE), 15);
++ }
+ fprintf(stderr, "Source IP: %s\n", src_ip);
+ memcpy(mac, eth_hdr->ether_dhost, MAC_SIZE-1);
+ fprintf(stderr, "Dest MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+@@ -506,8 +575,6 @@
+ {
+ pcap_t * in_file;
+ char * cache_file = NULL;
+- struct libnet_link_int * write_if; // Primary interface -i
+- struct libnet_link_int * write_if2; // Secondary interface -j
+ float Mrate = 0; //
+ double starttime_local, startusec;
+ char ebuf[EBUF_SIZE]; // Error buffer
+@@ -539,15 +606,16 @@
+ }
+
+ #ifdef DEBUG
+- while ((ch = getopt(argc, argv, "b:e:d:i:j:l:r:c:m:hR:I:J:")) != -1)
++ while ((ch = getopt(argc, argv, "nb:e:d:i:j:l:r:c:m:h:R:I:J:C:")) != -1)
+ #else
+- while ((ch = getopt(argc, argv, "b:e:i:j:l:r:c:m:hR:I:J:")) != -1)
++ while ((ch = getopt(argc, argv, "nb:e:i:j:l:r:c:m:h:R:I:J:C:")) != -1)
+ #endif
+ switch(ch) {
+ case 'b':
+ start = atoi(optarg);
+ break;
+ case 'c':
++ cache_mode = 1;
+ cache_file = optarg;
+ cache_packets = read_cache(cache_file);
+ break;
+@@ -578,7 +646,11 @@
+ case 'h':
+ usage();
+ break;
++ case 'n':
++ nomartians = 1;
++ break;
+ case 'R':
++ regex_mode = 1;
+ regex = optarg;
+ if ((regex_error = regcomp(preg, regex, regex_flags))) {
+ if (regerror(regex_error, preg, ebuf, EBUF_SIZE) != -1) {
+@@ -595,6 +667,12 @@
+ case 'J':
+ secondary_mac = mac2hex(optarg, "Secondary MAC");
+ break;
++ case 'C':
++ cidr_mode = 1;
++ if (! parse_cidr(optarg)) {
++ usage();
++ }
++ break;
+ default:
+ usage();
+ }
+@@ -616,8 +694,8 @@
+ exit (1);
+ }
+
+- if (((regex == NULL) && (cache_file == NULL)) && (interface2 != NULL)) {
+- fprintf(stderr, "Needs regex/cache with secondary interface\n");
++ if (((regex == NULL) && (cache_file == NULL) && (cidrdata == NULL)) && (interface2 != NULL)) {
++ fprintf(stderr, "Needs regex/cache/cidr with secondary interface\n");
+ exit (1);
+ }
+
+@@ -712,7 +790,7 @@
+ exit (1);
+ }
+ if (pcap_dispatch(in_file, 0,(void *)&write_packet,
+- (u_char *) write_if) == -1) {
++ NULL) == -1) {
+ pcap_perror(in_file, argv[1]);
+ }
+ pcap_close(in_file);
diff --git a/net/tcpreplay/pkg-messages b/net/tcpreplay/pkg-messages
new file mode 100644
index 000000000000..0f8a16597ace
--- /dev/null
+++ b/net/tcpreplay/pkg-messages
@@ -0,0 +1,3 @@
+This is a patched version of tcpreplay that seems to work well enough
+for some applications. A new development effort for tcpreplay has been
+started, see http://www.sf.net/projects/tcpreplay.