From d312a25879d5826ff1ca638410bbd36ba2619d93 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Fri, 24 Apr 2015 19:14:35 +0300 Subject: netsniff-ng nlmsg: Print netlink protocol name 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 [tklauser: Handle usage of NETLINK_SOCK_DIAG with pre 3.10 kernel headers, fix nl_proto2str() return value, formatting changes] Signed-off-by: Tobias Klauser --- dissector.c | 16 +++++++++------- dissector.h | 3 ++- netsniff-ng.c | 14 +++++++++----- pkt_buff.h | 11 ++++++----- proto_nlmsg.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/dissector.c b/dissector.c index 7c8ba39..ca98386 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; @@ -70,6 +71,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; switch (linktype) { case LINKTYPE_EN10MB: diff --git a/dissector.h b/dissector.h index fc20eda..d749205 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 2b9732e..f447864 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -314,7 +314,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); @@ -463,7 +464,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) { @@ -646,7 +648,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); @@ -913,7 +916,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))); @@ -1047,7 +1050,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..58b0506 100644 --- a/pkt_buff.h +++ b/pkt_buff.h @@ -19,8 +19,9 @@ 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) @@ -31,7 +32,7 @@ static inline struct pkt_buff *pkt_alloc(uint8_t *packet, unsigned int len) pkt->data = packet; pkt->tail = packet + len; pkt->size = len; - pkt->proto = NULL; + 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..b219867 100644 --- a/proto_nlmsg.c +++ b/proto_nlmsg.c @@ -14,6 +14,39 @@ #include "proto.h" #include "protos.h" +static const 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"; +/* NETLINK_INET_DIAG was renamed to NETLINK_SOCK_DIAG in Linux kernel 3.10 */ +#if defined(NETLINK_SOCK_DIAG) + case NETLINK_SOCK_DIAG: return "SOCK_DIAG"; +#elif defined(NETLINK_INET_DIAG) + case NETLINK_INET_DIAG: return "INET_DIAG"; +#endif + 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"; + default: return "Unknown"; + } +} + static void nlmsg(struct pkt_buff *pkt) { struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, sizeof(*hdr)); @@ -44,6 +77,8 @@ static void nlmsg(struct pkt_buff *pkt) snprintf(procname, sizeof(procname), "kernel"); tprintf(" [ NLMSG "); + tprintf("Proto %d (%s%s%s), ", ntohs(pkt->proto), colorize_start(bold), + nl_proto2str(ntohs(pkt->proto)), colorize_end()); tprintf("Len %u, ", hdr->nlmsg_len); tprintf("Type 0x%.4x (%s%s%s), ", hdr->nlmsg_type, colorize_start(bold), -- cgit v1.2.3-54-g00ecf