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.)

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

Reply via email to