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>