Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Dec 2008 20:25:04 +0000 (UTC)
From:      "George V. Neville-Neil" <gnn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186457 - in head/tools/tools: . ether_reflect
Message-ID:  <200812232025.mBNKP4FT012697@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gnn
Date: Tue Dec 23 20:25:04 2008
New Revision: 186457
URL: http://svn.freebsd.org/changeset/base/186457

Log:
  Add a new program, ether_reflect, which is useful in testing ethernet
  devices and switches.

Added:
  head/tools/tools/ether_reflect/
  head/tools/tools/ether_reflect/Makefile   (contents, props changed)
  head/tools/tools/ether_reflect/ether_reflect.1   (contents, props changed)
  head/tools/tools/ether_reflect/ether_reflect.c   (contents, props changed)
Modified:
  head/tools/tools/README

Modified: head/tools/tools/README
==============================================================================
--- head/tools/tools/README	Tue Dec 23 20:07:51 2008	(r186456)
+++ head/tools/tools/README	Tue Dec 23 20:25:04 2008	(r186457)
@@ -19,6 +19,7 @@ diffburst	OBSOLETE: equivalent functiona
 		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

Added: head/tools/tools/ether_reflect/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/ether_reflect/Makefile	Tue Dec 23 20:25:04 2008	(r186457)
@@ -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>

Added: head/tools/tools/ether_reflect/ether_reflect.1
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/ether_reflect/ether_reflect.1	Tue Dec 23 20:25:04 2008	(r186457)
@@ -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.

Added: head/tools/tools/ether_reflect/ether_reflect.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/ether_reflect/ether_reflect.c	Tue Dec 23 20:25:04 2008	(r186457)
@@ -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");
+	}
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812232025.mBNKP4FT012697>