From: Vadim Kochan <vadi...@gmail.com>

nlmsg proto handler can't identify Netlink protocol
from nlmsghdr, so sockaddr_ll can be used to get it.

Also renamed [proto -> handler] member in pkt_buff struct,
which is more understandable.

Example:

>U nlmon0 4756 1429891435s.14505747ns
 [ NLMSG Proto 0 (RTNETLINK), Len 1160, Type 0x0010 (0x10), Flags 0x0002 
(MULTI), Seq-Nr 1429891436, PID 31613 ]

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 dissector.c   | 18 ++++++++++--------
 dissector.h   |  3 ++-
 netsniff-ng.c | 14 +++++++++-----
 pkt_buff.h    | 19 ++++++++++---------
 proto_nlmsg.c | 34 ++++++++++++++++++++++++++++++++++
 5 files changed, 65 insertions(+), 23 deletions(-)

diff --git a/dissector.c b/dissector.c
index 7c8ba39..5f60a11 100644
--- a/dissector.c
+++ b/dissector.c
@@ -42,25 +42,26 @@ int dissector_set_print_type(void *ptr, int type)
 static void dissector_main(struct pkt_buff *pkt, struct protocol *start,
                           struct protocol *end)
 {
-       struct protocol *proto;
+       struct protocol *handler;
 
        if (!start)
                return;
 
-       for (pkt->proto = start; pkt->proto; ) {
-               if (unlikely(!pkt->proto->process))
+       for (pkt->handler = start; pkt->handler; ) {
+               if (unlikely(!pkt->handler->process))
                        break;
 
-               proto = pkt->proto;
-               pkt->proto = NULL;
-               proto->process(pkt);
+               handler         = pkt->handler;
+               pkt->handler    = NULL;
+               handler->process(pkt);
        }
 
        if (end && likely(end->process))
                end->process(pkt);
 }
 
-void dissector_entry_point(uint8_t *packet, size_t len, int linktype, int mode)
+void dissector_entry_point(uint8_t *packet, size_t len, int linktype, int mode,
+               uint16_t proto)
 {
        struct protocol *proto_start, *proto_end;
        struct pkt_buff *pkt;
@@ -69,7 +70,8 @@ void dissector_entry_point(uint8_t *packet, size_t len, int 
linktype, int mode)
                return;
 
        pkt = pkt_alloc(packet, len);
-       pkt->link_type = linktype;
+       pkt->link_type  = linktype;
+       pkt->proto      = proto;
 
        switch (linktype) {
        case LINKTYPE_EN10MB:
diff --git a/dissector.h b/dissector.h
index fc20eda..b2fb6b9 100644
--- a/dissector.h
+++ b/dissector.h
@@ -100,7 +100,8 @@ 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);
+extern void dissector_entry_point(uint8_t *packet, size_t len, int linktype,
+               int mode, uint16_t proto);
 extern void dissector_cleanup_all(void);
 extern int dissector_set_print_type(void *ptr, int type);
 
diff --git a/netsniff-ng.c b/netsniff-ng.c
index ee9dc38..a239b8b 100644
--- a/netsniff-ng.c
+++ b/netsniff-ng.c
@@ -311,7 +311,8 @@ static void pcap_to_xmit(struct ctx *ctx)
                                       ctx->link_type, hdr, ctx->print_mode);
 
                        dissector_entry_point(out, hdr->tp_h.tp_snaplen,
-                                             ctx->link_type, ctx->print_mode);
+                                             ctx->link_type, ctx->print_mode,
+                                             hdr->s_ll.sll_protocol);
 
                        kernel_may_pull_from_tx(&hdr->tp_h);
 
@@ -460,7 +461,8 @@ static void receive_to_xmit(struct ctx *ctx)
                                       ctx->link_type, hdr_in, ctx->print_mode);
 
                        dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
-                                             ctx->link_type, ctx->print_mode);
+                                             ctx->link_type, ctx->print_mode,
+                                             hdr_in->s_ll.sll_protocol);
 
                        if (frame_count_max != 0) {
                                if (frame_count >= frame_count_max) {
@@ -643,7 +645,8 @@ static void read_pcap(struct ctx *ctx)
                               ctx->print_mode);
 
                dissector_entry_point(out, fm.tp_h.tp_snaplen,
-                                     ctx->link_type, ctx->print_mode);
+                                     ctx->link_type, ctx->print_mode,
+                                     fm.s_ll.sll_protocol);
 
                if (is_out_pcap) {
                        size_t pcap_len = pcap_get_length(&phdr, ctx->magic);
@@ -897,7 +900,7 @@ static void walk_t3_block(struct block_desc *pbd, struct 
ctx *ctx,
                                 hdr, ctx->print_mode, true);
 
                dissector_entry_point(packet, hdr->tp_snaplen, ctx->link_type,
-                                     ctx->print_mode);
+                                     ctx->print_mode, sll->sll_protocol);
 next:
                 hdr = (void *) ((uint8_t *) hdr + hdr->tp_next_offset);
                sll = (void *) ((uint8_t *) hdr + TPACKET_ALIGN(sizeof(*hdr)));
@@ -1031,7 +1034,8 @@ static void recv_only_or_dump(struct ctx *ctx)
                                       ctx->link_type, hdr, ctx->print_mode);
 
                        dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
-                                             ctx->link_type, ctx->print_mode);
+                                             ctx->link_type, ctx->print_mode,
+                                             hdr->s_ll.sll_protocol);
 
                        if (frame_count_max != 0) {
                                if (unlikely(frame_count >= frame_count_max)) {
diff --git a/pkt_buff.h b/pkt_buff.h
index 1350388..d51e3d3 100644
--- a/pkt_buff.h
+++ b/pkt_buff.h
@@ -19,19 +19,20 @@ struct pkt_buff {
        uint8_t      *tail;
        unsigned int  size;
 
-       struct protocol *proto;
+       struct protocol *handler;
        int link_type;
+       uint16_t proto;
 };
 
 static inline struct pkt_buff *pkt_alloc(uint8_t *packet, unsigned int len)
 {
        struct pkt_buff *pkt = xmalloc(sizeof(*pkt));
 
-       pkt->head = packet;
-       pkt->data = packet;
-       pkt->tail = packet + len;
-       pkt->size = len;
-       pkt->proto = NULL;
+       pkt->head       = packet;
+       pkt->data       = packet;
+       pkt->tail       = packet + len;
+       pkt->size       = len;
+       pkt->handler    = NULL;
 
        return pkt;
 }
@@ -105,9 +106,9 @@ static inline void pkt_set_proto(struct pkt_buff *pkt, 
struct hash_table *table,
 {
        bug_on(!pkt || !table);
 
-       pkt->proto = lookup_hash(key, table);
-       while (pkt->proto && key != pkt->proto->key)
-               pkt->proto = pkt->proto->next;
+       pkt->handler = lookup_hash(key, table);
+       while (pkt->handler && key != pkt->handler->key)
+               pkt->handler = pkt->handler->next;
 }
 
 #endif /* PKT_BUFF_H */
diff --git a/proto_nlmsg.c b/proto_nlmsg.c
index 787d9d6..f7368b2 100644
--- a/proto_nlmsg.c
+++ b/proto_nlmsg.c
@@ -14,12 +14,42 @@
 #include "proto.h"
 #include "protos.h"
 
+static char *nl_proto2str(uint16_t proto)
+{
+       switch (proto) {
+       case NETLINK_ROUTE:             return "RTNETLINK";
+       case NETLINK_UNUSED:            return "UNUSED";
+       case NETLINK_USERSOCK:          return "USERSOCK";
+       case NETLINK_FIREWALL:          return "FIREWALL";
+       case NETLINK_SOCK_DIAG:         return "SOCK_DIAG";
+       case NETLINK_NFLOG:             return "NFLOG";
+       case NETLINK_XFRM:              return "XFRM";
+       case NETLINK_SELINUX:           return "SELINUX";
+       case NETLINK_ISCSI:             return "ISCSI";
+       case NETLINK_AUDIT:             return "AUDIT";
+       case NETLINK_FIB_LOOKUP:        return "FIB_LOOKUP";
+       case NETLINK_CONNECTOR:         return "CONNECTOR";
+       case NETLINK_NETFILTER:         return "NETFILTER";
+       case NETLINK_IP6_FW:            return "IP6_FW";
+       case NETLINK_DNRTMSG:           return "DNRTMSG";
+       case NETLINK_KOBJECT_UEVENT:    return "UEVENT";
+       case NETLINK_GENERIC:           return "GENERIC";
+       case NETLINK_SCSITRANSPORT:     return "SCSI";
+       case NETLINK_ECRYPTFS:          return "ECRYPTFS";
+       case NETLINK_RDMA:              return "RDMA";
+       case NETLINK_CRYPTO:            return "CRYPTO";
+       }
+
+       return NULL;
+}
+
 static void nlmsg(struct pkt_buff *pkt)
 {
        struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr));
        char type[32];
        char flags[128];
        char procname[PATH_MAX];
+       char *proto_name;
 
        if (hdr == NULL)
                return;
@@ -43,7 +73,11 @@ static void nlmsg(struct pkt_buff *pkt)
        } else
                snprintf(procname, sizeof(procname), "kernel");
 
+       proto_name = nl_proto2str(ntohs(pkt->proto));
+
        tprintf(" [ NLMSG ");
+       tprintf("Proto %d (%s%s%s), ", ntohs(pkt->proto), colorize_start(bold),
+                       proto_name ?: "Unknown", colorize_end());
        tprintf("Len %u, ", hdr->nlmsg_len);
        tprintf("Type 0x%.4x (%s%s%s), ", hdr->nlmsg_type,
                colorize_start(bold),
-- 
2.3.1

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