From 107456c646ab38e5ccb6ee788389faced59c16ff Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Tue, 19 May 2015 17:10:38 +0300 Subject: netsniff-ng, nlmsg: Dissect rtnl link type messages Dump RTnetlink interface related info with attributes. Signed-off-by: Vadim Kochan Signed-off-by: Daniel Borkmann --- netsniff-ng/Makefile | 2 + proto_nlmsg.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile index 9fe2ffe..92990ff 100644 --- a/netsniff-ng/Makefile +++ b/netsniff-ng/Makefile @@ -1,5 +1,6 @@ netsniff-ng-libs = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --libs libnl-3.0) \ $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --libs libnl-genl-3.0) \ + $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --libs libnl-route-3.0) \ -lpthread ifeq ($(CONFIG_LIBPCAP), 1) @@ -78,6 +79,7 @@ endif netsniff-ng-eflags = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --cflags libnl-3.0) \ $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --cflags libnl-genl-3.0) \ + $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --cflags libnl-route-3.0) \ -DNEED_TCPDUMP_LIKE_FILTER netsniff-ng-confs = ether.conf \ diff --git a/proto_nlmsg.c b/proto_nlmsg.c index 1b0eed7..89b48b2 100644 --- a/proto_nlmsg.c +++ b/proto_nlmsg.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include "pkt_buff.h" #include "proto.h" @@ -120,6 +123,115 @@ static const char *nlmsg_rtnl_type2str(uint16_t type) } } +static char *if_type2str(uint16_t type) +{ + switch (type) { + case ARPHRD_ETHER: return "ether"; + case ARPHRD_EETHER: return "eether"; + case ARPHRD_AX25: return "ax25"; + case ARPHRD_PRONET: return "pronet"; + case ARPHRD_CHAOS: return "chaos"; + case ARPHRD_IEEE802: return "ieee802"; + case ARPHRD_ARCNET: return "arcnet"; + case ARPHRD_APPLETLK: return "appletlk"; + case ARPHRD_DLCI: return "dlci"; + case ARPHRD_ATM: return "atm"; + case ARPHRD_METRICOM: return "metricom"; + case ARPHRD_IEEE1394: return "ieee1394"; + case ARPHRD_INFINIBAND: return "infiniband"; + case ARPHRD_SLIP: return "slip"; + case ARPHRD_CSLIP: return "cslip"; + case ARPHRD_SLIP6: return "slip6"; + case ARPHRD_CSLIP6: return "cslip6"; + case ARPHRD_RSRVD: return "RSRVD"; + case ARPHRD_ADAPT: return "adapt"; + case ARPHRD_ROSE: return "rose"; + case ARPHRD_X25: return "x25"; + case ARPHRD_HWX25: return "hwx25"; + case ARPHRD_CAN: return "can"; + case ARPHRD_PPP: return "ppp"; + case ARPHRD_HDLC: return "hdlc"; + case ARPHRD_LAPB: return "lapb"; + case ARPHRD_DDCMP: return "ddcmp"; + case ARPHRD_RAWHDLC: return "rawhdlc"; + case ARPHRD_TUNNEL: return "tunnel"; + case ARPHRD_TUNNEL6: return "tunnel6"; + case ARPHRD_FRAD: return "frad"; + case ARPHRD_SKIP: return "skip"; + case ARPHRD_LOOPBACK: return "loopback"; + case ARPHRD_LOCALTLK: return "localtlk"; + case ARPHRD_FDDI: return "fddi"; + case ARPHRD_BIF: return "bif"; + case ARPHRD_SIT: return "sit"; + case ARPHRD_IPDDP: return "ipddp"; + case ARPHRD_IPGRE: return "ipgre"; + case ARPHRD_PIMREG: return "pimreg"; + case ARPHRD_HIPPI: return "hippi"; + case ARPHRD_ASH: return "ash"; + case ARPHRD_ECONET: return "econet"; + case ARPHRD_IRDA: return "irda"; + case ARPHRD_FCPP: return "fcpp"; + case ARPHRD_FCAL: return "fcal"; + case ARPHRD_FCPL: return "fcpl"; + case ARPHRD_FCFABRIC: return "fcfb0"; + case ARPHRD_FCFABRIC + 1: return "fcfb1"; + case ARPHRD_FCFABRIC + 2: return "fcfb2"; + case ARPHRD_FCFABRIC + 3: return "fcfb3"; + case ARPHRD_FCFABRIC + 4: return "fcfb4"; + case ARPHRD_FCFABRIC + 5: return "fcfb5"; + case ARPHRD_FCFABRIC + 6: return "fcfb6"; + case ARPHRD_FCFABRIC + 7: return "fcfb7"; + case ARPHRD_FCFABRIC + 8: return "fcfb8"; + case ARPHRD_FCFABRIC + 9: return "fcfb9"; + case ARPHRD_FCFABRIC + 10: return "fcfb10"; + case ARPHRD_FCFABRIC + 11: return "fcfb11"; + case ARPHRD_FCFABRIC + 12: return "fcfb12"; + case ARPHRD_IEEE802_TR: return "ieee802_tr"; + case ARPHRD_IEEE80211: return "ieee80211"; + case ARPHRD_IEEE80211_PRISM: return "ieee80211_prism"; + case ARPHRD_IEEE80211_RADIOTAP: return "ieee80211_radiotap"; + case ARPHRD_IEEE802154: return "ieee802154"; + case ARPHRD_PHONET: return "phonet"; + case ARPHRD_PHONET_PIPE: return "phonet_pipe"; + case ARPHRD_CAIF: return "caif"; + case ARPHRD_IP6GRE: return "ip6gre"; + case ARPHRD_NETLINK: return "netlink"; + case ARPHRD_NONE: return "none"; + case ARPHRD_VOID: return "void"; + + default: return "Unknown"; + } +} + +/* Taken from iproute2 */ +static const char *ll_addr_n2a(const unsigned char *addr, int alen, int type, + char *buf, int blen) +{ + int i; + int l; + + if (alen == 4 && + (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) { + return inet_ntop(AF_INET, addr, buf, blen); + } + if (alen == 16 && type == ARPHRD_TUNNEL6) { + return inet_ntop(AF_INET6, addr, buf, blen); + } + l = 0; + for (i=0; iifi_family == AF_UNSPEC) + af_link = "unspec"; + else if (ifi->ifi_family == AF_BRIDGE) + af_link = "bridge"; + + tprintf(" [ Link Family %d (%s%s%s)", ifi->ifi_family, + colorize_start(bold), af_link, colorize_end()); + tprintf(", Type %d (%s%s%s)", ifi->ifi_type, + colorize_start(bold), + if_type2str(ifi->ifi_type), + colorize_end()); + tprintf(", Index %d", ifi->ifi_index); + tprintf(", Flags 0x%x (%s%s%s)", ifi->ifi_flags, + colorize_start(bold), + rtnl_link_flags2str(ifi->ifi_flags, flags, + sizeof(flags)), + colorize_end()); + tprintf(", Change 0x%x (%s%s%s) ]\n", ifi->ifi_change, + colorize_start(bold), + rtnl_link_flags2str(ifi->ifi_change, flags, + sizeof(flags)), + colorize_end()); + + for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) { + switch (attr->rta_type) { + case IFLA_ADDRESS: + tprintf("\tA: Address %s\n", + ll_addr_n2a(RTA_DATA(attr), + RTA_PAYLOAD(attr), + ifi->ifi_type, if_addr, + sizeof(if_addr))); + break; + case IFLA_BROADCAST: + tprintf("\tA: Broadcast %s\n", + ll_addr_n2a(RTA_DATA(attr), + RTA_PAYLOAD(attr), + ifi->ifi_type, if_addr, + sizeof(if_addr))); + break; + case IFLA_IFNAME: + tprintf("\tA: Name %s%s%s\n", + colorize_start(bold), + (char *)(RTA_DATA(attr)), + colorize_end()); + break; + case IFLA_MTU: + tprintf("\tA: MTU %d\n", *(int *)(RTA_DATA(attr))); + break; + case IFLA_LINK: + tprintf("\tA: Link %d\n", *(int *)(RTA_DATA(attr))); + break; + case IFLA_QDISC: + tprintf("\tA: QDisc %s\n", (char *)(RTA_DATA(attr))); + break; + case IFLA_OPERSTATE: + { + uint8_t st = *(uint8_t *)(RTA_DATA(attr)); + char states[256]; + + tprintf("\tA: Operation state 0x%x (%s%s%s)\n", + st, + colorize_start(bold), + rtnl_link_operstate2str(st, + states, sizeof(states)), + colorize_end()); + } + break; + case IFLA_LINKMODE: + { + uint8_t mode = *(uint8_t *)(RTA_DATA(attr)); + char str[32]; + + tprintf("\tA: Mode 0x%x (%s%s%s)\n", mode, + colorize_start(bold), + rtnl_link_mode2str(mode, str, + sizeof(str)), + colorize_end()); + } + break; + case IFLA_GROUP: + tprintf("\tA: Group %d\n", *(int *)(RTA_DATA(attr))); + break; + case IFLA_TXQLEN: + tprintf("\tA: Tx queue len %d\n", + *(int *)(RTA_DATA(attr))); + break; + case IFLA_NET_NS_PID: + tprintf("\tA: Network namespace pid %d\n", + *(int *)(RTA_DATA(attr))); + break; + case IFLA_NET_NS_FD: + tprintf("\tA: Network namespace fd %d\n", + *(int *)(RTA_DATA(attr))); + break; + } + } +} + +static void rtnl_msg_print(struct nlmsghdr *hdr) +{ + switch (hdr->nlmsg_type) { + case RTM_NEWLINK: + case RTM_DELLINK: + case RTM_GETLINK: + case RTM_SETLINK: + rtnl_print_ifinfo(hdr); + } +} + static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr) { char type[32]; @@ -178,6 +408,9 @@ static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr) tprintf(" (%s%s%s)", colorize_start(bold), basename(procname), colorize_end()); tprintf(" ]\n"); + + if (family == NETLINK_ROUTE) + rtnl_msg_print(hdr); } static void nlmsg(struct pkt_buff *pkt) -- cgit v1.2.3-54-g00ecf