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 <[email protected]> > 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 <[email protected]> > Signed-off-by: Daniel Borkmann <[email protected]> > --- > 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 <[email protected]> > 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 <[email protected]> > Signed-off-by: Daniel Borkmann <[email protected]> > --- > 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. -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
