summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2017-06-07 22:24:52 +0300
committerTobias Klauser <tklauser@distanz.ch>2017-06-09 15:50:06 +0200
commit78c13b71e196a107eaa4ec00bb40b062929a6a88 (patch)
tree39598c8a9bd49e1a3d13247c288c04ea0778d69d
parent322deaf9bae5dc87b174c4369e7d00b6bb0bf641 (diff)
trafgen: Allow to generate packets to output pcap file
Add trafgen_dev.c module which provides generic way of reading and writing packets to/from networking device or a pcap file. Also allow to handle output pcap file via '-o, --out, --dev' option. It might be useful in future for testing some link protocols which is not easy to capture (e.g. wlan packets) w/o having some special setup. Signed-off-by: Vadim Kochan <vadim4j@gmail.com> [tklauser: fix whitespace issues] Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--trafgen.85
-rw-r--r--trafgen.c102
-rw-r--r--trafgen/Makefile1
-rw-r--r--trafgen_dev.c258
-rw-r--r--trafgen_dev.h49
-rw-r--r--trafgen_l2.c4
-rw-r--r--trafgen_l3.c8
-rw-r--r--trafgen_proto.c50
-rw-r--r--trafgen_proto.h6
9 files changed, 391 insertions, 92 deletions
diff --git a/trafgen.8 b/trafgen.8
index fd9788a..50deacf 100644
--- a/trafgen.8
+++ b/trafgen.8
@@ -74,8 +74,9 @@ It is also possible to specify PCAP file with .pcap extension via -i,--in option
by default packets will be sent at rate considering timestamp from PCAP file which
might be reset via -b/-t options.
.PP
-.SS -o <dev>, -d <dev>, --out <dev>, --dev <dev>
-Defines the outgoing networking device such as eth0, wlan0 and others.
+.SS -o <dev|pcap>, -d <dev|pcap>, --out <dev|pcap>, --dev <dev|pcap>
+Defines the outgoing networking device such as eth0, wlan0 and others or
+a pcap file.
.PP
.SS -p, --cpp
Pass the packet configuration to the C preprocessor before reading it into
diff --git a/trafgen.c b/trafgen.c
index b25760f..6ae0076 100644
--- a/trafgen.c
+++ b/trafgen.c
@@ -57,6 +57,7 @@
#include "csum.h"
#include "trafgen_proto.h"
#include "pcap_io.h"
+#include "trafgen_dev.h"
enum shaper_type {
SHAPER_NONE,
@@ -79,6 +80,8 @@ struct shaper {
struct ctx {
bool rand, rfraw, jumbo_support, verbose, smoke_test, enforce, qdisc_path;
size_t reserve_size;
+ struct dev_io *dev_out;
+ struct dev_io *dev_in;
unsigned long num;
unsigned int cpus;
uid_t uid; gid_t gid;
@@ -145,7 +148,6 @@ static const char *copyright = "Please report bugs to <netsniff-ng@googlegroups.
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.";
-static int sock;
static struct cpu_stats *stats;
static unsigned int seed;
@@ -664,11 +666,6 @@ static void xmit_slowpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned lon
unsigned long num = 1, i = 0;
struct timeval start, end, diff;
unsigned long long tx_bytes = 0, tx_packets = 0;
- struct sockaddr_ll saddr = {
- .sll_family = PF_PACKET,
- .sll_halen = ETH_ALEN,
- .sll_ifindex = device_ifindex(ctx->device),
- };
if (ctx->num > 0)
num = ctx->num;
@@ -688,8 +685,7 @@ static void xmit_slowpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned lon
while (likely(sigint == 0 && num > 0 && plen > 0)) {
packet_apply_dyn_elements(i);
retry:
- ret = sendto(sock, packets[i].payload, packets[i].len, 0,
- (struct sockaddr *) &saddr, sizeof(saddr));
+ ret = dev_io_write(ctx->dev_out, packets[i].payload, packets[i].len);
if (unlikely(ret < 0)) {
if (errno == ENOBUFS) {
sched_yield();
@@ -745,15 +741,16 @@ retry:
static void xmit_fastpath_or_die(struct ctx *ctx, unsigned int cpu, unsigned long orig_num)
{
- int ifindex = device_ifindex(ctx->device);
+ int ifindex = dev_io_ifindex_get(ctx->dev_out);
uint8_t *out = NULL;
unsigned int it = 0;
unsigned long num = 1, i = 0;
- size_t size = ring_size(ctx->device, ctx->reserve_size);
+ size_t size = ring_size(dev_io_name_get(ctx->dev_out), ctx->reserve_size);
struct ring tx_ring;
struct frame_map *hdr;
struct timeval start, end, diff;
unsigned long long tx_bytes = 0, tx_packets = 0;
+ int sock = dev_io_fd_get(ctx->dev_out);
set_sock_prio(sock, 512);
@@ -938,69 +935,37 @@ static void xmit_packet_precheck(struct ctx *ctx, unsigned int cpu)
}
}
-static void pcap_load_packets(const char *path)
+static void pcap_load_packets(struct dev_io *dev)
{
- const struct pcap_file_ops *pcap_io = pcap_ops[PCAP_OPS_SG];
- uint32_t link_type, magic;
- pcap_pkthdr_t phdr;
+ struct timespec tstamp;
size_t buf_len;
uint8_t *buf;
- int ret;
- int fd;
-
- fd = open(path, O_RDONLY | O_LARGEFILE | O_NOATIME);
- if (fd < 0 && errno == EPERM)
- fd = open_or_die(path, O_RDONLY | O_LARGEFILE);
- if (fd < 0)
- panic("Cannot open file %s! %s.\n", path, strerror(errno));
-
- if (pcap_io->init_once_pcap)
- pcap_io->init_once_pcap(false);
-
- ret = pcap_io->pull_fhdr_pcap(fd, &magic, &link_type);
- if (ret)
- panic("Error reading pcap header!\n");
-
- if (pcap_io->prepare_access_pcap) {
- ret = pcap_io->prepare_access_pcap(fd, PCAP_MODE_RD, false);
- if (ret)
- panic("Error prepare reading pcap!\n");
- }
+ int pkt_len;
buf_len = round_up(1024 * 1024, RUNTIME_PAGE_SIZE);
buf = xmalloc_aligned(buf_len, CO_CACHE_LINE_SIZE);
- while (pcap_io->read_pcap(fd, &phdr, magic, buf, buf_len) > 0) {
+ while ((pkt_len = dev_io_read(dev, buf, buf_len, &tstamp)) > 0) {
struct packet *pkt;
- size_t pkt_len;
-
- pkt_len = pcap_get_length(&phdr, magic);
- if (!pkt_len)
- continue;
realloc_packet();
pkt = current_packet();
-
pkt->len = pkt_len;
pkt->payload = xzmalloc(pkt_len);
memcpy(pkt->payload, buf, pkt_len);
- pcap_get_tstamp(&phdr, magic, &pkt->tstamp);
+ memcpy(&pkt->tstamp, &tstamp, sizeof(tstamp));
}
- if (pcap_io->prepare_close_pcap)
- pcap_io->prepare_close_pcap(fd, PCAP_MODE_RD);
-
free(buf);
- close(fd);
}
static void main_loop(struct ctx *ctx, char *confname, bool slow,
unsigned int cpu, bool invoke_cpp, char **cpp_argv,
unsigned long orig_num)
{
- if (ctx->pcap_in) {
- pcap_load_packets(ctx->pcap_in);
+ if (ctx->dev_in && dev_io_is_pcap(ctx->dev_in)) {
+ pcap_load_packets(ctx->dev_in);
shaper_set_tstamp(&ctx->sh, &packets[0].tstamp);
ctx->num = plen;
} else {
@@ -1029,18 +994,14 @@ static void main_loop(struct ctx *ctx, char *confname, bool slow,
fflush(stdout);
}
- sock = pf_socket();
-
- if (ctx->qdisc_path == false)
- set_sock_qdisc_bypass(sock, ctx->verbose);
+ if (dev_io_is_netdev(ctx->dev_out) && ctx->qdisc_path == false)
+ set_sock_qdisc_bypass(dev_io_fd_get(ctx->dev_out), ctx->verbose);
if (slow)
xmit_slowpath_or_die(ctx, cpu, orig_num);
else
xmit_fastpath_or_die(ctx, cpu, orig_num);
- close(sock);
-
cleanup_packets();
}
@@ -1306,16 +1267,12 @@ int main(int argc, char **argv)
panic("No networking device given!\n");
if (confname == NULL && !ctx.packet_str)
panic("No configuration file or packet string given!\n");
- if (device_mtu(ctx.device) == 0)
- panic("This is no networking device!\n");
register_signal(SIGINT, signal_handler);
register_signal(SIGQUIT, signal_handler);
register_signal(SIGTERM, signal_handler);
register_signal(SIGHUP, signal_handler);
- protos_init(ctx.device);
-
if (prio_high) {
set_proc_prio(-20);
set_sched_status(SCHED_FIFO, sched_get_priority_max(SCHED_FIFO));
@@ -1334,7 +1291,21 @@ int main(int argc, char **argv)
sleep(0);
}
- if (shaper_is_set(&ctx.sh) || (ctx.pcap_in)) {
+ if (ctx.pcap_in) {
+ ctx.dev_in = dev_io_open(ctx.pcap_in, DEV_IO_IN);
+ if (!ctx.dev_in)
+ panic("Failed to open input device\n");
+ }
+
+ ctx.dev_out = dev_io_open(ctx.device, DEV_IO_OUT);
+ if (!ctx.dev_out)
+ panic("Failed to open output device\n");
+
+ protos_init(ctx.dev_out);
+
+ if (shaper_is_set(&ctx.sh) || (ctx.dev_in && dev_io_is_pcap(ctx.dev_in))
+ || dev_io_is_pcap(ctx.dev_out)) {
+
prctl(PR_SET_TIMERSLACK, 1UL);
/* Fall back to single core to not mess up correct timing.
* We are slow anyway!
@@ -1351,9 +1322,10 @@ int main(int argc, char **argv)
if (ctx.num)
ctx.cpus = min_t(unsigned int, ctx.num, ctx.cpus);
- irq = device_irq_number(ctx.device);
- if (set_irq_aff)
+ if (set_irq_aff && dev_io_is_netdev(ctx.dev_out)) {
+ irq = device_irq_number(ctx.device);
device_set_irq_affinity_list(irq, 0, ctx.cpus - 1);
+ }
stats = setup_shared_var(ctx.cpus);
@@ -1411,9 +1383,13 @@ int main(int argc, char **argv)
thread_out:
xunlockme();
destroy_shared_var(stats, ctx.cpus);
- if (set_irq_aff)
+ if (dev_io_is_netdev(ctx.dev_out) && set_irq_aff)
device_restore_irq_affinity_list();
+ dev_io_close(ctx.dev_out);
+ if (ctx.dev_in)
+ dev_io_close(ctx.dev_in);
+
argv_free(cpp_argv);
free(ctx.device);
free(ctx.device_trans);
diff --git a/trafgen/Makefile b/trafgen/Makefile
index d38f0b0..381f94d 100644
--- a/trafgen/Makefile
+++ b/trafgen/Makefile
@@ -25,6 +25,7 @@ trafgen-objs = xmalloc.o \
pcap_rw.o \
pcap_mm.o \
iosched.o \
+ trafgen_dev.o \
trafgen_proto.o \
trafgen_l2.o \
trafgen_l3.o \
diff --git a/trafgen_dev.c b/trafgen_dev.c
new file mode 100644
index 0000000..cd99a0c
--- /dev/null
+++ b/trafgen_dev.c
@@ -0,0 +1,258 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2011 - 2013 Daniel Borkmann <dborkma@tik.ee.ethz.ch>,
+ * Swiss federal institute of technology (ETH Zurich)
+ * Subject to the GPL, version 2.
+ */
+
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <net/ethernet.h>
+
+#include "sock.h"
+#include "xmalloc.h"
+#include "pcap_io.h"
+#include "built_in.h"
+#include "trafgen_dev.h"
+
+static int dev_pcap_open(struct dev_io *dev, const char *name, enum dev_io_mode_t mode)
+{
+ dev->pcap_magic = ORIGINAL_TCPDUMP_MAGIC;
+ dev->pcap_ops = pcap_ops[PCAP_OPS_SG];
+
+ if (mode == DEV_IO_IN) {
+ if (!strncmp("-", name, strlen("-"))) {
+ dev->fd = dup_or_die(fileno(stdin));
+ close(fileno(stdin));
+ } else {
+ dev->fd = open(name, O_RDONLY | O_LARGEFILE | O_NOATIME);
+ if (dev->fd < 0 && errno == EPERM)
+ dev->fd = open_or_die(name, O_RDONLY | O_LARGEFILE);
+ }
+
+ dev->pcap_mode = PCAP_MODE_RD;
+ } else if (mode & DEV_IO_OUT) {
+ if (!strncmp("-", name, strlen("-"))) {
+ dev->fd = dup_or_die(fileno(stdout));
+ close(fileno(stdout));
+ } else {
+ dev->fd = open_or_die_m(name, O_RDWR | O_CREAT | O_TRUNC |
+ O_LARGEFILE, DEFFILEMODE);
+ }
+
+ dev->pcap_mode = PCAP_MODE_WR;
+ } else {
+ bug();
+ }
+
+ if (dev->fd < 0)
+ panic("pcap_dev: Cannot open file %s! %s.\n", name, strerror(errno));
+
+ if (dev->pcap_ops->init_once_pcap)
+ dev->pcap_ops->init_once_pcap(false);
+
+ if (mode == DEV_IO_IN) {
+ if (dev->pcap_ops->pull_fhdr_pcap(dev->fd, &dev->pcap_magic, &dev->link_type))
+ panic("Error reading pcap header!\n");
+ }
+
+ if (dev->pcap_ops->prepare_access_pcap) {
+ if (dev->pcap_ops->prepare_access_pcap(dev->fd, dev->pcap_mode, false))
+ panic("Error prepare reading pcap!\n");
+ }
+
+ return 0;
+}
+
+static int dev_pcap_read(struct dev_io *dev, uint8_t *buf, size_t len,
+ struct timespec *tstamp)
+{
+ pcap_pkthdr_t phdr;
+ size_t pkt_len;
+
+ if (dev->pcap_ops->read_pcap(dev->fd, &phdr, dev->pcap_magic, buf, len) <= 0)
+ return -1;
+
+ pkt_len = pcap_get_length(&phdr, dev->pcap_magic);
+ if (!pkt_len)
+ return -1;
+
+ pcap_get_tstamp(&phdr, dev->pcap_magic, tstamp);
+
+ return pkt_len;
+}
+
+static int dev_pcap_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+{
+ struct timeval time;
+ pcap_pkthdr_t phdr;
+ int ret;
+
+ /* Write PCAP file header only once */
+ if (!dev->is_initialized) {
+ if (dev->pcap_ops->push_fhdr_pcap(dev->fd, dev->pcap_magic, dev->link_type)) {
+ fprintf(stderr, "Error writing pcap header!\n");
+ return -1;
+ }
+
+ if (dev->pcap_ops->prepare_access_pcap) {
+ if (dev->pcap_ops->prepare_access_pcap(dev->fd, PCAP_MODE_WR, true)) {
+ fprintf(stderr, "Error prepare writing pcap!\n");
+ return -1;
+ }
+ }
+
+ dev->is_initialized = true;
+ }
+
+ bug_on(gettimeofday(&time, NULL));
+
+ phdr.ppo.ts.tv_sec = time.tv_sec;
+ phdr.ppo.ts.tv_usec = time.tv_usec;
+ phdr.ppo.caplen = len;
+ phdr.ppo.len = len;
+
+ ret = dev->pcap_ops->write_pcap(dev->fd, &phdr, dev->pcap_magic,
+ buf, pcap_get_length(&phdr, dev->pcap_magic));
+
+ if (unlikely(ret != (int) pcap_get_total_length(&phdr, dev->pcap_magic))) {
+ fprintf(stderr, "Write error to pcap!\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static void dev_pcap_close(struct dev_io *dev)
+{
+ if (dev->pcap_mode == PCAP_MODE_WR)
+ dev->pcap_ops->fsync_pcap(dev->fd);
+
+ if (dev->pcap_ops->prepare_close_pcap)
+ dev->pcap_ops->prepare_close_pcap(dev->fd, dev->pcap_mode);
+
+ close(dev->fd);
+}
+
+static const struct dev_io_ops dev_pcap_ops = {
+ .open = dev_pcap_open,
+ .read = dev_pcap_read,
+ .write = dev_pcap_write,
+ .close = dev_pcap_close,
+};
+
+static int dev_net_open(struct dev_io *dev, const char *name, enum dev_io_mode_t mode)
+{
+ dev->ifindex = __device_ifindex(name);
+ dev->dev_type = device_type(name);
+ dev->fd = pf_socket();
+
+ return 0;
+}
+
+static int dev_net_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+{
+ struct sockaddr_ll saddr = {
+ .sll_family = PF_PACKET,
+ .sll_halen = ETH_ALEN,
+ .sll_ifindex = dev->ifindex,
+ };
+
+ return sendto(dev->fd, buf, len, 0, (struct sockaddr *) &saddr, sizeof(saddr));
+}
+
+static const struct dev_io_ops dev_net_ops = {
+ .open = dev_net_open,
+ .write = dev_net_write,
+};
+
+struct dev_io *dev_io_open(const char *name, enum dev_io_mode_t mode)
+{
+ struct dev_io *dev = xzmalloc(sizeof(struct dev_io));
+
+ if (strstr(name, ".pcap")) {
+ dev->ops = &dev_pcap_ops;
+ } else if (device_mtu(name) > 0) {
+ dev->ops = &dev_net_ops;
+ } else {
+ fprintf(stderr, "No networking device or pcap file: %s\n", name);
+ return NULL;
+ }
+
+ if (dev->ops->open) {
+ if (dev->ops->open(dev, name, mode)) {
+ xfree(dev);
+ return NULL;
+ }
+ }
+
+ dev->name = xstrdup(name);
+ return dev;
+};
+
+int dev_io_write(struct dev_io *dev, const uint8_t *buf, size_t len)
+{
+ bug_on(!dev);
+ bug_on(!dev->ops);
+
+ if (dev->ops->write)
+ return dev->ops->write(dev, buf, len);
+
+ return 0;
+}
+
+int dev_io_read(struct dev_io *dev, uint8_t *buf, size_t len,
+ struct timespec *tstamp)
+{
+ bug_on(!dev);
+ bug_on(!dev->ops);
+
+ if (dev->ops->read)
+ return dev->ops->read(dev, buf, len, tstamp);
+
+ return 0;
+}
+
+const char *dev_io_name_get(struct dev_io *dev)
+{
+ return dev->name;
+}
+
+bool dev_io_is_netdev(struct dev_io *dev)
+{
+ return dev->ops == &dev_net_ops;
+}
+
+bool dev_io_is_pcap(struct dev_io *dev)
+{
+ return dev->ops == &dev_pcap_ops;
+}
+
+void dev_io_link_type_set(struct dev_io *dev, int link_type)
+{
+ dev->link_type = link_type;
+}
+
+int dev_io_ifindex_get(struct dev_io *dev)
+{
+ return dev->ifindex;
+}
+
+int dev_io_fd_get(struct dev_io *dev)
+{
+ return dev->fd;
+}
+
+void dev_io_close(struct dev_io *dev)
+{
+ if (dev) {
+ if (dev->ops->close)
+ dev->ops->close(dev);
+
+ free(dev->name);
+ free(dev);
+ }
+}
diff --git a/trafgen_dev.h b/trafgen_dev.h
new file mode 100644
index 0000000..720c630
--- /dev/null
+++ b/trafgen_dev.h
@@ -0,0 +1,49 @@
+#ifndef TRAFGEN_DEV_H
+#define TRAFGEN_DEV_H
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "pcap_io.h"
+
+enum dev_io_mode_t {
+ DEV_IO_IN = 1 << 0,
+ DEV_IO_OUT = 1 << 1,
+};
+
+struct dev_io_ops;
+
+struct dev_io {
+ int fd;
+ char *name;
+ int ifindex;
+ int dev_type;
+ uint32_t link_type;
+ uint32_t pcap_magic;
+ bool is_initialized;
+ enum pcap_mode pcap_mode;
+
+ const struct pcap_file_ops *pcap_ops;
+ const struct dev_io_ops *ops;
+};
+
+struct dev_io_ops {
+ int(*open) (struct dev_io *dev, const char *name, enum dev_io_mode_t mode);
+ int(*write) (struct dev_io *dev, const uint8_t *buf, size_t len);
+ int(*read) (struct dev_io *dev, uint8_t *buf, size_t len, struct timespec *tstamp);
+ void(*close) (struct dev_io *dev);
+};
+
+extern struct dev_io *dev_io_open(const char *name, enum dev_io_mode_t mode);
+extern int dev_io_write(struct dev_io *dev, const uint8_t *buf, size_t len);
+extern int dev_io_read(struct dev_io *dev, uint8_t *buf, size_t len,
+ struct timespec *tstamp);
+extern int dev_io_ifindex_get(struct dev_io *dev);
+extern int dev_io_fd_get(struct dev_io *dev);
+extern const char *dev_io_name_get(struct dev_io *dev);
+extern void dev_io_link_type_set(struct dev_io *dev, int link_type);
+extern bool dev_io_is_netdev(struct dev_io *dev);
+extern bool dev_io_is_pcap(struct dev_io *dev);
+extern void dev_io_close(struct dev_io *dev);
+
+#endif /* TRAFGEN_DEV_H */
diff --git a/trafgen_l2.c b/trafgen_l2.c
index 427ff9b..4858c5f 100644
--- a/trafgen_l2.c
+++ b/trafgen_l2.c
@@ -8,7 +8,9 @@
#include "die.h"
#include "built_in.h"
+#include "linktype.h"
#include "trafgen_l2.h"
+#include "trafgen_dev.h"
#include "trafgen_proto.h"
static struct proto_field eth_fields[] = {
@@ -48,6 +50,8 @@ static void eth_header_init(struct proto_hdr *hdr)
proto_header_fields_add(hdr, eth_fields, array_size(eth_fields));
proto_hdr_field_set_default_dev_mac(hdr, ETH_SRC_ADDR);
+
+ dev_io_link_type_set(proto_dev_get(), LINKTYPE_EN10MB);
}
static const struct proto_ops eth_proto_ops = {
diff --git a/trafgen_l3.c b/trafgen_l3.c
index 7c8a786..7199b89 100644
--- a/trafgen_l3.c
+++ b/trafgen_l3.c
@@ -35,10 +35,10 @@ static struct proto_field ipv4_fields[] = {
static void ipv4_header_init(struct proto_hdr *hdr)
{
- const char *dev = proto_dev_get();
+ struct dev_io *dev = proto_dev_get();
/* In case of tun interface we do not need to create Ethernet header */
- if (dev && device_mtu(dev) && device_type(dev) != ARPHRD_NONE)
+ if (dev_io_is_pcap(dev) || device_type(dev_io_name_get(dev)) != ARPHRD_NONE)
proto_lower_default_add(hdr, PROTO_ETH);
proto_header_fields_add(hdr, ipv4_fields, array_size(ipv4_fields));
@@ -140,10 +140,10 @@ static struct proto_field ipv6_fields[] = {
static void ipv6_header_init(struct proto_hdr *hdr)
{
- const char *dev = proto_dev_get();
+ struct dev_io *dev = proto_dev_get();
/* In case of tun interface we do not need to create Ethernet header */
- if (dev && device_mtu(dev) && device_type(dev) != ARPHRD_NONE)
+ if (dev_io_is_netdev(dev) && device_type(dev_io_name_get(dev)) != ARPHRD_NONE)
proto_lower_default_add(hdr, PROTO_ETH);
proto_header_fields_add(hdr, ipv6_fields, array_size(ipv6_fields));
diff --git a/trafgen_proto.c b/trafgen_proto.c
index 0353d6b..c2cbffb 100644
--- a/trafgen_proto.c
+++ b/trafgen_proto.c
@@ -24,7 +24,7 @@
((f)->mask ? (f)->mask : (0xffffffff))) >> (f)->shift)
struct ctx {
- const char *dev;
+ struct dev_io *dev;
};
static struct ctx ctx;
@@ -508,11 +508,13 @@ static void __proto_hdr_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid,
if (proto_hdr_field_is_set(hdr, fid))
return;
- ret = device_hw_address(ctx.dev, mac, sizeof(mac));
- if (ret < 0)
- panic("Could not get device hw address\n");
+ if (dev_io_is_netdev(ctx.dev)) {
+ ret = device_hw_address(dev_io_name_get(ctx.dev), mac, sizeof(mac));
+ if (ret < 0)
+ panic("Could not get device hw address\n");
- __proto_field_set_bytes(field, mac, 6, is_default, false);
+ __proto_field_set_bytes(field, mac, 6, is_default, false);
+ }
}
void proto_hdr_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid)
@@ -536,14 +538,17 @@ static void __proto_hdr_field_set_dev_ipv4(struct proto_hdr *hdr, uint32_t fid,
if (proto_hdr_field_is_set(hdr, fid))
return;
- ret = device_address(ctx.dev, AF_INET, &ss);
- if (ret < 0) {
- fprintf(stderr, "Warning: Could not get device IPv4 address for %s\n", ctx.dev);
- return;
- }
+ if (dev_io_is_netdev(ctx.dev)) {
+ ret = device_address(dev_io_name_get(ctx.dev), AF_INET, &ss);
+ if (ret < 0) {
+ fprintf(stderr, "Warning: Could not get device IPv4 address for %s\n",
+ dev_io_name_get(ctx.dev));
+ return;
+ }
- ss4 = (struct sockaddr_in *) &ss;
- __proto_field_set_bytes(field, (uint8_t *)&ss4->sin_addr.s_addr, 4, is_default, false);
+ ss4 = (struct sockaddr_in *) &ss;
+ __proto_field_set_bytes(field, (uint8_t *)&ss4->sin_addr.s_addr, 4, is_default, false);
+ }
}
void proto_hdr_field_set_dev_ipv4(struct proto_hdr *hdr, uint32_t fid)
@@ -567,14 +572,17 @@ static void __proto_hdr_field_set_dev_ipv6(struct proto_hdr *hdr, uint32_t fid,
if (proto_hdr_field_is_set(hdr, fid))
return;
- ret = device_address(ctx.dev, AF_INET6, &ss);
- if (ret < 0) {
- fprintf(stderr, "Warning: Could not get device IPv6 address for %s\n", ctx.dev);
- return;
- }
+ if (dev_io_is_netdev(ctx.dev)) {
+ ret = device_address(dev_io_name_get(ctx.dev), AF_INET6, &ss);
+ if (ret < 0) {
+ fprintf(stderr, "Warning: Could not get device IPv6 address for %s\n",
+ dev_io_name_get(ctx.dev));
+ return;
+ }
- ss6 = (struct sockaddr_in6 *) &ss;
- __proto_field_set_bytes(field, (uint8_t *)&ss6->sin6_addr.s6_addr, 16, is_default, false);
+ ss6 = (struct sockaddr_in6 *) &ss;
+ __proto_field_set_bytes(field, (uint8_t *)&ss6->sin6_addr.s6_addr, 16, is_default, false);
+ }
}
void proto_hdr_field_set_dev_ipv6(struct proto_hdr *hdr, uint32_t fid)
@@ -658,7 +666,7 @@ void proto_field_set_default_string(struct proto_field *field, const char *str)
__proto_field_set_bytes(field, (uint8_t *)str, strlen(str) + 1, true, false);
}
-void protos_init(const char *dev)
+void protos_init(struct dev_io *dev)
{
ctx.dev = dev;
@@ -792,7 +800,7 @@ void proto_field_dyn_apply(struct proto_field *field)
field->hdr->ops->field_changed(field);
}
-const char *proto_dev_get(void)
+struct dev_io *proto_dev_get(void)
{
return ctx.dev;
}
diff --git a/trafgen_proto.h b/trafgen_proto.h
index f3d07ba..d3da963 100644
--- a/trafgen_proto.h
+++ b/trafgen_proto.h
@@ -5,6 +5,8 @@
#include <stdint.h>
#include <stdbool.h>
+#include "trafgen_dev.h"
+
enum proto_id {
PROTO_NONE = 0,
PROTO_ETH,
@@ -94,7 +96,7 @@ struct proto_field {
struct proto_hdr *hdr;
};
-extern void protos_init(const char *dev);
+extern void protos_init(struct dev_io *dev);
extern void proto_ops_register(const struct proto_ops *ops);
extern struct proto_hdr *proto_header_push(enum proto_id pid);
@@ -176,6 +178,6 @@ extern void proto_field_set_default_string(struct proto_field *field, const char
extern void proto_field_func_add(struct proto_field *field,
struct proto_field_func *func);
-extern const char *proto_dev_get(void);
+extern struct dev_io *proto_dev_get(void);
#endif /* TRAFGEN_PROTO_H */