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.

Reply via email to