#include <sys/cdefs.h>
#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 (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");
}
}