On 2017-06-06 at 22:30:36 +0200, Vadim Kochan <vadi...@gmail.com> wrote: > 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.
Looks good in general, a few minor nits below. > Signed-off-by: Vadim Kochan <vadi...@gmail.com> > --- > trafgen.8 | 5 +- > trafgen.c | 102 +++++++++------------ > trafgen/Makefile | 1 + > trafgen_dev.c | 263 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > trafgen_dev.h | 49 +++++++++++ > trafgen_l2.c | 4 + > trafgen_l3.c | 8 +- > trafgen_proto.c | 50 ++++++----- > trafgen_proto.h | 6 +- > 9 files changed, 396 insertions(+), 92 deletions(-) > create mode 100644 trafgen_dev.c > create mode 100644 trafgen_dev.h > > 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..cc54f9e 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 open input device\n"); This should say "Failed to open input device" > + } > + > + ctx.dev_out = dev_io_open(ctx.device, DEV_IO_OUT); > + if (!ctx.dev_out) > + panic("Failed open output device\n"); Likewise, should say "Failed to..." > + > + 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..de6a225 > --- /dev/null > +++ b/trafgen_dev.c > @@ -0,0 +1,263 @@ > +/* > + * netsniff-ng - the packet sniffing beast > + * Copyright 2011 - 2013 Daniel Borkmann <dbor...@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 void dev_net_close(struct dev_io *dev) > +{ > +} Just omit .close from dev_net_ops, since you're checking it before access in dev_io_close. > + > +static const struct dev_io_ops dev_net_ops = { > + .open = dev_net_open, > + .write = dev_net_write, > + .close = dev_net_close, > +}; > + > +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..4fc1a4d > --- /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; Indentation is messed up. > + 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); Please space as follows: int(*open) (struct dev_io *dev, const char *name, enum dev_io_mode_t mode); Likewise for the other ops. > + 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 */ > -- > 2.12.1 > -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.