Browse Source

Merge upstream version 3.3.2

Noèl Köthe 15 years ago
parent
commit
afd2202cc1

BIN
._configure.ac


+ 5 - 7
Makefile.in

@@ -35,10 +35,10 @@ target_triplet = @target@
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/doxygen.cfg.in \
-	$(srcdir)/tcpreplay.spec.in $(top_srcdir)/configure INSTALL \
-	config/compile config/config.guess config/config.sub \
-	config/depcomp config/install-sh config/ltmain.sh \
-	config/missing config/mkinstalldirs
+	$(top_srcdir)/configure INSTALL config/compile \
+	config/config.guess config/config.sub config/depcomp \
+	config/install-sh config/ltmain.sh config/missing \
+	config/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -47,7 +47,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/src/config.h
-CONFIG_CLEAN_FILES = doxygen.cfg tcpreplay.spec
+CONFIG_CLEAN_FILES = doxygen.cfg
 SOURCES =
 DIST_SOURCES =
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
@@ -259,8 +259,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 	cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
 doxygen.cfg: $(top_builddir)/config.status $(srcdir)/doxygen.cfg.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
-tcpreplay.spec: $(top_builddir)/config.status $(srcdir)/tcpreplay.spec.in
-	cd $(top_builddir) && $(SHELL) ./config.status $@
 
 mostlyclean-libtool:
 	-rm -f *.lo

+ 8 - 9
configure

@@ -2226,7 +2226,7 @@ MAINTAINER_AUTOGEN_VERSION=5.9.2
 
 MAJOR_VERSION=3
 MINOR_VERSION=3
-MICRO_VERSION=1
+MICRO_VERSION=2
 TCPREPLAY_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
 
 TCPREPLAY_RELEASE=1
@@ -27261,16 +27261,16 @@ fi
 
 
 if test $have_bpf = no -a $have_pcap_inject = no -a $have_pcap_sendpacket = no \
-	-a $have_libnet = no -a $have_pf = no ; then
-	{ { $as_echo "$as_me:$LINENO: error: Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libnet" >&5
-$as_echo "$as_me: error: Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libnet" >&2;}
+	-a $have_libdnet = no -a $have_pf = no ; then
+	{ { $as_echo "$as_me:$LINENO: error: Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libdnet" >&5
+$as_echo "$as_me: error: Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libdnet" >&2;}
    { (exit 1); exit 1; }; }
 fi
 
 enable_tcpbridge=yes
-if test $have_bpf = no -a $have_libnet = no -a $have_pf = no ; then
-	{ $as_echo "$as_me:$LINENO: tcpbridge support disabled without BPF, Libnet or Linux PF_PACKET" >&5
-$as_echo "$as_me: tcpbridge support disabled without BPF, Libnet or Linux PF_PACKET" >&6;}
+if test $have_bpf = no -a $have_libdnet = no -a $have_pf = no ; then
+	{ $as_echo "$as_me:$LINENO: tcpbridge support disabled without BPF, Libdnet or Linux PF_PACKET" >&5
+$as_echo "$as_me: tcpbridge support disabled without BPF, Libdnet or Linux PF_PACKET" >&6;}
 	enable_tcpbridge=no
 fi
 
@@ -36791,7 +36791,7 @@ fi
 
 
 
-ac_config_files="$ac_config_files Makefile doxygen.cfg lib/Makefile docs/Makefile src/Makefile src/common/Makefile src/tcpedit/Makefile src/fragroute/Makefile src/defines.h test/Makefile test/config scripts/Makefile tcpreplay.spec"
+ac_config_files="$ac_config_files Makefile doxygen.cfg lib/Makefile docs/Makefile src/Makefile src/common/Makefile src/tcpedit/Makefile src/fragroute/Makefile src/defines.h test/Makefile test/config scripts/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -37494,7 +37494,6 @@ do
     "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
     "test/config") CONFIG_FILES="$CONFIG_FILES test/config" ;;
     "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
-    "tcpreplay.spec") CONFIG_FILES="$CONFIG_FILES tcpreplay.spec" ;;
 
   *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;}

+ 7 - 8
configure.ac

@@ -1,5 +1,5 @@
 
-dnl $Id: configure.ac 2029 2008-05-17 17:45:36Z aturner $
+dnl $Id: configure.ac 2050 2008-05-23 05:00:04Z aturner $
 
 AC_INIT(tcpreplay)
 AC_CONFIG_SRCDIR(src/tcpreplay.c)
@@ -15,7 +15,7 @@ MAINTAINER_AUTOGEN_VERSION=5.9.2
 dnl Set version info here!
 MAJOR_VERSION=3
 MINOR_VERSION=3
-MICRO_VERSION=1
+MICRO_VERSION=2
 TCPREPLAY_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
 
 dnl Release is only used for the RPM spec file
@@ -803,15 +803,15 @@ main(int argc, char *argv[]) {
 
 dnl Make sure we have a valid packet injection mechanisim
 if test $have_bpf = no -a $have_pcap_inject = no -a $have_pcap_sendpacket = no \
-	-a $have_libnet = no -a $have_pf = no ; then
-	AC_MSG_ERROR([Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libnet])
+	-a $have_libdnet = no -a $have_pf = no ; then
+	AC_MSG_ERROR([Unable to find a supported method to send packets.  Please upgrade your libpcap or enable libdnet])
 fi
 
 dnl Libpcap support doesn't give us a method to get the hardware address of the
 dnl interfaces which prevents us from doing proper filtering to prevent bridging loops
 enable_tcpbridge=yes
-if test $have_bpf = no -a $have_libnet = no -a $have_pf = no ; then
-	AC_MSG_NOTICE([tcpbridge support disabled without BPF, Libnet or Linux PF_PACKET])
+if test $have_bpf = no -a $have_libdnet = no -a $have_pf = no ; then
+	AC_MSG_NOTICE([tcpbridge support disabled without BPF, Libdnet or Linux PF_PACKET])
 	enable_tcpbridge=no
 fi
 
@@ -1205,8 +1205,7 @@ AC_OUTPUT([Makefile
            src/defines.h
            test/Makefile
            test/config
-           scripts/Makefile
-           tcpreplay.spec])
+           scripts/Makefile])
 
 # Configuration results
 AC_MSG_RESULT(

+ 14 - 1
docs/CHANGELOG

@@ -1,5 +1,18 @@
-$Id: CHANGELOG 2032 2008-05-17 18:25:39Z aturner $
+$Id: CHANGELOG 2063 2008-06-20 16:03:22Z aturner $
 
+06/20/2008: Version 3.3.2
+    - Fix (again) tcpbridge --unidir assert error (#308)
+    - Fix tcpbridge bug where all packets that were sent were all zeros
+    - Fix tcpbridge not honoring --include/exclude flags (#311)
+    - Fix ip_in_cidr() debug messages (#312)
+    - Report packets which have timestamps which go backwards in time (#315)
+    - Clean up --sleep-accel code to use options struct (#316)
+    - Remove really old and out of date RPM .spec file (#317)
+    - Warn when sending on non-Ethernet interface (#318)
+    - Re-enable tcpreplay --listnics (#319)
+    - Fix sendpacket always reporting using PF_PACKET, even when it doesn't (#322)
+    - Fix major packet timing issue under old versions of glibc (#324)
+    
 05/17/2008: Version 3.3.1
     - Fix limitation of PF_PACKET only supporting Ethernet (#123)
     - Fix (again) /dev/bpf detection in FreeBSD 8.0 (#292)

BIN
src/._bridge.c


BIN
src/._sleep.c


BIN
src/._tcpbridge.c


BIN
src/._tcpbridge.h


BIN
src/._tcpreplay.c


BIN
src/._tcpreplay.h


BIN
src/._tcpreplay_opts.def


+ 16 - 8
src/bridge.c

@@ -1,4 +1,4 @@
-/* $Id: bridge.c 1898 2007-08-25 05:10:51Z aturner $ */
+/* $Id: bridge.c 2040 2008-05-20 22:37:40Z aturner $ */
 
 /*
  * Copyright (c) 2001-2005 Aaron Turner.
@@ -146,7 +146,7 @@ do_bridge(tcpedit_t *tcpedit, pcap_t * pcap1, pcap_t * pcap2)
             exit(1);
         }
 
-        dbgx(1, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC, 
+        dbgx(3, "limit_send: " COUNTER_SPEC " \t pkts_sent: " COUNTER_SPEC, 
             options.limit_send, pkts_sent);
 
         /* poll for a packet on the two interfaces */
@@ -156,7 +156,7 @@ do_bridge(tcpedit_t *tcpedit, pcap_t * pcap1, pcap_t * pcap2)
         if (pollresult > 0) {
             /* success, got one or more packets */
             if (polls[PCAP_INT1].revents > 0) {
-                dbg(2, "Processing first interface");
+                dbg(5, "Processing first interface");
                 livedata.source = source1;
                 livedata.pcap = pcap1;
                 pcap_dispatch(pcap1, -1, (pcap_handler) live_callback,
@@ -165,7 +165,7 @@ do_bridge(tcpedit_t *tcpedit, pcap_t * pcap1, pcap_t * pcap2)
 
             /* check the other interface?? */
             if (! options.unidir && polls[PCAP_INT2].revents > 0) {
-                dbg(2, "Processing second interface");
+                dbg(5, "Processing second interface");
                 livedata.source = source2;
                 livedata.pcap = pcap2;
                 pcap_dispatch(pcap2, -1, (pcap_handler) live_callback,
@@ -211,6 +211,7 @@ live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
 #ifdef DEBUG
     u_char dstmac[ETHER_ADDR_LEN];
 #endif
+    u_int16_t l2proto;
 
     packetnum++;
     dbgx(2, "packet %d caplen %d", packetnum, pkthdr->caplen);
@@ -224,6 +225,10 @@ live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
         memset(pktdata, '\0', MAXPACKET);
     }
 
+    /* copy the packet to our buffer */
+    memcpy(pktdata, nextpkt, pkthdr->caplen);
+
+
 #ifdef ENABLE_VERBOSE
     /* decode packet? */
     if (options.verbose)
@@ -235,18 +240,18 @@ live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
     memcpy(&finder.key, &pktdata[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
 #ifdef DEBUG
     memcpy(&dstmac, pktdata, ETHER_ADDR_LEN);
-    dbgx(1, "Source MAC: " MAC_FORMAT "\tDestin MAC: " MAC_FORMAT,
+    dbgx(1, "SRC MAC: " MAC_FORMAT "\tDST MAC: " MAC_FORMAT,
         MAC_STR(finder.key), MAC_STR(dstmac));
 #endif
 
     /* first, is this a packet sent locally?  If so, ignore it */
     if ((memcmp(sendpacket_get_hwaddr(options.sp1), &finder.key, 
-                ETHER_ADDR_LEN)) == 0) {
+            ETHER_ADDR_LEN)) == 0) {
         dbgx(1, "Packet matches the MAC of %s, skipping.", options.intf1);
         return (1);
     }
     else if ((memcmp(sendpacket_get_hwaddr(options.sp2), &finder.key,
-                     ETHER_ADDR_LEN)) == 0) {
+            ETHER_ADDR_LEN)) == 0) {
         dbgx(1, "Packet matches the MAC of %s, skipping.", options.intf2);
         return (1);
     }
@@ -275,14 +280,17 @@ live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr,
     /* what is our cache mode? */
     cache_mode = livedata->source == PCAP_INT1 ? TCPR_DIR_C2S : TCPR_DIR_S2C;
 
+    l2proto = tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
+    dbgx(2, "Packet protocol: %04hx", l2proto);
     /* should we skip this packet based on CIDR match? */
-    if (tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len) == ETHERTYPE_IP) {
+    if (l2proto == ETHERTYPE_IP) {
         dbg(3, "Packet is IP");
         ip_hdr = (ipv4_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len);
 
         /* look for include or exclude CIDR match */
         if (options.xX.cidr != NULL) {
             if (!process_xX_by_cidr(options.xX.mode, options.xX.cidr, ip_hdr)) {
+                dbg(2, "Skipping packet due to CIDR match");
                 return (1);
             }
         }

BIN
src/common/._cidr.c


BIN
src/common/._dlt_names.h


BIN
src/common/._interface.c


BIN
src/common/._interface.h


+ 16 - 9
src/common/cidr.c

@@ -1,4 +1,4 @@
-/* $Id: cidr.c 1897 2007-08-25 04:57:38Z aturner $ */
+/* $Id: cidr.c 2053 2008-05-31 02:19:17Z aturner $ */
 
 /*
  * Copyright (c) 2001-2004 Aaron Turner.
@@ -384,6 +384,9 @@ ip_in_cidr(const tcpr_cidr_t * mycidr, const unsigned long ip)
 {
     unsigned long ipaddr = 0, network = 0, mask = 0;
     int ret = 0;
+#ifdef DEBUG
+    char netstr[20];
+#endif
     
     /* always return 1 if 0.0.0.0/0 */
     if (mycidr->masklen == 0 && mycidr->network == 0)
@@ -399,21 +402,25 @@ ip_in_cidr(const tcpr_cidr_t * mycidr, const unsigned long ip)
 
     network = htonl(mycidr->network) & mask;
 
+
+#ifdef DEBUG
+    /* copy this for debug purposes, since it's not re-entrant */
+    strlcpy(netstr, get_addr2name4(htonl(mycidr->network), RESOLVE), 20);
+#endif
+
     /* if they're the same, then ip is in network */
     if (network == ipaddr) {
-
+#ifdef DEBUG
         dbgx(1, "The ip %s is inside of %s/%d",
-            get_addr2name4(ip, RESOLVE),
-            get_addr2name4(htonl(network), RESOLVE), mycidr->masklen);
-
+            get_addr2name4(ip, RESOLVE), netstr, mycidr->masklen);
+#endif
         ret = 1;
     }
     else {
-
+#ifdef DEBUG
         dbgx(1, "The ip %s is not inside of %s/%d",
-            get_addr2name4(ip, RESOLVE),
-            get_addr2name4(htonl(network), RESOLVE), mycidr->masklen);
-
+            get_addr2name4(ip, RESOLVE), netstr, mycidr->masklen);
+#endif
         ret = 0;
     }
     return ret;

+ 23 - 26
src/common/sendpacket.c

@@ -1,4 +1,4 @@
-/* $Id: sendpacket.c 2024 2008-05-06 19:39:35Z aturner $ */
+/* $Id: sendpacket.c 2059 2008-06-09 19:37:53Z aturner $ */
 
 /*
  * Copyright (c) 2006 Aaron Turner.
@@ -70,16 +70,11 @@
 #include "sendpacket.h"
 
 
-/* Allow users to force the injection method, default is linux PF_PACKET */
-#define INJECT_METHOD "PF_PACKET send()"
-
 #ifdef FORCE_INJECT_LIBNET
 #undef HAVE_PF_PACKET
 #undef HAVE_PCAP_INJECT
 #undef HAVE_PCAP_SENDPACKET
 #undef HAVE_BPF
-#undef INJECT_METHOD
-#define INJECT_METHOD "libnet send()"
 #endif
 
 #ifdef FORCE_INJECT_BPF
@@ -87,8 +82,6 @@
 #undef HAVE_PCAP_INJECT
 #undef HAVE_PCAP_SENDPACKET
 #undef HAVE_PF_PACKET
-#undef INJECT_METHOD
-#define INJECT_METHOD "bpf send()"
 #endif
 
 #ifdef FORCE_INJECT_PCAP_INJECT
@@ -96,8 +89,6 @@
 #undef HAVE_PCAP_SENDPACKET
 #undef HAVE_BPF
 #undef HAVE_PF_PACKET
-#undef INJECT_METHOD
-#define INJECT_METHOD "pcap_inject()"
 #endif
 
 #ifdef FORCE_INJECT_PCAP_SENDPACKET
@@ -105,11 +96,8 @@
 #undef HAVE_PCAP_INJECT
 #undef HAVE_BPF
 #undef HAVE_PF_PACKET
-#undef INJECT_METHOD
-#define INJECT_METHOD "pcap_sendpacket()"
 #endif
 
-
 #if (defined HAVE_WINPCAP && defined HAVE_PCAP_INJECT)
 #undef HAVE_PCAP_INJECT /* configure returns true for some odd reason */
 #endif
@@ -140,6 +128,9 @@
 #include <unistd.h>
 
 #ifdef HAVE_PF_PACKET
+#undef INJECT_METHOD
+#define INJECT_METHOD "PF_PACKET send()"
+
 #include <fcntl.h>
 #include <sys/utsname.h>
 #include <net/if.h>
@@ -159,6 +150,9 @@ static int get_iface_index(int fd, const int8_t *device, char *);
 #endif /* HAVE_PF_PACKET */
 
 #ifdef HAVE_BPF
+#undef INJECT_METHOD
+#define INJECT_METHOD "bpf send()"
+
 #include <net/bpf.h>
 #include <sys/socket.h>
 #include <net/if.h>
@@ -171,6 +165,9 @@ static struct tcpr_ether_addr *sendpacket_get_hwaddr_bpf(sendpacket_t *) _U_;
 #endif /* HAVE_BPF */
 
 #ifdef HAVE_LIBNET
+#undef INJECT_METHOD
+#define INJECT_METHOD "libnet send()"
+
 static sendpacket_t *sendpacket_open_libnet(const char *, char *) _U_;
 static struct tcpr_ether_addr *sendpacket_get_hwaddr_libnet(sendpacket_t *) _U_;
 #endif /* HAVE_LIBNET */
@@ -180,6 +177,14 @@ static sendpacket_t *sendpacket_open_pcap(const char *, char *) _U_;
 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *) _U_;
 #endif /* HAVE_PCAP_INJECT || HAVE_PACKET_SENDPACKET */
 
+#ifdef HAVE_PCAP_INJECT
+#undef INJECT_METHOD
+#define INJECT_METHOD "pcap_inject()"
+#elif defined HAVE_PCAP_SENDPACKET
+#undef INJECT_METHOD
+#define INJECT_METHOD "pcap_sendpacket()"
+#endif
+
 static void sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...);
 
 /* You need to define didsig in your main .c file.  Set to 1 if CTRL-C was pressed */
@@ -620,18 +625,10 @@ sendpacket_open_pf(const char *device, char *errbuf)
         return NULL;
     }
 
-#if 0 /* why is this check necessary??? */
-    /* make sure it's ethernet */
-    switch (ifr.ifr_hwaddr.sa_family) {
-        case ARPHRD_ETHER:
-            break;
-        default:
-            snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, 
-                "unsupported pysical layer type 0x%x", ifr.ifr_hwaddr.sa_family);
-            close(mysocket);
-            return NULL;
-    }
-#endif
+    /* make sure it's not loopback (PF_PACKET doesn't support it) */
+    if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
+        warnx("Unsupported physical layer type 0x%04x on %s.  Maybe it works, maybe it wont."
+        "  See tickets #123/318", ifr.ifr_hwaddr.sa_family, device);
 
 #ifdef SO_BROADCAST
     /*
@@ -644,7 +641,7 @@ sendpacket_open_pf(const char *device, char *errbuf)
      */ 
     if (setsockopt(mysocket, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1) {
         snprintf(errbuf, SENDPACKET_ERRBUF_SIZE,
-                "SO_BROADCAS: %s\n", strerror(errno));
+                "SO_BROADCAST: %s\n", strerror(errno));
         close(mysocket);
         return NULL;
     }

+ 1 - 1
src/common/svn_version.c

@@ -1,4 +1,4 @@
-const char SVN_Version[] = "2033";
+const char SVN_Version[] = "2065";
 const char *svn_version(void) {
 	return SVN_Version;
 }

+ 11 - 1
src/common/timer.c

@@ -1,4 +1,4 @@
-/* $Id: timer.c 2006 2008-05-01 04:46:55Z aturner $ */
+/* $Id: timer.c 2061 2008-06-20 07:00:39Z aturner $ */
 
 /*
  * Copyright (c) 2001-2007 Aaron Turner.
@@ -69,3 +69,13 @@ void timesdiv(struct timespec *tvs, float div)
     tvs->tv_nsec = interval - (tvs->tv_nsec * 1000000000);
 }
 
+void
+init_delta_time(delta_t *ctx)
+{
+#ifdef HAVE_ABSOLUTE_TIME
+    SetZero(*ctx);
+#else
+    timerclear(ctx);
+#endif 
+}
+

+ 3 - 1
src/common/timer.h

@@ -1,4 +1,4 @@
-/* $Id: timer.h 2006 2008-05-01 04:46:55Z aturner $ */
+/* $Id: timer.h 2061 2008-06-20 07:00:39Z aturner $ */
 
 /*
  * Copyright (c) 2001-2007 Aaron Turner.
@@ -210,6 +210,8 @@ start_delta_time(delta_t *ctx)
 #endif
 }
 
+void init_delta_time(delta_t *ctx);
+
 /* 
  * returns the amount of time that has passed since the 
  * last time you called start_delta_time()

+ 20 - 21
src/send_packets.c

@@ -1,4 +1,4 @@
-/* $Id: send_packets.c 2008 2008-05-01 18:39:05Z aturner $ */
+/* $Id: send_packets.c 2061 2008-06-20 07:00:39Z aturner $ */
 
 /*
  * Copyright (c) 2001-2008 Aaron Turner.
@@ -93,6 +93,8 @@ send_packets(pcap_t *pcap, int cache_file_idx)
     struct pcap_pkthdr *pkthdr_ptr;
 #endif
     delta_t delta_ctx;
+
+    init_delta_time(&delta_ctx);
     
     /* register signals */
     didsig = 0;
@@ -336,7 +338,7 @@ do_sleep(struct timeval *time, struct timeval *last, int len, int accurate,
 
 
 #ifdef TCPREPLAY
-    adjuster.tv_nsec = OPT_VALUE_SLEEP_ACCEL * 1000;
+    adjuster.tv_nsec = options.sleep_accel * 1000;
     dbgx(2, "Adjuster: " TIMEVAL_FORMAT, adjuster.tv_sec, adjuster.tv_nsec);
 #else
     adjuster.tv_nsec = 0;
@@ -365,30 +367,27 @@ do_sleep(struct timeval *time, struct timeval *last, int len, int accurate,
         timersub(&now, &start, &sleep_until);
     }
 
+    /* If top speed, you shouldn't even be here */
+    assert(options.speed.mode != SPEED_TOPSPEED);
+
     switch(options.speed.mode) {
-    /* 
-     * If top speed, you shouldn't even be here, but handle it anyways
-     */
-    case SPEED_TOPSPEED:
-        notice("you shouldn't call do_sleep() in top speed mode.");
-        return;
-        break;
-        
     case SPEED_MULTIPLIER:
         /* 
          * Replay packets a factor of the time they were originally sent.
          */
-        if (timerisset(last) && timercmp(time, last, >)) {
-            timersub(time, last, &nap_for);
-            TIMEVAL_TO_TIMESPEC(&nap_for, &nap);
-            timesdiv(&nap, options.speed.speed);
-        }
-        else {
-            /* 
-             * Don't sleep if this is our first packet, or if the
-             * this packet appears to have been sent before the 
-             * last packet.
-             */
+        if (timerisset(last)) {
+            if (timercmp(time, last, <)) {
+                /* Packet has gone back in time!  Don't sleep and warn user */
+                warnx("Packet #" COUNTER_SPEC " has gone back in time!", counter);
+                timesclear(&nap); 
+            } else {
+                /* time has increased or is the same, so handle normally */
+                timersub(time, last, &nap_for);
+                TIMEVAL_TO_TIMESPEC(&nap_for, &nap);
+                timesdiv(&nap, options.speed.speed);
+            }
+        } else {
+            /* Don't sleep if this is our first packet */
             timesclear(&nap);
         }        
         break;

+ 8 - 9
src/tcpbridge.c

@@ -1,4 +1,4 @@
-/* $Id: tcpbridge.c 2027 2008-05-15 16:54:58Z aturner $ */
+/* $Id: tcpbridge.c 2036 2008-05-20 16:38:20Z aturner $ */
 
 /*
  * Copyright (c) 2004-2005 Aaron Turner.
@@ -211,15 +211,14 @@ post_args(_U_ int argc, _U_ char *argv[])
         errx(1, "Unable to open interface %s for recieving: %s", options.intf1, ebuf);
 
 
-    /* open interfaces bi-directionally ?? */
-    if (!options.unidir) {
-        if (strcmp(options.intf1, options.intf2) == 0)
-            errx(1, "Whoa tiger!  You don't want to use %s twice!", options.intf1);
+    if (strcmp(options.intf1, options.intf2) == 0)
+        errx(1, "Whoa tiger!  You don't want to use %s twice!", options.intf1);
+
+    if ((options.sp2 = sendpacket_open(options.intf2, ebuf, TCPR_DIR_S2C)) == NULL)
+        errx(1, "Unable to open interface %s for sending: %s", options.intf2, ebuf);
 
-        if ((options.sp2 = sendpacket_open(options.intf2, ebuf, TCPR_DIR_S2C)) == NULL)
-            errx(1, "Unable to open interface %s for sending: %s", options.intf2, ebuf);
-        
-        
+    /* open 2nd interface for listening? (not in unidir mode) */
+    if (!options.unidir) {
         if ((options.listen2 = pcap_open_live(options.intf2, options.snaplen,
                                               options.promisc, options.to_ms, ebuf)) == NULL)
             errx(1, "Unable to open interface %s for recieving: %s", options.intf2, ebuf);

BIN
src/tcpedit/._edit_packet.c


BIN
src/tcpedit/._tcpedit.c


+ 4 - 4
src/tcpedit/tcpedit.c

@@ -1,4 +1,4 @@
-/* $Id: tcpedit.c 1983 2008-04-25 04:51:07Z aturner $ */
+/* $Id: tcpedit.c 2040 2008-05-20 22:37:40Z aturner $ */
 
 /*
  * Copyright (c) 2001-2007 Aaron Turner.
@@ -458,11 +458,11 @@ tcpedit_l3proto(tcpedit_t *tcpedit, tcpedit_coder_t code, const u_char *packet,
 {
     int result = 0;
     if (code == BEFORE_PROCESS) {
-        tcpedit_dlt_proto(tcpedit->dlt_ctx, tcpedit->dlt_ctx->decoder->dlt, packet, pktlen);        
+        result = tcpedit_dlt_proto(tcpedit->dlt_ctx, tcpedit->dlt_ctx->decoder->dlt, packet, pktlen);        
     } else {
-        tcpedit_dlt_proto(tcpedit->dlt_ctx, tcpedit->dlt_ctx->encoder->dlt, packet, pktlen);
+        result = tcpedit_dlt_proto(tcpedit->dlt_ctx, tcpedit->dlt_ctx->encoder->dlt, packet, pktlen);
     }
-    return result;
+    return ntohs(result);
 }
 
 /*

+ 7 - 2
src/tcpreplay-edit.1

@@ -1,7 +1,7 @@
-.TH TCPREPLAY 1 2008-05-15 "(tcpreplay )" "Programmer's Manual"
+.TH TCPREPLAY 1 2008-06-09 "(tcpreplay )" "Programmer's Manual"
 .\"  DO NOT EDIT THIS FILE   (tcpreplay-edit.1)
 .\"  
-.\"  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:21 AM PDT
+.\"  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:43 AM PDT
 .\"  From the definitions    tcpreplay_opts.def
 .\"  and the template file   agman1.tpl
 .\"
@@ -457,6 +457,11 @@ cachefile.
 .sp
 
 .TP
+.BR \--listnics
+List available network interfaces and exit.
+.sp
+
+.TP
 .BR \-l " \fInumber\fP, " \--loop "=" \fInumber\fP
 Loop through the capture file X times.
 This option may appear up to 1 times.

+ 7 - 2
src/tcpreplay.1

@@ -1,7 +1,7 @@
-.TH TCPREPLAY 1 2008-05-15 "(tcpreplay )" "Programmer's Manual"
+.TH TCPREPLAY 1 2008-06-09 "(tcpreplay )" "Programmer's Manual"
 .\"  DO NOT EDIT THIS FILE   (tcpreplay.1)
 .\"  
-.\"  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:21 AM PDT
+.\"  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:43 AM PDT
 .\"  From the definitions    tcpreplay_opts.def
 .\"  and the template file   agman1.tpl
 .\"
@@ -154,6 +154,11 @@ cachefile.
 .sp
 
 .TP
+.BR \--listnics
+List available network interfaces and exit.
+.sp
+
+.TP
 .BR \-l " \fInumber\fP, " \--loop "=" \fInumber\fP
 Loop through the capture file X times.
 This option may appear up to 1 times.

+ 2 - 1
src/tcpreplay.c

@@ -1,4 +1,4 @@
-/* $Id: tcpreplay.c 2006 2008-05-01 04:46:55Z aturner $ */
+/* $Id: tcpreplay.c 2047 2008-05-22 22:09:51Z aturner $ */
 
 /*
  * Copyright (c) 2001-2008 Aaron Turner.
@@ -296,6 +296,7 @@ post_args(void)
 #endif
         
     options.loop = OPT_VALUE_LOOP;
+    options.sleep_accel = OPT_VALUE_SLEEP_ACCEL;
 
     if (HAVE_OPT(LIMIT))
         options.limit_send = OPT_VALUE_LIMIT;

+ 4 - 3
src/tcpreplay.h

@@ -1,4 +1,4 @@
-/* $Id: tcpreplay.h 2006 2008-05-01 04:46:55Z aturner $ */
+/* $Id: tcpreplay.h 2047 2008-05-22 22:09:51Z aturner $ */
 
 /*
  * Copyright (c) 2001-2008 Aaron Turner.
@@ -72,7 +72,8 @@ struct tcpreplay_opt_s {
 
     tcpr_speed_t speed;
     u_int32_t loop;
-
+    int sleep_accel;
+    
     /* tcpprep cache data */
     COUNTER cache_packets;
     char *cachedata;
@@ -93,7 +94,7 @@ struct tcpreplay_opt_s {
     
     char *files[MAX_FILES];
     COUNTER limit_send;
-    
+
 #ifdef ENABLE_VERBOSE
     /* tcpdump verbose printing */
     int verbose;

+ 79 - 24
src/tcpreplay_edit_opts.c

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (tcpreplay_edit_opts.c)
  *  
- *  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:21 AM PDT
+ *  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:43 AM PDT
  *  From the definitions    tcpreplay_opts.def
  *  and the template file   options
  *
@@ -542,6 +542,24 @@ static const int
         | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
 
 /*
+ *  Listnics option description:
+ */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+tSCC    zListnicsText[] =
+        "List available network interfaces and exit";
+tSCC    zListnics_NAME[]           = "LISTNICS";
+tSCC    zListnics_Name[]           = "listnics";
+#define LISTNICS_FLAGS       (OPTST_DISABLED | OPTST_IMM)
+
+#else   /* disable Listnics */
+#define VALUE_OPT_LISTNICS NO_EQUIVALENT
+#define LISTNICS_FLAGS       (OPTST_OMITTED | OPTST_NO_INIT)
+#define zListnicsText       NULL
+#define zListnics_NAME      NULL
+#define zListnics_Name      NULL
+#endif  /* ENABLE_PCAP_FINDALLDEVS */
+
+/*
  *  Loop option description:
  */
 tSCC    zLoopText[] =
@@ -711,6 +729,11 @@ tSCC zNotLoad_Opts_Pfx[]  = "no";
 #else /* not DEBUG */
 # define doOptDbug NULL
 #endif /* def/not DEBUG */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+  static tOptProc doOptListnics;
+#else /* not ENABLE_PCAP_FINDALLDEVS */
+# define doOptListnics NULL
+#endif /* def/not ENABLE_PCAP_FINDALLDEVS */
 extern tOptProc
     optionNumericVal, optionPagedUsage, optionStackArg;
 static tOptProc
@@ -1156,8 +1179,20 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zIntf2Text, zIntf2_NAME, zIntf2_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 36, VALUE_OPT_LOOP,
-     /* equiv idx, value */ 36, VALUE_OPT_LOOP,
+  {  /* entry idx, value */ 36, VALUE_OPT_LISTNICS,
+     /* equiv idx, value */ 36, VALUE_OPT_LISTNICS,
+     /* equivalenced to  */ NO_EQUIVALENT,
+     /* min, max, act ct */ 0, 1, 0,
+     /* opt state flags  */ LISTNICS_FLAGS, 0,
+     /* last opt argumnt */ { NULL },
+     /* arg list/cookie  */ NULL,
+     /* must/cannot opts */ NULL, NULL,
+     /* option proc      */ doOptListnics,
+     /* desc, NAME, name */ zListnicsText, zListnics_NAME, zListnics_Name,
+     /* disablement strs */ NULL, NULL },
+
+  {  /* entry idx, value */ 37, VALUE_OPT_LOOP,
+     /* equiv idx, value */ 37, VALUE_OPT_LOOP,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LOOP_FLAGS, 0,
@@ -1168,8 +1203,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zLoopText, zLoop_NAME, zLoop_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 37, VALUE_OPT_PKTLEN,
-     /* equiv idx, value */ 37, VALUE_OPT_PKTLEN,
+  {  /* entry idx, value */ 38, VALUE_OPT_PKTLEN,
+     /* equiv idx, value */ 38, VALUE_OPT_PKTLEN,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PKTLEN_FLAGS, 0,
@@ -1180,8 +1215,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPktlenText, zPktlen_NAME, zPktlen_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 38, VALUE_OPT_LIMIT,
-     /* equiv idx, value */ 38, VALUE_OPT_LIMIT,
+  {  /* entry idx, value */ 39, VALUE_OPT_LIMIT,
+     /* equiv idx, value */ 39, VALUE_OPT_LIMIT,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LIMIT_FLAGS, 0,
@@ -1192,8 +1227,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zLimitText, zLimit_NAME, zLimit_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 39, VALUE_OPT_MULTIPLIER,
-     /* equiv idx, value */ 39, VALUE_OPT_MULTIPLIER,
+  {  /* entry idx, value */ 40, VALUE_OPT_MULTIPLIER,
+     /* equiv idx, value */ 40, VALUE_OPT_MULTIPLIER,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MULTIPLIER_FLAGS, 0,
@@ -1204,8 +1239,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zMultiplierText, zMultiplier_NAME, zMultiplier_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 40, VALUE_OPT_PPS,
-     /* equiv idx, value */ 40, VALUE_OPT_PPS,
+  {  /* entry idx, value */ 41, VALUE_OPT_PPS,
+     /* equiv idx, value */ 41, VALUE_OPT_PPS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PPS_FLAGS, 0,
@@ -1216,8 +1251,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPpsText, zPps_NAME, zPps_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 41, VALUE_OPT_MBPS,
-     /* equiv idx, value */ 41, VALUE_OPT_MBPS,
+  {  /* entry idx, value */ 42, VALUE_OPT_MBPS,
+     /* equiv idx, value */ 42, VALUE_OPT_MBPS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MBPS_FLAGS, 0,
@@ -1228,8 +1263,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zMbpsText, zMbps_NAME, zMbps_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 42, VALUE_OPT_TOPSPEED,
-     /* equiv idx, value */ 42, VALUE_OPT_TOPSPEED,
+  {  /* entry idx, value */ 43, VALUE_OPT_TOPSPEED,
+     /* equiv idx, value */ 43, VALUE_OPT_TOPSPEED,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ TOPSPEED_FLAGS, 0,
@@ -1240,8 +1275,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zTopspeedText, zTopspeed_NAME, zTopspeed_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 43, VALUE_OPT_ONEATATIME,
-     /* equiv idx, value */ 43, VALUE_OPT_ONEATATIME,
+  {  /* entry idx, value */ 44, VALUE_OPT_ONEATATIME,
+     /* equiv idx, value */ 44, VALUE_OPT_ONEATATIME,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ ONEATATIME_FLAGS, 0,
@@ -1252,8 +1287,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zOneatatimeText, zOneatatime_NAME, zOneatatime_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 44, VALUE_OPT_PID,
-     /* equiv idx, value */ 44, VALUE_OPT_PID,
+  {  /* entry idx, value */ 45, VALUE_OPT_PID,
+     /* equiv idx, value */ 45, VALUE_OPT_PID,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PID_FLAGS, 0,
@@ -1264,8 +1299,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPidText, zPid_NAME, zPid_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 45, VALUE_OPT_VERSION,
-     /* equiv idx, value */ 45, VALUE_OPT_VERSION,
+  {  /* entry idx, value */ 46, VALUE_OPT_VERSION,
+     /* equiv idx, value */ 46, VALUE_OPT_VERSION,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ VERSION_FLAGS, 0,
@@ -1276,8 +1311,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zVersionText, zVersion_NAME, zVersion_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 46, VALUE_OPT_LESS_HELP,
-     /* equiv idx, value */ 46, VALUE_OPT_LESS_HELP,
+  {  /* entry idx, value */ 47, VALUE_OPT_LESS_HELP,
+     /* equiv idx, value */ 47, VALUE_OPT_LESS_HELP,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LESS_HELP_FLAGS, 0,
@@ -1407,7 +1442,7 @@ tOptions tcpreplayOptions = {
       NO_EQUIVALENT /* index of '-#' option */,
       9 /* index of default opt */
     },
-    51 /* full option count */, 47 /* user option count */,
+    52 /* full option count */, 48 /* user option count */,
     tcpreplay_full_usage, tcpreplay_short_usage
 };
 
@@ -1681,6 +1716,26 @@ doOptDbug(
 
 /* * * * * * *
  *
+ *   For the listnics option, when ENABLE_PCAP_FINDALLDEVS is #define-d.
+ */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+static void
+doOptListnics(
+    tOptions*   pOptions,
+    tOptDesc*   pOptDesc )
+{
+    /* extracted from tcpreplay_opts.def, line 256 */
+
+interface_list_t *list = get_interface_list();
+list_interfaces(list);
+free(list);
+    exit(0);
+
+}
+#endif /* defined ENABLE_PCAP_FINDALLDEVS */
+
+/* * * * * * *
+ *
  *   For the loop option.
  */
 static void

+ 22 - 18
src/tcpreplay_edit_opts.h

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (tcpreplay_edit_opts.h)
  *  
- *  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:21 AM PDT
+ *  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:43 AM PDT
  *  From the definitions    tcpreplay_opts.def
  *  and the template file   options
  *
@@ -112,24 +112,25 @@ typedef enum {
         INDEX_OPT_CACHEFILE        = 33,
         INDEX_OPT_INTF1            = 34,
         INDEX_OPT_INTF2            = 35,
-        INDEX_OPT_LOOP             = 36,
-        INDEX_OPT_PKTLEN           = 37,
-        INDEX_OPT_LIMIT            = 38,
-        INDEX_OPT_MULTIPLIER       = 39,
-        INDEX_OPT_PPS              = 40,
-        INDEX_OPT_MBPS             = 41,
-        INDEX_OPT_TOPSPEED         = 42,
-        INDEX_OPT_ONEATATIME       = 43,
-        INDEX_OPT_PID              = 44,
-        INDEX_OPT_VERSION          = 45,
-        INDEX_OPT_LESS_HELP        = 46,
-        INDEX_OPT_HELP             = 47,
-        INDEX_OPT_MORE_HELP        = 48,
-        INDEX_OPT_SAVE_OPTS        = 49,
-        INDEX_OPT_LOAD_OPTS        = 50
+        INDEX_OPT_LISTNICS         = 36,
+        INDEX_OPT_LOOP             = 37,
+        INDEX_OPT_PKTLEN           = 38,
+        INDEX_OPT_LIMIT            = 39,
+        INDEX_OPT_MULTIPLIER       = 40,
+        INDEX_OPT_PPS              = 41,
+        INDEX_OPT_MBPS             = 42,
+        INDEX_OPT_TOPSPEED         = 43,
+        INDEX_OPT_ONEATATIME       = 44,
+        INDEX_OPT_PID              = 45,
+        INDEX_OPT_VERSION          = 46,
+        INDEX_OPT_LESS_HELP        = 47,
+        INDEX_OPT_HELP             = 48,
+        INDEX_OPT_MORE_HELP        = 49,
+        INDEX_OPT_SAVE_OPTS        = 50,
+        INDEX_OPT_LOAD_OPTS        = 51
 } teOptIndex;
 
-#define OPTION_CT    51
+#define OPTION_CT    52
 
 /*
  *  Interface defines for all options.  Replace "n" with the UPPER_CASED
@@ -214,9 +215,12 @@ typedef enum {
 #define VALUE_OPT_CACHEFILE      'c'
 #define VALUE_OPT_INTF1          'i'
 #define VALUE_OPT_INTF2          'I'
+#ifdef ENABLE_PCAP_FINDALLDEVS
+#define VALUE_OPT_LISTNICS       132
+#endif /* ENABLE_PCAP_FINDALLDEVS */
 #define VALUE_OPT_LOOP           'l'
 #define OPT_VALUE_LOOP           (DESC(LOOP).optArg.argInt)
-#define VALUE_OPT_PKTLEN         133
+#define VALUE_OPT_PKTLEN         134
 #define VALUE_OPT_LIMIT          'L'
 #define OPT_VALUE_LIMIT          (DESC(LIMIT).optArg.argInt)
 #define VALUE_OPT_MULTIPLIER     'x'

+ 79 - 24
src/tcpreplay_opts.c

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (tcpreplay_opts.c)
  *  
- *  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:12 AM PDT
+ *  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:37 AM PDT
  *  From the definitions    tcpreplay_opts.def
  *  and the template file   options
  *
@@ -261,6 +261,24 @@ static const int
         | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
 
 /*
+ *  Listnics option description:
+ */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+tSCC    zListnicsText[] =
+        "List available network interfaces and exit";
+tSCC    zListnics_NAME[]           = "LISTNICS";
+tSCC    zListnics_Name[]           = "listnics";
+#define LISTNICS_FLAGS       (OPTST_DISABLED | OPTST_IMM)
+
+#else   /* disable Listnics */
+#define VALUE_OPT_LISTNICS NO_EQUIVALENT
+#define LISTNICS_FLAGS       (OPTST_OMITTED | OPTST_NO_INIT)
+#define zListnicsText       NULL
+#define zListnics_NAME      NULL
+#define zListnics_Name      NULL
+#endif  /* ENABLE_PCAP_FINDALLDEVS */
+
+/*
  *  Loop option description:
  */
 tSCC    zLoopText[] =
@@ -430,6 +448,11 @@ tSCC zNotLoad_Opts_Pfx[]  = "no";
 #else /* not DEBUG */
 # define doOptDbug NULL
 #endif /* def/not DEBUG */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+  static tOptProc doOptListnics;
+#else /* not ENABLE_PCAP_FINDALLDEVS */
+# define doOptListnics NULL
+#endif /* def/not ENABLE_PCAP_FINDALLDEVS */
 extern tOptProc
     optionNumericVal, optionPagedUsage;
 static tOptProc
@@ -573,8 +596,20 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zIntf2Text, zIntf2_NAME, zIntf2_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 11, VALUE_OPT_LOOP,
-     /* equiv idx, value */ 11, VALUE_OPT_LOOP,
+  {  /* entry idx, value */ 11, VALUE_OPT_LISTNICS,
+     /* equiv idx, value */ 11, VALUE_OPT_LISTNICS,
+     /* equivalenced to  */ NO_EQUIVALENT,
+     /* min, max, act ct */ 0, 1, 0,
+     /* opt state flags  */ LISTNICS_FLAGS, 0,
+     /* last opt argumnt */ { NULL },
+     /* arg list/cookie  */ NULL,
+     /* must/cannot opts */ NULL, NULL,
+     /* option proc      */ doOptListnics,
+     /* desc, NAME, name */ zListnicsText, zListnics_NAME, zListnics_Name,
+     /* disablement strs */ NULL, NULL },
+
+  {  /* entry idx, value */ 12, VALUE_OPT_LOOP,
+     /* equiv idx, value */ 12, VALUE_OPT_LOOP,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LOOP_FLAGS, 0,
@@ -585,8 +620,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zLoopText, zLoop_NAME, zLoop_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 12, VALUE_OPT_PKTLEN,
-     /* equiv idx, value */ 12, VALUE_OPT_PKTLEN,
+  {  /* entry idx, value */ 13, VALUE_OPT_PKTLEN,
+     /* equiv idx, value */ 13, VALUE_OPT_PKTLEN,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PKTLEN_FLAGS, 0,
@@ -597,8 +632,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPktlenText, zPktlen_NAME, zPktlen_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 13, VALUE_OPT_LIMIT,
-     /* equiv idx, value */ 13, VALUE_OPT_LIMIT,
+  {  /* entry idx, value */ 14, VALUE_OPT_LIMIT,
+     /* equiv idx, value */ 14, VALUE_OPT_LIMIT,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LIMIT_FLAGS, 0,
@@ -609,8 +644,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zLimitText, zLimit_NAME, zLimit_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 14, VALUE_OPT_MULTIPLIER,
-     /* equiv idx, value */ 14, VALUE_OPT_MULTIPLIER,
+  {  /* entry idx, value */ 15, VALUE_OPT_MULTIPLIER,
+     /* equiv idx, value */ 15, VALUE_OPT_MULTIPLIER,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MULTIPLIER_FLAGS, 0,
@@ -621,8 +656,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zMultiplierText, zMultiplier_NAME, zMultiplier_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 15, VALUE_OPT_PPS,
-     /* equiv idx, value */ 15, VALUE_OPT_PPS,
+  {  /* entry idx, value */ 16, VALUE_OPT_PPS,
+     /* equiv idx, value */ 16, VALUE_OPT_PPS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PPS_FLAGS, 0,
@@ -633,8 +668,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPpsText, zPps_NAME, zPps_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 16, VALUE_OPT_MBPS,
-     /* equiv idx, value */ 16, VALUE_OPT_MBPS,
+  {  /* entry idx, value */ 17, VALUE_OPT_MBPS,
+     /* equiv idx, value */ 17, VALUE_OPT_MBPS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MBPS_FLAGS, 0,
@@ -645,8 +680,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zMbpsText, zMbps_NAME, zMbps_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 17, VALUE_OPT_TOPSPEED,
-     /* equiv idx, value */ 17, VALUE_OPT_TOPSPEED,
+  {  /* entry idx, value */ 18, VALUE_OPT_TOPSPEED,
+     /* equiv idx, value */ 18, VALUE_OPT_TOPSPEED,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ TOPSPEED_FLAGS, 0,
@@ -657,8 +692,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zTopspeedText, zTopspeed_NAME, zTopspeed_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 18, VALUE_OPT_ONEATATIME,
-     /* equiv idx, value */ 18, VALUE_OPT_ONEATATIME,
+  {  /* entry idx, value */ 19, VALUE_OPT_ONEATATIME,
+     /* equiv idx, value */ 19, VALUE_OPT_ONEATATIME,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ ONEATATIME_FLAGS, 0,
@@ -669,8 +704,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zOneatatimeText, zOneatatime_NAME, zOneatatime_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 19, VALUE_OPT_PID,
-     /* equiv idx, value */ 19, VALUE_OPT_PID,
+  {  /* entry idx, value */ 20, VALUE_OPT_PID,
+     /* equiv idx, value */ 20, VALUE_OPT_PID,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PID_FLAGS, 0,
@@ -681,8 +716,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zPidText, zPid_NAME, zPid_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 20, VALUE_OPT_VERSION,
-     /* equiv idx, value */ 20, VALUE_OPT_VERSION,
+  {  /* entry idx, value */ 21, VALUE_OPT_VERSION,
+     /* equiv idx, value */ 21, VALUE_OPT_VERSION,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ VERSION_FLAGS, 0,
@@ -693,8 +728,8 @@ static tOptDesc optDesc[ OPTION_CT ] = {
      /* desc, NAME, name */ zVersionText, zVersion_NAME, zVersion_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 21, VALUE_OPT_LESS_HELP,
-     /* equiv idx, value */ 21, VALUE_OPT_LESS_HELP,
+  {  /* entry idx, value */ 22, VALUE_OPT_LESS_HELP,
+     /* equiv idx, value */ 22, VALUE_OPT_LESS_HELP,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LESS_HELP_FLAGS, 0,
@@ -823,7 +858,7 @@ tOptions tcpreplayOptions = {
       NO_EQUIVALENT /* index of '-#' option */,
       NO_EQUIVALENT /* index of default opt */
     },
-    26 /* full option count */, 22 /* user option count */,
+    27 /* full option count */, 23 /* user option count */,
     tcpreplay_full_usage, tcpreplay_short_usage
 };
 
@@ -893,6 +928,26 @@ doOptDbug(
 
 /* * * * * * *
  *
+ *   For the listnics option, when ENABLE_PCAP_FINDALLDEVS is #define-d.
+ */
+#ifdef ENABLE_PCAP_FINDALLDEVS
+static void
+doOptListnics(
+    tOptions*   pOptions,
+    tOptDesc*   pOptDesc )
+{
+    /* extracted from tcpreplay_opts.def, line 256 */
+
+interface_list_t *list = get_interface_list();
+list_interfaces(list);
+free(list);
+    exit(0);
+
+}
+#endif /* defined ENABLE_PCAP_FINDALLDEVS */
+
+/* * * * * * *
+ *
  *   For the loop option.
  */
 static void

+ 2 - 2
src/tcpreplay_opts.def

@@ -245,7 +245,7 @@ flag = {
     descrip     = "Client/secondary traffic output interface";
     doc         = "";
 };
-/*
+
 flag = {
 	ifdef		= ENABLE_PCAP_FINDALLDEVS;
 	name		= listnics;
@@ -261,7 +261,7 @@ flag = {
 	
 EOFlag;
 };
-*/
+
 /*
  * Limits and loops: -l
  */

+ 22 - 18
src/tcpreplay_opts.h

@@ -2,7 +2,7 @@
  *  
  *  DO NOT EDIT THIS FILE   (tcpreplay_opts.h)
  *  
- *  It has been AutoGen-ed  Thursday May 15, 2008 at 08:51:12 AM PDT
+ *  It has been AutoGen-ed  Monday June  9, 2008 at 11:05:36 AM PDT
  *  From the definitions    tcpreplay_opts.def
  *  and the template file   options
  *
@@ -88,24 +88,25 @@ typedef enum {
         INDEX_OPT_CACHEFILE        =  8,
         INDEX_OPT_INTF1            =  9,
         INDEX_OPT_INTF2            = 10,
-        INDEX_OPT_LOOP             = 11,
-        INDEX_OPT_PKTLEN           = 12,
-        INDEX_OPT_LIMIT            = 13,
-        INDEX_OPT_MULTIPLIER       = 14,
-        INDEX_OPT_PPS              = 15,
-        INDEX_OPT_MBPS             = 16,
-        INDEX_OPT_TOPSPEED         = 17,
-        INDEX_OPT_ONEATATIME       = 18,
-        INDEX_OPT_PID              = 19,
-        INDEX_OPT_VERSION          = 20,
-        INDEX_OPT_LESS_HELP        = 21,
-        INDEX_OPT_HELP             = 22,
-        INDEX_OPT_MORE_HELP        = 23,
-        INDEX_OPT_SAVE_OPTS        = 24,
-        INDEX_OPT_LOAD_OPTS        = 25
+        INDEX_OPT_LISTNICS         = 11,
+        INDEX_OPT_LOOP             = 12,
+        INDEX_OPT_PKTLEN           = 13,
+        INDEX_OPT_LIMIT            = 14,
+        INDEX_OPT_MULTIPLIER       = 15,
+        INDEX_OPT_PPS              = 16,
+        INDEX_OPT_MBPS             = 17,
+        INDEX_OPT_TOPSPEED         = 18,
+        INDEX_OPT_ONEATATIME       = 19,
+        INDEX_OPT_PID              = 20,
+        INDEX_OPT_VERSION          = 21,
+        INDEX_OPT_LESS_HELP        = 22,
+        INDEX_OPT_HELP             = 23,
+        INDEX_OPT_MORE_HELP        = 24,
+        INDEX_OPT_SAVE_OPTS        = 25,
+        INDEX_OPT_LOAD_OPTS        = 26
 } teOptIndex;
 
-#define OPTION_CT    26
+#define OPTION_CT    27
 
 /*
  *  Interface defines for all options.  Replace "n" with the UPPER_CASED
@@ -156,9 +157,12 @@ typedef enum {
 #define VALUE_OPT_CACHEFILE      'c'
 #define VALUE_OPT_INTF1          'i'
 #define VALUE_OPT_INTF2          'I'
+#ifdef ENABLE_PCAP_FINDALLDEVS
+#define VALUE_OPT_LISTNICS       11
+#endif /* ENABLE_PCAP_FINDALLDEVS */
 #define VALUE_OPT_LOOP           'l'
 #define OPT_VALUE_LOOP           (DESC(LOOP).optArg.argInt)
-#define VALUE_OPT_PKTLEN         12
+#define VALUE_OPT_PKTLEN         13
 #define VALUE_OPT_LIMIT          'L'
 #define OPT_VALUE_LIMIT          (DESC(LIMIT).optArg.argInt)
 #define VALUE_OPT_MULTIPLIER     'x'

+ 0 - 71
tcpreplay.spec.in

@@ -1,71 +0,0 @@
-# $Id: tcpreplay.spec.in 1910 2007-10-23 21:49:53Z aturner $
-Summary: A tool to replay captured network traffic.
-Name: tcpreplay
-Version: @TCPREPLAY_VERSION@
-Release: @TCPREPLAY_RELEASE@
-License: BSD
-Group: Applications/Internet
-Source0: http://prdownloads.sf.net/tcpreplay/tcpreplay-%{version}.tar.gz
-Prefix: %{_prefix}
-BuildRoot: %{_tmppath}/%{name}-root
-Packager: Aaron Turner <aturner@pobox.com>
-Requires: libnet >= 1.1, libpcap >= 0.5
-BuildPreReq: libnet >= 1.1, libpcap >= 0.5
-URL: http://tcpreplay.sf.net/
-
-# set to 1 to enable debugging
-%define enable_debug 0
-
-%description
-Tcpreplay is a suite of tools to edit and replay captured network traffic.
-The tcpreplay suite includes tcpprep to pre-process pcap files, tcprewrite a
-pcap editor and tcpreplay to send packets.  Also included is tcpbridge which
-is a user-space bridge.
-
-%prep
-%setup -q
-
-%build
-%if %{enable_debug}
-./configure --enable-debug
-%else
-./configure
-%endif
-make
-
-%install
-mkdir -p $RPM_BUILD_ROOT%{_bindir}
-mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1
-install -m755 src/tcpreplay $RPM_BUILD_ROOT%{_bindir} 
-install -m755 src/tcpprep $RPM_BUILD_ROOT%{_bindir} 
-install -m755 src/tcpbridge $RPM_BUILD_ROOT%{_bindir}
-install -m755 src/tcprewrite $RPM_BUILD_ROOT%{_bindir}
-
-install -m644 man/tcpreplay.1 $RPM_BUILD_ROOT%{_mandir}/man1
-install -m644 man/tcpprep.1 $RPM_BUILD_ROOT%{_mandir}/man1
-install -m644 man/tcpbridge.1 $RPM_BUILD_ROOT%{_mandir}/man1
-install -m644 man/tcprewrite.1 $RPM_BUILD_ROOT%{_mandir}/man1
-
-%clean
-rm -rf ${RPM_BUILD_ROOT}
-
-%files
-%defattr(-,root,root)
-%doc	docs/CHANGELOG docs/LICENSE docs/README docs/TODO docs/CREDIT \
-    docs/NOTES docs/INSTALL docs/FAQ.pdf docs/manual.pdf
-%{_bindir}/*
-%{_mandir}/man1/*
-
-
-%changelog
-* Thu Jun 16 2005 Aaron Turner <aturner@pobox.com>
-- Make things right for 3.0
-
-* Wed May 29 2003 Aaron Turner <aturner@pobox.com>
-- Update paths for man pages and docs
-
-* Sun Dec 22 2002 Aaron Turner <aturner@pobox.com>
-- Update packaging to add pcapmerge and remove tcpprep.FAQ
-
-* Fri Jun 28 2002 Aaron Turner <aturner@pobox.com>
-- Initial packaging