On Fri, Jun 19, 2015 at 10:47:49PM +0200, Daniel Borkmann wrote: > On 06/18/2015 11:49 AM, Daniel Borkmann wrote: > >On 06/18/2015 11:42 AM, Vadim Kochan wrote: > >>On Thu, Jun 18, 2015 at 10:45:29AM +0200, Daniel Borkmann wrote: > >>>I've started splitting this into smaller digestible chunks, > >>>couple of more evenings and it should be done from my side. > >>>Thanks for your patience. > >> > >>But implementation now is OK in the last original patch series v2 ? > > > >The only missing piece from your first patch I need to go through > >is the pcap i/o parts. I wanted to check if two new dummy types > >are possible (where we'd have transparent mapping - so it would be > >semantically the same as this patch), whether they result in a > >smaller code diff and would have lesser impact on the fast path. > >If that's the case, I'd go for that, if not I will take the current > >remaining piece. Will let you know. > > Okay, here it goes. I tested this with capturing from netsniff-ng, > reading via Wireshark and capturing from Wireshark and reading via > netsniff-ng. > > Seems fine, please double check it. > > All in all this should have less overhead and result in smaller > code diff. Apart from that, the pcap_io.h might need some cleanups > anyway. > > [PATCH] 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 > >
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 ? -- 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.
