summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorgnn <gnn@FreeBSD.org>2008-12-23 20:25:04 +0000
committergnn <gnn@FreeBSD.org>2008-12-23 20:25:04 +0000
commit174adf4f1e57526d8c5cee1b504632ecf2814887 (patch)
tree3fd8716a1be7d20c6edf4973fed35d81efb9d339 /tools
parent399c7590674838f12a7c290ead932f0367f92825 (diff)
downloadFreeBSD-src-174adf4f1e57526d8c5cee1b504632ecf2814887.zip
FreeBSD-src-174adf4f1e57526d8c5cee1b504632ecf2814887.tar.gz
Add a new program, ether_reflect, which is useful in testing ethernet
devices and switches.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/README1
-rw-r--r--tools/tools/ether_reflect/Makefile10
-rw-r--r--tools/tools/ether_reflect/ether_reflect.1108
-rw-r--r--tools/tools/ether_reflect/ether_reflect.c164
4 files changed, 283 insertions, 0 deletions
diff --git a/tools/tools/README b/tools/tools/README
index e1aca07..c00cf2a 100644
--- a/tools/tools/README
+++ b/tools/tools/README
@@ -19,6 +19,7 @@ diffburst OBSOLETE: equivalent functionality is available via split -p.
For example: "split -p ^diff < patchfile". See split(1).
editing Editor modes and the like to help editing FreeBSD code.
epfe Extract printing filter examples from printing.sgml.
+ether_reflect An Ethernet packet reflector for low level testing.
find-sb Scan a disk for possible filesystem superblocks.
gdb_regofs A simple tool that prints out a register offset table
for mapping gdb(1) register numbers to struct reg and
diff --git a/tools/tools/ether_reflect/Makefile b/tools/tools/ether_reflect/Makefile
new file mode 100644
index 0000000..e3cf266
--- /dev/null
+++ b/tools/tools/ether_reflect/Makefile
@@ -0,0 +1,10 @@
+#
+# $FreeBSD$
+#
+# A Makefile that builds both the ether_reflect program and its manual page.
+
+PROG= ether_reflect
+
+LDADD+= -lpcap
+
+.include <bsd.prog.mk>
diff --git a/tools/tools/ether_reflect/ether_reflect.1 b/tools/tools/ether_reflect/ether_reflect.1
new file mode 100644
index 0000000..704a4b0
--- /dev/null
+++ b/tools/tools/ether_reflect/ether_reflect.1
@@ -0,0 +1,108 @@
+.\" Copyright (c) 2008 George V. Neville-Neil
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 23, 2008
+.Dt ether_reflect 1
+.Os
+.Sh NAME
+.Nm ether_reflect
+.Nd "reflect ethernet packets"
+.Sh SYNOPSIS
+.Nm
+.Op Fl a Ar ethernet address
+.Op Fl e Ar ethertype
+.Op Fl i Ar interface
+.Op Fl t Ar timeout
+.Op Fl p
+.Op Fl d
+.Sh DESCRIPTION
+The
+.Nm
+command implements a simple ethernet packet reflector using the
+.Xr PCAP 3
+library and
+.Xr bpf 4 ,
+the Berkeley Packet Filter. The program is useful primarily to test
+the low level round trip time of packets through an Ethernet interface
+and/or a switch. Network protocols, such as IP, and the network stack
+in general are never invoked, only the device driver that implements
+the particular interface is executed. As the
+.Nm
+command uses the
+.Xr bpf 4
+device the user must have root privileges to execute this program.
+.Pp
+The options are as follows:
+.Bl -tag -width ".Fl d Ar argument"
+.It Fl a Ar address
+Instead of reversing the ethernet destination and source addresses
+supply a different destination ethernet address for each packet
+received.
+.It Fl e Ar ether type
+Use a different ethertype than the default, 0x8822, which is the IEEE
+ether type for driver testing.
+.It Fl i Ar interface
+Network interface, which can be found with ifconfig(1).
+.It Fl t Ar timeout
+The time, in milliseconds, to wait for a packet. Lower times decrease
+latency at the cost of CPU.
+.It Fl p
+Set the device into promiscuous mode before testing. This is not
+usually necessary.
+.It Fl d
+Debug output. Print various small pieces of debug information.
+.El
+.Sh EXAMPLES
+The following is an example of a typical usage
+of the
+.Nm
+command:
+.Pp
+.Dl "ether_reflect -i em0 -t 1"
+.Pp
+Reflect all test packets, those with an ether type of 0x8822, which
+are seen on ineterface em0. The timeout is 1 millisecond.
+.Pp
+.Dl "ether_reflect -i em0 -a 00:00:00:aa:bb:cc -t 1"
+.Pp
+Rewrite the destination address in each packet to 00:00:00:aa:bb:cc
+before reflecting the packet.
+.Sh SEE ALSO
+.Xr ifconfig 8 ,
+.Xr tcpdump 1 ,
+.Xr pcap 4 ,
+.Xr bpf 2 .
+.Sh HISTORY
+The
+.Nm
+program first appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+This
+manual page was written by
+.An George V. Neville-Neil Aq gnn@FreeBSD.org .
+.Sh BUGS
+Should be reported to the author or to net@freebsd.org.
diff --git a/tools/tools/ether_reflect/ether_reflect.c b/tools/tools/ether_reflect/ether_reflect.c
new file mode 100644
index 0000000..bb6d865
--- /dev/null
+++ b/tools/tools/ether_reflect/ether_reflect.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2008, Neville-Neil Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: George V. Neville-Neil
+ *
+ * Purpose: This program uses libpcap to read packets from the network
+ * of a specific ethertype (default is 0x8822) and reflects them back
+ * out the same interface with their destination and source mac
+ * addresses reversed.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <pcap-int.h>
+#include <pcap.h>
+#include <net/ethernet.h>
+
+#define ETHER_TYPE_TEST "0x8822"
+#define SNAPLEN 96
+#define MAXPROG 128
+
+char errbuf[PCAP_ERRBUF_SIZE];
+
+void usage(char* message) {
+ if (message != NULL)
+ printf ("error: %s\n", message);
+ printf("usage: ether_reflect -i interface -e ethertype "
+ "-a address -t timeout -p -d\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int ch;
+ int debug = 0, promisc = 0;
+ int timeout = 100;
+ bpf_u_int32 localnet=0, netmask=0;
+ unsigned int error = 0;
+ char *interface = NULL;
+ char *proto = ETHER_TYPE_TEST;
+ char in_string[MAXPROG];
+ char tmp[ETHER_ADDR_LEN];
+ char addr[ETHER_ADDR_LEN];
+ char *user_addr = NULL;
+ pcap_t *capture;
+ struct bpf_program program;
+ struct pcap_pkthdr *header;
+ unsigned char *packet = NULL;
+
+ while ((ch = getopt(argc, argv, "a:e:i:t:pd")) != -1) {
+ switch (ch) {
+ case 'a':
+ user_addr = optarg;
+ break;
+ case 'e':
+ proto = optarg;
+ break;
+ case 'i':
+ interface = optarg;
+ break;
+ case 'p':
+ promisc = 1;
+ break;
+ case 't':
+ timeout = atoi(optarg);
+ break;
+ case 'd':
+ debug = 1;
+ break;
+ case '?':
+ default:
+ usage("invalid arguments");
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (interface == NULL)
+ usage("You must specify an interface");
+
+ if (user_addr != NULL)
+ ether_aton_r(user_addr, (struct ether_addr *)&tmp);
+
+ if ((capture = pcap_open_live(interface, SNAPLEN, promisc, timeout,
+ &errbuf[0])) == NULL)
+ usage(errbuf);
+
+ snprintf(&in_string[0], MAXPROG, "ether proto %s\n", proto);
+
+ if (pcap_lookupnet(interface, &localnet, &netmask, errbuf) < 0)
+ usage(errbuf);
+
+ if (pcap_compile(capture, &program, in_string, 1, netmask) < 0)
+ usage(errbuf);
+
+ if (pcap_setfilter(capture, &program) < 0)
+ usage(errbuf);
+
+ if (pcap_setdirection(capture, PCAP_D_IN) < 0)
+ usage(errbuf);
+
+ while (1) {
+ error = pcap_next_ex(capture, &header,
+ (const unsigned char **)&packet);
+ if (error == 0)
+ continue;
+ if (error == -1)
+ usage("packet read error");
+ if (error == -2)
+ usage("savefile? invalid!");
+
+ if (debug) {
+ printf ("got packet of %d length\n", header->len);
+ printf ("header %s\n",
+ ether_ntoa((const struct ether_addr*)
+ &packet[0]));
+ printf ("header %s\n",
+ ether_ntoa((const struct ether_addr*)
+ &packet[ETHER_ADDR_LEN]));
+ }
+
+ /*
+ * If the user did not supply an address then we simply
+ * reverse the source and destination addresses.
+ */
+ if (user_addr == NULL) {
+ bcopy(packet, &tmp, ETHER_ADDR_LEN);
+ bcopy(&packet[ETHER_ADDR_LEN], packet, ETHER_ADDR_LEN);
+ bcopy(&tmp, &packet[ETHER_ADDR_LEN], ETHER_ADDR_LEN);
+ } else {
+ bcopy(&tmp, packet, ETHER_ADDR_LEN);
+ }
+ if (pcap_inject(capture, packet, header->len) < 0)
+ if (debug)
+ pcap_perror(capture, "pcap_inject");
+ }
+}
OpenPOWER on IntegriCloud