From da8fcdd7d8ce59ea334ec24cdaddcc02eb611f04 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Sat, 13 Jun 2015 15:30:46 +0300 Subject: netsniff-ng: Add cooked cmdline option. Add a --cooked option that we later on use for capturing in cooked header. For now, this only captures with a dgram packet socket, but the remaining logic will follow up. Signed-off-by: Vadim Kochan [ dbkm: split out patch ] Signed-off-by: Daniel Borkmann --- netsniff-ng.8 | 20 ++++++++++++---- netsniff-ng.c | 14 +++++++---- pcap_io.h | 75 ++++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 77 insertions(+), 32 deletions(-) diff --git a/netsniff-ng.8 b/netsniff-ng.8 index 677a78c..fb208cf 100644 --- a/netsniff-ng.8 +++ b/netsniff-ng.8 @@ -69,12 +69,14 @@ netsniff-ng can also be used to debug netlink traffic. Defines an input device. This can either be a networking device, a pcap file or stdin (\[lq]\-\[rq]). In case of a pcap file, the pcap type (\[lq]\-D\[rq] option) is determined automatically by the pcap file magic. In case of stdin, -it is assumed that the input stream is a pcap file. +it is assumed that the input stream is a pcap file. If the pcap link type is +Netlink and pcap type is default format (usec or nsec), then each packet will +be wrapped with pcap cooked header [2]. .PP .SS -o , --out Defines the output device. This can either be a networking device, a pcap file, -a folder, a trafgen(8) configuration file or stdout (\[lq]-\[rq]). In the case of a pcap -file that should not have the default pcap type (0xa1b2c3d4), the additional +a folder, a trafgen(8) configuration file or stdout (\[lq]-\[rq]). In the case of a +pcap file that should not have the default pcap type (0xa1b2c3d4), the additional option \[lq]\-T\[rq] must be provided. If a directory is given, then, instead of a single pcap file, multiple pcap files are generated with rotation based on maximum file size or a given interval (\[lq]\-F\[rq] option). Optionally, @@ -84,7 +86,10 @@ input device is a pcap file. To specify a pcap file as the output device, the file name must have \[lq].pcap\[rq] as its extension. If stdout is given as a device, then a trafgen configuration will be written to stdout if the input device is a pcap file, or a pcap file if the input device is a networking -device. +device. In case if the input device is a Netlink monitor device and pcap type +is default (usec or nsec) then each packet will be wrapped with pcap cooked +header [2] to keep Netlink family number (Kuznetzov's and netsniff-ng pcap types +already contain family number in protocol number field). .PP .SS -C , --fanout-group If multiple netsniff-ng instances are being started that all have the same packet @@ -254,6 +259,11 @@ possible addresses. Thus, to save bandwidth or for mirroring of Maxmind's databases (to bypass their traffic limit policy), different hosts or IP addresses can be placed into geoip.conf, separated by a newline. .PP +.SS -w, --cooked +Replace each frame link header with Linux "cooked" header [3] which keeps info +about link type and protocol. It allows to dump and dissect frames captured +from different link types when -i "any" was specified, for example. +.PP .SS -V, --verbose Be more verbose during startup i.e. show detailed ring setup information. .PP @@ -588,6 +598,8 @@ in the payload itself as reported here. However, the filtering for VLANs works reliable if your NIC supports it. See bpfc(8) for an example. .PP [1] http://lkml.indiana.edu/hypermail/linux/kernel/0710.3/3816.html + [2] http://www.tcpdump.org/linktypes/LINKTYPE_NETLINK.html + [3] http://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html .PP .SH LEGAL netsniff-ng is licensed under the GNU GPL version 2.0. diff --git a/netsniff-ng.c b/netsniff-ng.c index d3e9a13..0a9c620 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -69,7 +69,8 @@ struct ctx { static volatile sig_atomic_t sigint = 0, sighup = 0; static volatile bool next_dump = false; -static const char *short_options = "d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAP:Vu:g:T:DBUC:K:L:"; +static const char *short_options = + "d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAP:Vu:g:T:DBUC:K:L:w"; static const struct option long_options[] = { {"dev", required_argument, NULL, 'd'}, {"in", required_argument, NULL, 'i'}, @@ -106,6 +107,7 @@ static const struct option long_options[] = { {"ascii", no_argument, NULL, 'l'}, {"no-sock-mem", no_argument, NULL, 'A'}, {"update", no_argument, NULL, 'U'}, + {"cooked", no_argument, NULL, 'w'}, {"verbose", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, @@ -956,10 +958,9 @@ static void recv_only_or_dump(struct ctx *ctx) struct timeval start, end, diff; unsigned long frame_count = 0; - sock = pf_socket(); + sock = pf_socket_type(ctx->link_type); ifindex = device_ifindex(ctx->device_in); - size = ring_size(ctx->device_in, ctx->reserve_size); enable_kernel_bpf_jit_compiler(); @@ -1174,6 +1175,7 @@ static void __noreturn help(void) " -n|--num <0|uint> Number of packets until exit (def: 0)\n" " -P|--prefix Prefix for pcaps stored in directory\n" " -T|--magic Pcap magic number/pcap format to store, see -D\n" + " -w|--cooked Use Linux \"cooked\" header instead of link header\n" " -D|--dump-pcap-types Dump pcap types and magic numbers and quit\n" " -B|--dump-bpf Dump generated BPF assembly\n" " -r|--rand Randomize packet forwarding order (dev->dev)\n" @@ -1441,6 +1443,9 @@ int main(int argc, char **argv) update_geoip(); die(); break; + case 'w': + ctx.link_type = LINKTYPE_LINUX_SLL; + break; case 'v': version(); break; @@ -1512,7 +1517,8 @@ int main(int argc, char **argv) if (ctx.rfraw) setup_rfmon_mac80211_dev(&ctx, &ctx.device_in); - ctx.link_type = pcap_devtype_to_linktype(ctx.device_in); + if (!ctx.link_type) + ctx.link_type = pcap_dev_to_linktype(ctx.device_in); if (!ctx.device_out) { ctx.dump = 0; diff --git a/pcap_io.h b/pcap_io.h index 35faa51..e9251bf 100644 --- a/pcap_io.h +++ b/pcap_io.h @@ -150,9 +150,9 @@ static inline uint16_t tp_to_pcap_tsource(uint32_t status) return 0; } -static inline int pcap_devtype_to_linktype(const char *ifname) +static inline int pcap_devtype_to_linktype(int dev_type) { - switch (device_type(ifname)) { + switch (dev_type) { case ARPHRD_TUNNEL: case ARPHRD_TUNNEL6: case ARPHRD_LOOPBACK: @@ -160,38 +160,65 @@ static inline int pcap_devtype_to_linktype(const char *ifname) case ARPHRD_IPDDP: case ARPHRD_IPGRE: case ARPHRD_IP6GRE: - case ARPHRD_ETHER: return LINKTYPE_EN10MB; - case ARPHRD_IEEE80211_RADIOTAP: return LINKTYPE_IEEE802_11_RADIOTAP; + case ARPHRD_ETHER: + return LINKTYPE_EN10MB; + case ARPHRD_IEEE80211_RADIOTAP: + return LINKTYPE_IEEE802_11_RADIOTAP; case ARPHRD_IEEE80211_PRISM: - case ARPHRD_IEEE80211: return LINKTYPE_IEEE802_11; - case ARPHRD_NETLINK: return LINKTYPE_NETLINK; - case ARPHRD_EETHER: return LINKTYPE_EN3MB; - case ARPHRD_AX25: return LINKTYPE_AX25; - case ARPHRD_CHAOS: return LINKTYPE_CHAOS; - case ARPHRD_PRONET: return LINKTYPE_PRONET; + case ARPHRD_IEEE80211: + return LINKTYPE_IEEE802_11; + case ARPHRD_NETLINK: + return LINKTYPE_NETLINK; + case ARPHRD_EETHER: + return LINKTYPE_EN3MB; + case ARPHRD_AX25: + return LINKTYPE_AX25; + case ARPHRD_CHAOS: + return LINKTYPE_CHAOS; + case ARPHRD_PRONET: + return LINKTYPE_PRONET; case ARPHRD_IEEE802_TR: - case ARPHRD_IEEE802: return LINKTYPE_IEEE802; - case ARPHRD_INFINIBAND: return LINKTYPE_INFINIBAND; - case ARPHRD_ATM: return LINKTYPE_ATM_CLIP; - case ARPHRD_DLCI: return LINKTYPE_FRELAY; - case ARPHRD_ARCNET: return LINKTYPE_ARCNET_LINUX; + case ARPHRD_IEEE802: + return LINKTYPE_IEEE802; + case ARPHRD_INFINIBAND: + return LINKTYPE_INFINIBAND; + case ARPHRD_ATM: + return LINKTYPE_ATM_CLIP; + case ARPHRD_DLCI: + return LINKTYPE_FRELAY; + case ARPHRD_ARCNET: + return LINKTYPE_ARCNET_LINUX; case ARPHRD_CSLIP: case ARPHRD_CSLIP6: case ARPHRD_SLIP6: - case ARPHRD_SLIP: return LINKTYPE_SLIP; - case ARPHRD_PPP: return LINKTYPE_PPP; - case ARPHRD_CAN: return LINKTYPE_CAN20B; - case ARPHRD_ECONET: return LINKTYPE_ECONET; + case ARPHRD_SLIP: + return LINKTYPE_SLIP; + case ARPHRD_PPP: + return LINKTYPE_PPP; + case ARPHRD_CAN: + return LINKTYPE_CAN20B; + case ARPHRD_ECONET: + return LINKTYPE_ECONET; case ARPHRD_RAWHDLC: - case ARPHRD_CISCO: return LINKTYPE_C_HDLC; - case ARPHRD_FDDI: return LINKTYPE_FDDI; + case ARPHRD_CISCO: + return LINKTYPE_C_HDLC; + case ARPHRD_FDDI: + return LINKTYPE_FDDI; case ARPHRD_IEEE802154_MONITOR: - case ARPHRD_IEEE802154: return LINKTYPE_IEEE802_15_4_LINUX; - case ARPHRD_IRDA: return LINKTYPE_LINUX_IRDA; - default: return LINKTYPE_NULL; + case ARPHRD_IEEE802154: + return LINKTYPE_IEEE802_15_4_LINUX; + case ARPHRD_IRDA: + return LINKTYPE_LINUX_IRDA; + default: + return LINKTYPE_NULL; } } +static inline int pcap_dev_to_linktype(const char *ifname) +{ + return pcap_devtype_to_linktype(device_type(ifname)); +} + static inline void pcap_check_magic(uint32_t magic) { switch (magic) { -- cgit v1.2.3-54-g00ecf