From 78c13b71e196a107eaa4ec00bb40b062929a6a88 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Wed, 7 Jun 2017 22:24:52 +0300 Subject: 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 [tklauser: fix whitespace issues] Signed-off-by: Tobias Klauser --- trafgen.8 | 5 +- trafgen.c | 102 +++++++++------------- trafgen/Makefile | 1 + trafgen_dev.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ trafgen_dev.h | 49 +++++++++++ trafgen_l2.c | 4 + trafgen_l3.c | 8 +- trafgen_proto.c | 50 ++++++----- trafgen_proto.h | 6 +- 9 files changed, 391 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 , -d , --out , --dev -Defines the outgoing networking device such as eth0, wlan0 and others. +.SS -o , -d , --out , --dev +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 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 , + * Swiss federal institute of technology (ETH Zurich) + * Subject to the GPL, version 2. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include + +#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 +#include + +#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 #include +#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 */ -- cgit v1.2.3-54-g00ecf