On Sat, Jun 20, 2015 at 01:12:06AM +0300, Vadim Kochan wrote: > On Fri, Jun 19, 2015 at 11:59:32PM +0200, Daniel Borkmann wrote: > > On 06/19/2015 11:37 PM, Vadim Kochan wrote: > > ... > > >Never applied patches from emails, I tried to do in mutt by saving as > > >attachments or mbox, I even cut till 'diff' line but with no luck to > > >apply this. May be you can suggest some work flow with mutt for > > >patches via email ? > > > > Ok, so here's both as an attachment, also your dissector on top, > > which works fine for me. > > > > (I usually save the whole source and git am it.) > > > From 045e9395ca9c2971ab7f7a886f5d6b4cf679c7fd Mon Sep 17 00:00:00 2001 > > Message-Id: > > <045e9395ca9c2971ab7f7a886f5d6b4cf679c7fd.1434749532.git.dan...@iogearbox.net> > > From: Daniel Borkmann <dan...@iogearbox.net> > > Date: Fri, 19 Jun 2015 00:30:31 +0200 > > Subject: [PATCH 1/2] pcap_io: add cooked mode support > > > > Originally submitted by Vadim in a different form, he wrote: > > > > Use Linux "cooked" header for Netlink interface automatically or > > as replacement of L2 header if "--cooked" option is specified: > > > > http://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html > > > > 'Cooked headers' makes sense to use for default or nsec pcap > > types which does not contain protocol info. > > > > Added new LINKTYPE_LINUX_SLL which indicates pcap file with > > Linux "cooked" header as L2 layer header. This pcap file is > > compatible with Wireshark's "cooked" header & vice-versa. > > > > Signed-off-by: Vadim Kochan <vadi...@gmail.com> > > Signed-off-by: Daniel Borkmann <dan...@iogearbox.net> > > --- > > netsniff-ng.c | 17 ++++++ > > pcap_io.h | 192 > > +++++++++++++++++++++++++++++++++++++++++++++++----------- > > 2 files changed, 172 insertions(+), 37 deletions(-) > > > > diff --git a/netsniff-ng.c b/netsniff-ng.c > > index 0a9c620..e593b9d 100644 > > --- a/netsniff-ng.c > > +++ b/netsniff-ng.c > > @@ -1519,6 +1519,23 @@ int main(int argc, char **argv) > > > > if (!ctx.link_type) > > ctx.link_type = pcap_dev_to_linktype(ctx.device_in); > > + if (link_has_sll_hdr(ctx.link_type)) { > > + switch (ctx.magic) { > > + case ORIGINAL_TCPDUMP_MAGIC: > > + ctx.magic = ORIGINAL_TCPDUMP_MAGIC_LL; > > + break; > > + case NSEC_TCPDUMP_MAGIC: > > + ctx.magic = NSEC_TCPDUMP_MAGIC_LL; > > + break; > > + case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC): > > + ctx.magic = > > ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL); > > + break; > > + case ___constant_swab32(NSEC_TCPDUMP_MAGIC): > > + ctx.magic = > > ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL); > > + break; > > + } > > + } > > + > > > > if (!ctx.device_out) { > > ctx.dump = 0; > > diff --git a/pcap_io.h b/pcap_io.h > > index 497e453..5beccf9 100644 > > --- a/pcap_io.h > > +++ b/pcap_io.h > > @@ -27,6 +27,8 @@ > > #define TCPDUMP_MAGIC 0xa1b2c3d4 > > #define ORIGINAL_TCPDUMP_MAGIC TCPDUMP_MAGIC > > #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d > > +#define ORIGINAL_TCPDUMP_MAGIC_LL 0xb1b2c3d4 /* Internal > > dummy just for mapping */ > > +#define NSEC_TCPDUMP_MAGIC_LL 0xb1b23c4d /* > > Internal dummy just for mapping */ > > #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34 > > #define BORKMANN_TCPDUMP_MAGIC 0xa1e2cb12 > > > > @@ -78,6 +80,20 @@ struct pcap_pkthdr_ns { > > uint32_t len; > > }; > > > > +struct pcap_pkthdr_ll { > > + struct pcap_timeval ts; > > + uint32_t caplen; > > + uint32_t len; > > + struct pcap_ll ll; > > +}; > > + > > +struct pcap_pkthdr_ns_ll { > > + struct pcap_timeval_ns ts; > > + uint32_t caplen; > > + uint32_t len; > > + struct pcap_ll ll; > > +}; > > + > > struct pcap_pkthdr_kuz { > > struct pcap_timeval ts; > > uint32_t caplen; > > @@ -99,21 +115,27 @@ struct pcap_pkthdr_bkm { > > }; > > > > typedef union { > > - struct pcap_pkthdr ppo; > > - struct pcap_pkthdr_ns ppn; > > - struct pcap_pkthdr_kuz ppk; > > - struct pcap_pkthdr_bkm ppb; > > - uint8_t raw; > > + struct pcap_pkthdr ppo; > > + struct pcap_pkthdr_ns ppn; > > + struct pcap_pkthdr_ll ppo_ll; > > + struct pcap_pkthdr_ns_ll ppn_ll; > > + struct pcap_pkthdr_kuz ppk; > > + struct pcap_pkthdr_bkm ppb; > > + uint8_t raw; > > } pcap_pkthdr_t; > > > > enum pcap_type { > > DEFAULT = ORIGINAL_TCPDUMP_MAGIC, > > NSEC = NSEC_TCPDUMP_MAGIC, > > + DEFAULT_LL = ORIGINAL_TCPDUMP_MAGIC_LL, > > + NSEC_LL = NSEC_TCPDUMP_MAGIC_LL, > > KUZNETZOV = KUZNETZOV_TCPDUMP_MAGIC, > > BORKMANN = BORKMANN_TCPDUMP_MAGIC, > > > > DEFAULT_SWAPPED = ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC), > > NSEC_SWAPPED = ___constant_swab32(NSEC_TCPDUMP_MAGIC), > > + DEFAULT_LL_SWAPPED = ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL), > > + NSEC_LL_SWAPPED = ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL), > > KUZNETZOV_SWAPPED = ___constant_swab32(KUZNETZOV_TCPDUMP_MAGIC), > > BORKMANN_SWAPPED = ___constant_swab32(BORKMANN_TCPDUMP_MAGIC), > > }; > > @@ -244,6 +266,19 @@ static inline int pcap_devtype_to_linktype(int > > dev_type) > > } > > } > > > > +static inline bool link_has_sll_hdr(uint32_t link_type) > > +{ > > + switch (link_type) { > > + case LINKTYPE_NETLINK: > > + case LINKTYPE_LINUX_SLL: > > + case ___constant_swab32(LINKTYPE_NETLINK): > > + case ___constant_swab32(LINKTYPE_LINUX_SLL): > > + return true; > > + default: > > + return false; > > + } > > +} > > + > > static inline int pcap_dev_to_linktype(const char *ifname) > > { > > return pcap_devtype_to_linktype(device_type(ifname)); > > @@ -287,20 +322,24 @@ static inline bool pcap_magic_is_swapped(uint32_t > > magic) > > static inline u32 pcap_get_length(pcap_pkthdr_t *phdr, enum pcap_type type) > > { > > switch (type) { > > -#define CASE_RET_CAPLEN(what, member, swap) \ > > +#define CASE_RET_CAPLEN(what, member, swap, extra) \ > > case (what): \ > > return (swap ? ___constant_swab32(phdr->member.caplen) : \ > > - phdr->member.caplen) > > - > > - CASE_RET_CAPLEN(DEFAULT, ppo, 0); > > - CASE_RET_CAPLEN(NSEC, ppn, 0); > > - CASE_RET_CAPLEN(KUZNETZOV, ppk, 0); > > - CASE_RET_CAPLEN(BORKMANN, ppb, 0); > > - > > - CASE_RET_CAPLEN(DEFAULT_SWAPPED, ppo, 1); > > - CASE_RET_CAPLEN(NSEC_SWAPPED, ppn, 1); > > - CASE_RET_CAPLEN(KUZNETZOV_SWAPPED, ppk, 1); > > - CASE_RET_CAPLEN(BORKMANN_SWAPPED, ppb, 1); > > + phdr->member.caplen) - extra > > + > > + CASE_RET_CAPLEN(DEFAULT, ppo, 0, 0); > > + CASE_RET_CAPLEN(NSEC, ppn, 0, 0); > > + CASE_RET_CAPLEN(DEFAULT_LL, ppo_ll, 0, sizeof(struct pcap_ll)); > > + CASE_RET_CAPLEN(NSEC_LL, ppn_ll, 0, sizeof(struct pcap_ll)); > > + CASE_RET_CAPLEN(KUZNETZOV, ppk, 0, 0); > > + CASE_RET_CAPLEN(BORKMANN, ppb, 0, 0); > > + > > + CASE_RET_CAPLEN(DEFAULT_SWAPPED, ppo, 1, 0); > > + CASE_RET_CAPLEN(NSEC_SWAPPED, ppn, 1, 0); > > + CASE_RET_CAPLEN(DEFAULT_LL_SWAPPED, ppo_ll, 1, sizeof(struct pcap_ll)); > > + CASE_RET_CAPLEN(NSEC_LL_SWAPPED, ppn_ll, 1, sizeof(struct pcap_ll)); > > + CASE_RET_CAPLEN(KUZNETZOV_SWAPPED, ppk, 1, 0); > > + CASE_RET_CAPLEN(BORKMANN_SWAPPED, ppb, 1, 0); > > > > default: > > bug(); > > @@ -317,11 +356,15 @@ static inline void pcap_set_length(pcap_pkthdr_t > > *phdr, enum pcap_type type, u32 > > > > CASE_SET_CAPLEN(DEFAULT, ppo, 0); > > CASE_SET_CAPLEN(NSEC, ppn, 0); > > + CASE_SET_CAPLEN(DEFAULT_LL, ppo_ll, 0); > > + CASE_SET_CAPLEN(NSEC_LL, ppn_ll, 0); > > CASE_SET_CAPLEN(KUZNETZOV, ppk, 0); > > CASE_SET_CAPLEN(BORKMANN, ppb, 0); > > > > CASE_SET_CAPLEN(DEFAULT_SWAPPED, ppo, 1); > > CASE_SET_CAPLEN(NSEC_SWAPPED, ppn, 1); > > + CASE_SET_CAPLEN(DEFAULT_LL_SWAPPED, ppo_ll, 1); > > + CASE_SET_CAPLEN(NSEC_LL_SWAPPED, ppn_ll, 1); > > CASE_SET_CAPLEN(KUZNETZOV_SWAPPED, ppk, 1); > > CASE_SET_CAPLEN(BORKMANN_SWAPPED, ppb, 1); > > > > @@ -339,11 +382,15 @@ static inline u32 pcap_get_hdr_length(pcap_pkthdr_t > > *phdr, enum pcap_type type) > > > > CASE_RET_HDRLEN(DEFAULT, ppo); > > CASE_RET_HDRLEN(NSEC, ppn); > > + CASE_RET_HDRLEN(DEFAULT_LL, ppo_ll); > > + CASE_RET_HDRLEN(NSEC_LL, ppn_ll); > > CASE_RET_HDRLEN(KUZNETZOV, ppk); > > CASE_RET_HDRLEN(BORKMANN, ppb); > > > > CASE_RET_HDRLEN(DEFAULT_SWAPPED, ppo); > > CASE_RET_HDRLEN(NSEC_SWAPPED, ppn); > > + CASE_RET_HDRLEN(DEFAULT_LL_SWAPPED, ppo_ll); > > + CASE_RET_HDRLEN(NSEC_LL_SWAPPED, ppn_ll); > > CASE_RET_HDRLEN(KUZNETZOV_SWAPPED, ppk); > > CASE_RET_HDRLEN(BORKMANN_SWAPPED, ppb); > > > > @@ -354,25 +401,7 @@ static inline u32 pcap_get_hdr_length(pcap_pkthdr_t > > *phdr, enum pcap_type type) > > > > static inline u32 pcap_get_total_length(pcap_pkthdr_t *phdr, enum > > pcap_type type) > > { > > - switch (type) { > > -#define CASE_RET_TOTLEN(what, member, swap) \ > > - case (what): \ > > - return ((swap ? ___constant_swab32(phdr->member.caplen) : \ > > - phdr->member.caplen) + sizeof(phdr->member)) > > - > > - CASE_RET_TOTLEN(DEFAULT, ppo, 0); > > - CASE_RET_TOTLEN(NSEC, ppn, 0); > > - CASE_RET_TOTLEN(KUZNETZOV, ppk, 0); > > - CASE_RET_TOTLEN(BORKMANN, ppb, 0); > > - > > - CASE_RET_TOTLEN(DEFAULT_SWAPPED, ppo, 1); > > - CASE_RET_TOTLEN(NSEC_SWAPPED, ppn, 1); > > - CASE_RET_TOTLEN(KUZNETZOV_SWAPPED, ppk, 1); > > - CASE_RET_TOTLEN(BORKMANN_SWAPPED, ppb, 1); > > - > > - default: > > - bug(); > > - } > > + return pcap_get_hdr_length(phdr, type) + pcap_get_length(phdr, type); > > } > > > > static inline void > > @@ -383,31 +412,55 @@ __tpacket_hdr_to_pcap_pkthdr(uint32_t sec, uint32_t > > nsec, uint32_t snaplen, > > { > > switch (type) { > > case DEFAULT: > > + case DEFAULT_LL: > > phdr->ppo.ts.tv_sec = sec; > > phdr->ppo.ts.tv_usec = nsec / 1000; > > phdr->ppo.caplen = snaplen; > > phdr->ppo.len = len; > > + if (type == DEFAULT_LL) { > > + phdr->ppo.caplen += sizeof(struct pcap_ll); > > + phdr->ppo.len += sizeof(struct pcap_ll); > > + sockaddr_to_ll(sll, &phdr->ppo_ll.ll); > > + } > > break; > > > > case DEFAULT_SWAPPED: > > + case DEFAULT_LL_SWAPPED: > > phdr->ppo.ts.tv_sec = ___constant_swab32(sec); > > phdr->ppo.ts.tv_usec = ___constant_swab32(nsec / 1000); > > phdr->ppo.caplen = ___constant_swab32(snaplen); > > phdr->ppo.len = ___constant_swab32(len); > > + if (type == DEFAULT_LL_SWAPPED) { > > + phdr->ppo.caplen = ___constant_swab32(snaplen + > > sizeof(struct pcap_ll)); > > + phdr->ppo.len = ___constant_swab32(len + sizeof(struct > > pcap_ll)); > > + sockaddr_to_ll(sll, &phdr->ppo_ll.ll); > > + } > > break; > > > > case NSEC: > > + case NSEC_LL: > > phdr->ppn.ts.tv_sec = sec; > > phdr->ppn.ts.tv_nsec = nsec; > > phdr->ppn.caplen = snaplen; > > phdr->ppn.len = len; > > + if (type == NSEC_LL) { > > + phdr->ppn.caplen += sizeof(struct pcap_ll); > > + phdr->ppn.len += sizeof(struct pcap_ll); > > + sockaddr_to_ll(sll, &phdr->ppn_ll.ll); > > + } > > break; > > > > case NSEC_SWAPPED: > > + case NSEC_LL_SWAPPED: > > phdr->ppn.ts.tv_sec = ___constant_swab32(sec); > > phdr->ppn.ts.tv_nsec = ___constant_swab32(nsec); > > phdr->ppn.caplen = ___constant_swab32(snaplen); > > phdr->ppn.len = ___constant_swab32(len); > > + if (type == NSEC_LL_SWAPPED) { > > + phdr->ppn.caplen = ___constant_swab32(snaplen + > > sizeof(struct pcap_ll)); > > + phdr->ppn.len = ___constant_swab32(len + sizeof(struct > > pcap_ll)); > > + sockaddr_to_ll(sll, &phdr->ppn_ll.ll); > > + } > > break; > > > > case KUZNETZOV: > > @@ -492,31 +545,59 @@ static inline void > > pcap_pkthdr_to_tpacket_hdr(pcap_pkthdr_t *phdr, > > { > > switch (type) { > > case DEFAULT: > > + case DEFAULT_LL: > > thdr->tp_sec = phdr->ppo.ts.tv_sec; > > thdr->tp_nsec = phdr->ppo.ts.tv_usec * 1000; > > thdr->tp_snaplen = phdr->ppo.caplen; > > thdr->tp_len = phdr->ppo.len; > > + if (type == DEFAULT_LL) { > > + thdr->tp_snaplen -= sizeof(struct pcap_ll); > > + thdr->tp_len -= sizeof(struct pcap_ll); > > + if (sll) > > + ll_to_sockaddr(&phdr->ppo_ll.ll, sll); > > + } > > break; > > > > case DEFAULT_SWAPPED: > > + case DEFAULT_LL_SWAPPED: > > thdr->tp_sec = ___constant_swab32(phdr->ppo.ts.tv_sec); > > thdr->tp_nsec = ___constant_swab32(phdr->ppo.ts.tv_usec) * 1000; > > thdr->tp_snaplen = ___constant_swab32(phdr->ppo.caplen); > > thdr->tp_len = ___constant_swab32(phdr->ppo.len); > > + if (type == DEFAULT_LL_SWAPPED) { > > + thdr->tp_snaplen -= sizeof(struct pcap_ll); > > + thdr->tp_len -= sizeof(struct pcap_ll); > > + if (sll) > > + ll_to_sockaddr(&phdr->ppo_ll.ll, sll); > > + } > > break; > > > > case NSEC: > > + case NSEC_LL: > > thdr->tp_sec = phdr->ppn.ts.tv_sec; > > thdr->tp_nsec = phdr->ppn.ts.tv_nsec; > > thdr->tp_snaplen = phdr->ppn.caplen; > > thdr->tp_len = phdr->ppn.len; > > + if (type == NSEC_LL) { > > + thdr->tp_snaplen -= sizeof(struct pcap_ll); > > + thdr->tp_len -= sizeof(struct pcap_ll); > > + if (sll) > > + ll_to_sockaddr(&phdr->ppn_ll.ll, sll); > > + } > > break; > > > > case NSEC_SWAPPED: > > + case NSEC_LL_SWAPPED: > > thdr->tp_sec = ___constant_swab32(phdr->ppn.ts.tv_sec); > > thdr->tp_nsec = ___constant_swab32(phdr->ppn.ts.tv_nsec); > > thdr->tp_snaplen = ___constant_swab32(phdr->ppn.caplen); > > thdr->tp_len = ___constant_swab32(phdr->ppn.len); > > + if (type == NSEC_LL_SWAPPED) { > > + thdr->tp_snaplen -= sizeof(struct pcap_ll); > > + thdr->tp_len -= sizeof(struct pcap_ll); > > + if (sll) > > + ll_to_sockaddr(&phdr->ppn_ll.ll, sll); > > + } > > break; > > > > case KUZNETZOV: > > @@ -682,6 +763,24 @@ static inline void pcap_prepare_header(struct > > pcap_filehdr *hdr, uint32_t magic, > > { > > bool swapped = pcap_magic_is_swapped(magic); > > > > + /* As *_LL types are just internal, we need to remap pcap > > + * magics to actually valid types. > > + */ > > + switch (magic) { > > + case ORIGINAL_TCPDUMP_MAGIC_LL: > > + magic = ORIGINAL_TCPDUMP_MAGIC; > > + break; > > + case NSEC_TCPDUMP_MAGIC_LL: > > + magic = NSEC_TCPDUMP_MAGIC; > > + break; > > + case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL): > > + magic = ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC); > > + break; > > + case ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL): > > + magic = ___constant_swab32(NSEC_TCPDUMP_MAGIC); > > + break; > > + } > > + > > hdr->magic = magic; > > hdr->version_major = swapped ? ___constant_swab16(PCAP_VERSION_MAJOR) : > > PCAP_VERSION_MAJOR; > > hdr->version_minor = swapped ? ___constant_swab16(PCAP_VERSION_MINOR) : > > PCAP_VERSION_MINOR; > > @@ -716,9 +815,10 @@ static const bool > > pcap_supported_linktypes[LINKTYPE_MAX] __maybe_unused = { > > [LINKTYPE_IEEE802_15_4_LINUX] = true, > > [LINKTYPE_INFINIBAND] = true, > > [LINKTYPE_NETLINK] = true, > > + [LINKTYPE_LINUX_SLL] = true, > > }; > > > > -static inline void pcap_validate_header(const struct pcap_filehdr *hdr) > > +static inline void pcap_validate_header(struct pcap_filehdr *hdr) > > { > > bool good = false; > > uint32_t linktype; > > @@ -737,6 +837,24 @@ static inline void pcap_validate_header(const struct > > pcap_filehdr *hdr) > > if (unlikely(hdr->version_minor != PCAP_VERSION_MINOR) && > > ___constant_swab16(hdr->version_minor) != > > PCAP_VERSION_MINOR) > > panic("This file has an invalid pcap minor version (must be > > %d)\n", PCAP_VERSION_MINOR); > > + > > + /* Remap to internal *_LL types in case of LINKTYPE_LINUX_SLL. */ > > + if (linktype == LINKTYPE_LINUX_SLL) { > > + switch (hdr->magic) { > > + case ORIGINAL_TCPDUMP_MAGIC: > > + hdr->magic = ORIGINAL_TCPDUMP_MAGIC_LL; > > + break; > > + case NSEC_TCPDUMP_MAGIC: > > + hdr->magic = NSEC_TCPDUMP_MAGIC_LL; > > + break; > > + case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC): > > + hdr->magic = > > ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL); > > + break; > > + case ___constant_swab32(NSEC_TCPDUMP_MAGIC): > > + hdr->magic = ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL); > > + break; > > + } > > + } > > } > > > > static int pcap_generic_pull_fhdr(int fd, uint32_t *magic, > > -- > > 1.9.3 > > > > > From 42afc1ba23f232de744a8212e15f8bfbb72bee03 Mon Sep 17 00:00:00 2001 > > Message-Id: > > <42afc1ba23f232de744a8212e15f8bfbb72bee03.1434749532.git.dan...@iogearbox.net> > > In-Reply-To: > > <045e9395ca9c2971ab7f7a886f5d6b4cf679c7fd.1434749532.git.dan...@iogearbox.net> > > References: > > <045e9395ca9c2971ab7f7a886f5d6b4cf679c7fd.1434749532.git.dan...@iogearbox.net> > > From: Vadim Kochan <vadi...@gmail.com> > > Date: Tue, 16 Jun 2015 04:10:19 +0300 > > Subject: [PATCH 2/2] netsniff-ng: Add dissector for Linux "cooked" packets > > > > Added dissector_sll.c which uses sockaddr_ll to lookup & print > > higher L3 layer protocol. > > > > This dissector is mapped by LINKTYPE_LINUX_SLL link type. > > > > Sample output of dissected Netlink & Ethernet packets. > > Truncated manually some longer lines by "...": > > > > > nlmon0 20 1434193547s.717131169ns #6 > > [ Linux "cooked" Pkt Type 4 (outgoing), If Type 824 (netlink), Addr Len 0, > > Src (), Proto 0x0 ] > > [ NLMSG Family 0 (routing), Len 20, Type 0x0003 (DONE)... > > > > > wlp3s0 52 1434194181s.436224709ns #9 > > [ Linux "cooked" Pkt Type 4 (outgoing), If Type 1 (ether), Addr Len 6, Src > > (XX:XX:XX:XX:XX:XX), Proto 0x800 ] > > [ IPv4 Addr (XXX.XXX.XXX.XXX => 212.42.76.253), Proto (6), TTL (64), TOS > > (0), ... > > ), CSum (0x1ef5) is ok ] > > [ Geo (local => Ukraine) ] > > [ TCP Port (45849 => 443 (https)), SN (0x1744209), AN (0x46ca9611), > > DataOff (8) ... > > [ Chr .....w.Rj).. ] > > [ Hex XX XX XX XX XX XX XX XX XX XX XX XX ] > > > > Signed-off-by: Vadim Kochan <vadi...@gmail.com> > > Signed-off-by: Daniel Borkmann <dan...@iogearbox.net> > > --- > > dissector.c | 12 +++++- > > dissector.h | 2 +- > > dissector_sll.c | 113 > > +++++++++++++++++++++++++++++++++++++++++++++++++++ > > dissector_sll.h | 18 ++++++++ > > netsniff-ng.c | 10 ++--- > > netsniff-ng/Makefile | 1 + > > pkt_buff.h | 2 +- > > proto_nlmsg.c | 4 +- > > 8 files changed, 151 insertions(+), 11 deletions(-) > > create mode 100644 dissector_sll.c > > create mode 100644 dissector_sll.h > > > > diff --git a/dissector.c b/dissector.c > > index 4cad588..6aa253d 100644 > > --- a/dissector.c > > +++ b/dissector.c > > @@ -14,6 +14,7 @@ > > #include "proto.h" > > #include "dissector.h" > > #include "dissector_eth.h" > > +#include "dissector_sll.h" > > #include "dissector_80211.h" > > #include "dissector_netlink.h" > > #include "linktype.h" > > @@ -61,7 +62,7 @@ static void dissector_main(struct pkt_buff *pkt, struct > > protocol *start, > > } > > > > void dissector_entry_point(uint8_t *packet, size_t len, int linktype, int > > mode, > > - uint16_t proto) > > + struct sockaddr_ll *sll) > > { > > struct protocol *proto_start, *proto_end; > > struct pkt_buff *pkt; > > @@ -71,7 +72,7 @@ void dissector_entry_point(uint8_t *packet, size_t len, > > int linktype, int mode, > > > > pkt = pkt_alloc(packet, len); > > pkt->link_type = linktype; > > - pkt->proto = proto; > > + pkt->sll = sll; > > > > switch (linktype) { > > case LINKTYPE_EN10MB: > > @@ -91,6 +92,11 @@ void dissector_entry_point(uint8_t *packet, size_t len, > > int linktype, int mode, > > proto_start = dissector_get_netlink_entry_point(); > > proto_end = dissector_get_netlink_exit_point(); > > break; > > + case LINKTYPE_LINUX_SLL: > > + case ___constant_swab32(LINKTYPE_LINUX_SLL): > > + proto_start = dissector_get_sll_entry_point(); > > + proto_end = dissector_get_sll_exit_point(); > > + break; > > default: > > proto_start = &none_ops; > > proto_end = NULL; > > @@ -120,6 +126,7 @@ void dissector_init_all(int fnttype) > > dissector_init_ethernet(fnttype); > > dissector_init_ieee80211(fnttype); > > dissector_init_netlink(fnttype); > > + dissector_init_sll(fnttype); > > } > > > > void dissector_cleanup_all(void) > > @@ -127,4 +134,5 @@ void dissector_cleanup_all(void) > > dissector_cleanup_ethernet(); > > dissector_cleanup_ieee80211(); > > dissector_cleanup_netlink(); > > + dissector_cleanup_sll(); > > } > > diff --git a/dissector.h b/dissector.h > > index a99442e..5580110 100644 > > --- a/dissector.h > > +++ b/dissector.h > > @@ -105,7 +105,7 @@ static inline void show_frame_hdr(uint8_t *packet, > > size_t len, int linktype, > > > > extern void dissector_init_all(int fnttype); > > extern void dissector_entry_point(uint8_t *packet, size_t len, int > > linktype, > > - int mode, uint16_t proto); > > + int mode, struct sockaddr_ll *sll); > > extern void dissector_cleanup_all(void); > > extern int dissector_set_print_type(void *ptr, int type); > > > > diff --git a/dissector_sll.c b/dissector_sll.c > > new file mode 100644 > > index 0000000..e2e5bfa > > --- /dev/null > > +++ b/dissector_sll.c > > @@ -0,0 +1,113 @@ > > +/* > > + * netsniff-ng - the packet sniffing beast > > + * Subject to the GPL, version 2. > > + */ > > + > > +#include "oui.h" > > +#include "protos.h" > > +#include "pcap_io.h" > > +#include "pkt_buff.h" > > +#include "dissector.h" > > +#include "dissector_sll.h" > > +#include "dissector_eth.h" > > + > > +static char *pkt_type2str(uint8_t pkttype) > > +{ > > + switch (pkttype) { > > + case PACKET_HOST: > > + return "host"; > > + case PACKET_BROADCAST: > > + return "broadcast"; > > + case PACKET_MULTICAST: > > + return "multicast"; > > + case PACKET_OTHERHOST: > > + return "other host"; > > + case PACKET_OUTGOING: > > + return "outgoing"; > > + case PACKET_USER: > > + return "user"; > > + case PACKET_KERNEL: > > + return "kernel"; > > + } > > + > > + return "Unknown"; > > +} > > + > > +static void sll_print_full(struct pkt_buff *pkt) > > +{ > > + struct sockaddr_ll *sll = pkt->sll; > > + char addr_str[40] = {}; > > + > > + if (!pkt || !sll) > > + return; > > + > > + tprintf(" [ Linux \"cooked\""); > > + tprintf(" Pkt Type %d (%s)", sll->sll_pkttype, > > + pkt_type2str(sll->sll_pkttype)); > > + tprintf(", If Type %d (%s)", sll->sll_hatype, > > + device_type2str(sll->sll_hatype)); > > + tprintf(", Addr Len %d", sll->sll_halen); > > + tprintf(", Src (%s)", device_addr2str(sll->sll_addr, sll->sll_halen, > > + sll->sll_hatype, addr_str, sizeof(addr_str))); > > + tprintf(", Proto 0x%x", ntohs(sll->sll_protocol)); > > + tprintf(" ]\n"); > > + > > + switch (pcap_devtype_to_linktype(sll->sll_hatype)) { > > + case LINKTYPE_EN10MB: > > + case ___constant_swab32(LINKTYPE_EN10MB): > > + pkt_set_dissector(pkt, ð_lay2, ntohs(sll->sll_protocol)); > > + break; > > + case LINKTYPE_NETLINK: > > + case ___constant_swab32(LINKTYPE_NETLINK): > > + pkt->dissector = &nlmsg_ops; > > + break; > > + default: > > + tprintf(" [ Uknown protocol ]\n"); > > + } > > +} > > + > > +static void sll_print_less(struct pkt_buff *pkt) > > +{ > > + struct sockaddr_ll *sll = pkt->sll; > > + char addr_str[40] = {}; > > + > > + if (!pkt || !sll) > > + return; > > + > > + tprintf(" Pkt Type %d (%s)", sll->sll_pkttype, > > + pkt_type2str(sll->sll_pkttype)); > > + tprintf(", If Type %d (%s)", sll->sll_hatype, > > + device_type2str(sll->sll_hatype)); > > + tprintf(", Addr Len %d", sll->sll_halen); > > + tprintf(", Src (%s)", device_addr2str(sll->sll_addr, sll->sll_halen, > > + sll->sll_hatype, addr_str, sizeof(addr_str))); > > + tprintf(", Proto 0x%x", ntohs(sll->sll_protocol)); > > +} > > + > > +struct protocol sll_ops = { > > + .key = 0, > > + .print_full = sll_print_full, > > + .print_less = sll_print_less, > > +}; > > + > > +struct protocol *dissector_get_sll_entry_point(void) > > +{ > > + return &sll_ops; > > +} > > + > > +struct protocol *dissector_get_sll_exit_point(void) > > +{ > > + return &none_ops; > > +} > > + > > +void dissector_init_sll(int fnttype) > > +{ > > + dissector_set_print_type(&sll_ops, fnttype); > > + dissector_set_print_type(&none_ops, fnttype); > > + dissector_init_oui(); > > +} > > + > > +void dissector_cleanup_sll(void) > > +{ > > + dissector_cleanup_oui(); > > +} > > diff --git a/dissector_sll.h b/dissector_sll.h > > new file mode 100644 > > index 0000000..2067942 > > --- /dev/null > > +++ b/dissector_sll.h > > @@ -0,0 +1,18 @@ > > +/* > > + * netsniff-ng - the packet sniffing beast > > + * Subject to the GPL, version 2. > > + */ > > + > > +#ifndef DISSECTOR_SLL_H > > +#define DISSECTOR_SLL_H > > + > > +#include "hash.h" > > +#include "proto.h" > > + > > +extern void dissector_init_sll(int fnttype); > > +extern void dissector_cleanup_sll(void); > > + > > +extern struct protocol *dissector_get_sll_entry_point(void); > > +extern struct protocol *dissector_get_sll_exit_point(void); > > + > > +#endif /* DISSECTOR_SLL_H */ > > diff --git a/netsniff-ng.c b/netsniff-ng.c > > index e593b9d..91356ba 100644 > > --- a/netsniff-ng.c > > +++ b/netsniff-ng.c > > @@ -318,7 +318,7 @@ static void pcap_to_xmit(struct ctx *ctx) > > > > dissector_entry_point(out, hdr->tp_h.tp_snaplen, > > ctx->link_type, ctx->print_mode, > > - hdr->s_ll.sll_protocol); > > + &hdr->s_ll); > > > > kernel_may_pull_from_tx(&hdr->tp_h); > > > > @@ -469,7 +469,7 @@ static void receive_to_xmit(struct ctx *ctx) > > > > dissector_entry_point(in, hdr_in->tp_h.tp_snaplen, > > ctx->link_type, ctx->print_mode, > > - hdr_in->s_ll.sll_protocol); > > + &hdr_in->s_ll); > > > > if (frame_count_max != 0) { > > if (frame_count >= frame_count_max) { > > @@ -662,7 +662,7 @@ static void read_pcap(struct ctx *ctx) > > > > dissector_entry_point(out, fm.tp_h.tp_snaplen, > > ctx->link_type, ctx->print_mode, > > - fm.s_ll.sll_protocol); > > + &fm.s_ll); > > > > if (is_out_pcap) { > > size_t pcap_len = pcap_get_length(&phdr, ctx->magic); > > @@ -929,7 +929,7 @@ static void walk_t3_block(struct block_desc *pbd, > > struct ctx *ctx, > > hdr, ctx->print_mode, true, *frame_count); > > > > dissector_entry_point(packet, hdr->tp_snaplen, ctx->link_type, > > - ctx->print_mode, sll->sll_protocol); > > + ctx->print_mode, sll); > > next: > > hdr = (void *) ((uint8_t *) hdr + hdr->tp_next_offset); > > sll = (void *) ((uint8_t *) hdr + TPACKET_ALIGN(sizeof(*hdr))); > > @@ -1064,7 +1064,7 @@ static void recv_only_or_dump(struct ctx *ctx) > > > > dissector_entry_point(packet, hdr->tp_h.tp_snaplen, > > ctx->link_type, ctx->print_mode, > > - hdr->s_ll.sll_protocol); > > + &hdr->s_ll); > > > > if (frame_count_max != 0) { > > if (unlikely(frame_count >= frame_count_max)) { > > diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile > > index 92990ff..33701a4 100644 > > --- a/netsniff-ng/Makefile > > +++ b/netsniff-ng/Makefile > > @@ -12,6 +12,7 @@ netsniff-ng-libs += -lGeoIP \ > > endif > > > > netsniff-ng-objs = dissector.o \ > > + dissector_sll.o \ > > dissector_eth.o \ > > dissector_80211.o \ > > dissector_netlink.o \ > > diff --git a/pkt_buff.h b/pkt_buff.h > > index 28872ef..30b999e 100644 > > --- a/pkt_buff.h > > +++ b/pkt_buff.h > > @@ -21,7 +21,7 @@ struct pkt_buff { > > > > struct protocol *dissector; > > uint32_t link_type; > > - uint16_t proto; > > + struct sockaddr_ll *sll; > > }; > > > > static inline struct pkt_buff *pkt_alloc(uint8_t *packet, unsigned int len) > > diff --git a/proto_nlmsg.c b/proto_nlmsg.c > > index 5018adf..44ef328 100644 > > --- a/proto_nlmsg.c > > +++ b/proto_nlmsg.c > > @@ -740,7 +740,7 @@ static void nlmsg(struct pkt_buff *pkt) > > struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr)); > > > > while (hdr) { > > - nlmsg_print(ntohs(pkt->proto), hdr); > > + nlmsg_print(ntohs(pkt->sll->sll_protocol), hdr); > > > > if (!pkt_pull(pkt, NLMSG_PAYLOAD(hdr, 0))) > > break; > > @@ -755,7 +755,7 @@ static void nlmsg(struct pkt_buff *pkt) > > static void nlmsg_less(struct pkt_buff *pkt) > > { > > struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr)); > > - uint16_t family = ntohs(pkt->proto); > > + uint16_t family = ntohs(pkt->sll->sll_protocol); > > char type[32]; > > > > if (hdr == NULL) > > -- > > 1.9.3 > > > > Thank you! > > So I tested only Netlink linktype and after: > > $ sudo netsniff-ng/netsniff-ng -i nl0 -n 10 -o /tmp/nl0.pcap > > netsniff-ng can't dissect it normaly from pcap file: > > $ sudo netsniff-ng/netsniff-ng -i /tmp/nl0.pcap > > and after fixing this: > > > + /* Remap to internal *_LL types in case of LINKTYPE_LINUX_SLL. */ > > + if (linktype == LINKTYPE_LINUX_SLL) { > > + switch (hdr->magic) { > > + case ORIGINAL_TCPDUMP_MAGIC: > > + hdr->magic = ORIGINAL_TCPDUMP_MAGIC_LL; > > + break; > > + case NSEC_TCPDUMP_MAGIC: > > + hdr->magic = NSEC_TCPDUMP_MAGIC_LL; > > + break; > > + case ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC): > > + hdr->magic = > > ___constant_swab32(ORIGINAL_TCPDUMP_MAGIC_LL); > > + break; > > + case ___constant_swab32(NSEC_TCPDUMP_MAGIC): > > + hdr->magic = ___constant_swab32(NSEC_TCPDUMP_MAGIC_LL); > > + break; > > + } > > + } > > by adding "|| linktype == LINKTYPE_LINUX_SLL)" I got dissected Netlink > messages. > > Also may be it is better to get this 'switch' out from validation > function, just but semantic meaning of this function which should just > validate but not change something valuable.
Sorry .... I meant I added LINKTYPE_NETLINK checking too, and it fixed dissecting. -- 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.