diff options
-rw-r--r-- | trafgen.8 | 3 | ||||
-rw-r--r-- | trafgen.c | 25 | ||||
-rw-r--r-- | trafgen_dev.c | 35 | ||||
-rw-r--r-- | trafgen_dev.h | 4 |
4 files changed, 48 insertions, 19 deletions
@@ -98,7 +98,8 @@ a bigger memory footprint for the ring buffer. In case the output networking device is a wireless device, it is possible with trafgen to turn this into monitor mode and create a mon<X> device that trafgen will be transmitting on instead of wlan<X>, for instance. This enables trafgen -to inject raw 802.11 frames. +to inject raw 802.11 frames. In case if the output is a pcap file the link type +is set to 127 (ieee80211 radio tap). .PP .SS -s <ipv4>, --smoke-test <ipv4> In case this option is enabled, trafgen will perform a smoke test. In other @@ -45,7 +45,6 @@ #include "lockme.h" #include "privs.h" #include "proc.h" -#include "mac80211.h" #include "ioops.h" #include "irq.h" #include "config.h" @@ -85,7 +84,7 @@ struct ctx { unsigned long num; unsigned int cpus; uid_t uid; gid_t gid; - char *device, *device_trans, *rhost; + char *device, *rhost; struct sockaddr_in dest; struct shaper sh; char *packet_str; @@ -1023,7 +1022,7 @@ static unsigned int generate_srand_seed(void) static void on_panic_del_rfmon(void *arg) { - leave_rfmon_mac80211(arg); + dev_io_close(arg); } int main(int argc, char **argv) @@ -1283,15 +1282,6 @@ int main(int argc, char **argv) set_system_socket_memory(vals, array_size(vals)); xlockme(); - if (ctx.rfraw) { - ctx.device_trans = xstrdup(ctx.device); - xfree(ctx.device); - - enter_rfmon_mac80211(ctx.device_trans, &ctx.device); - panic_handler_add(on_panic_del_rfmon, ctx.device); - sleep(0); - } - if (ctx.pcap_in) { ctx.dev_in = dev_io_open(ctx.pcap_in, DEV_IO_IN); if (!ctx.dev_in) @@ -1302,6 +1292,13 @@ int main(int argc, char **argv) if (!ctx.dev_out) panic("Failed to open output device\n"); + if (ctx.rfraw) { + if (dev_io_link_type_set(ctx.dev_out, LINKTYPE_IEEE802_11_RADIOTAP)) + panic("Failed to setup rfraw device\n"); + + panic_handler_add(on_panic_del_rfmon, ctx.dev_out); + } + protos_init(ctx.dev_out); if (shaper_is_set(&ctx.sh) || (ctx.dev_in && dev_io_is_pcap(ctx.dev_in)) @@ -1357,9 +1354,6 @@ int main(int argc, char **argv) die(); } - if (ctx.rfraw) - leave_rfmon_mac80211(ctx.device); - if (set_sock_mem) reset_system_socket_memory(vals, array_size(vals)); @@ -1393,7 +1387,6 @@ thread_out: argv_free(cpp_argv); free(ctx.device); - free(ctx.device_trans); free(ctx.rhost); free(confname); free(ctx.packet_str); diff --git a/trafgen_dev.c b/trafgen_dev.c index 80e7481..d7f1cd5 100644 --- a/trafgen_dev.c +++ b/trafgen_dev.c @@ -16,6 +16,8 @@ #include "xmalloc.h" #include "pcap_io.h" #include "built_in.h" +#include "mac80211.h" +#include "linktype.h" #include "trafgen_dev.h" static int dev_pcap_open(struct dev_io *dev, const char *name, enum dev_io_mode_t mode) @@ -164,9 +166,34 @@ static int dev_net_write(struct dev_io *dev, const uint8_t *buf, size_t len) return sendto(dev->fd, buf, len, 0, (struct sockaddr *) &saddr, sizeof(saddr)); } +static int dev_net_set_link_type(struct dev_io *dev, int link_type) +{ + if (link_type != LINKTYPE_IEEE802_11 && link_type != LINKTYPE_IEEE802_11_RADIOTAP) + return 0; + + dev->trans = xstrdup(dev->name); + xfree(dev->name); + + enter_rfmon_mac80211(dev->trans, &dev->name); + dev->ifindex = __device_ifindex(dev->name); + dev->dev_type = device_type(dev->name); + + return 0; +} + +static void dev_net_close(struct dev_io *dev) +{ + if (dev->link_type == LINKTYPE_IEEE802_11 || dev->link_type == LINKTYPE_IEEE802_11_RADIOTAP) + leave_rfmon_mac80211(dev->name); + + free(dev->trans); +} + static const struct dev_io_ops dev_net_ops = { .open = dev_net_open, .write = dev_net_write, + .set_link_type = dev_net_set_link_type, + .close = dev_net_close, }; struct dev_io *dev_io_open(const char *name, enum dev_io_mode_t mode) @@ -232,9 +259,15 @@ 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) +int dev_io_link_type_set(struct dev_io *dev, int link_type) { + if (dev->ops->set_link_type) { + if (dev->ops->set_link_type(dev, link_type)) + return -1; + } + dev->link_type = link_type; + return 0; } int dev_io_ifindex_get(struct dev_io *dev) diff --git a/trafgen_dev.h b/trafgen_dev.h index 720c630..686a577 100644 --- a/trafgen_dev.h +++ b/trafgen_dev.h @@ -16,6 +16,7 @@ struct dev_io_ops; struct dev_io { int fd; char *name; + char *trans; int ifindex; int dev_type; uint32_t link_type; @@ -31,6 +32,7 @@ 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); + int(*set_link_type) (struct dev_io *dev, int link_type); void(*close) (struct dev_io *dev); }; @@ -41,7 +43,7 @@ extern int dev_io_read(struct dev_io *dev, uint8_t *buf, size_t len, 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 int 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); |