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, &eth_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.

Reply via email to