mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-01 12:19:28 +00:00
Add a new program, ether_reflect, which is useful in testing ethernet
devices and switches.
This commit is contained in:
parent
d541033521
commit
e39eeac77b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186457
@ -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
|
||||
|
10
tools/tools/ether_reflect/Makefile
Normal file
10
tools/tools/ether_reflect/Makefile
Normal file
@ -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>
|
108
tools/tools/ether_reflect/ether_reflect.1
Normal file
108
tools/tools/ether_reflect/ether_reflect.1
Normal file
@ -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.
|
164
tools/tools/ether_reflect/ether_reflect.c
Normal file
164
tools/tools/ether_reflect/ether_reflect.c
Normal file
@ -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");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user