diff options
| author | Vadim Kochan <vadim4j@gmail.com> | 2015-06-17 00:38:31 +0300 | 
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2015-06-17 23:02:12 +0200 | 
| commit | 1c8226e7b4a452c576f5e891895faadd5065be0a (patch) | |
| tree | 40fa88c8e3bfcc555f14a446f204a7186ad58dbc | |
| parent | b780681c3c9b42d6e60d369c499eaf4b94088c1d (diff) | |
netsniff-ng: nlmsg: Print rtnl neigh info
Dissect basic rtnl neighbour info.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
| -rw-r--r-- | proto_nlmsg.c | 101 | 
1 files changed, 101 insertions, 0 deletions
| diff --git a/proto_nlmsg.c b/proto_nlmsg.c index 9dc9f6b..5018adf 100644 --- a/proto_nlmsg.c +++ b/proto_nlmsg.c @@ -30,6 +30,15 @@  #define RTA_UINT32(attr) (*(uint32_t *)RTA_DATA(attr))  #define RTA_STR(attr) ((char *)RTA_DATA(attr)) +#ifndef NDA_RTA +#define NDA_RTA(r) \ +	((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif + +#ifndef NDA_PAYLOAD +#define NDA_PAYLOAD(n)	NLMSG_PAYLOAD(n,sizeof(struct ndmsg)) +#endif +  #define attr_fmt(attr, fmt, ...) \  	tprintf("\tA: "fmt, ##__VA_ARGS__); \  	tprintf(", Len %lu\n", RTA_LEN(attr)); @@ -562,6 +571,93 @@ static void rtnl_print_route(struct nlmsghdr *hdr)  	}  } +static struct flag_name neigh_states[] = { +	{ "incomplete", NUD_INCOMPLETE }, +	{ "reachable", NUD_REACHABLE }, +	{ "stale", NUD_STALE }, +	{ "delay", NUD_DELAY }, +	{ "probe", NUD_PROBE }, +	{ "failed", NUD_FAILED }, +	{ "noarp", NUD_NOARP }, +	{ "permanent", NUD_PERMANENT }, +	{ "none", NUD_NONE }, +	{ NULL, 0 }, +}; + +static struct flag_name neigh_flags[] = { +	{ "use", NTF_USE }, +	{ "self", NTF_SELF }, +	{ "master", NTF_MASTER }, +	{ "proxy", NTF_PROXY }, +#ifdef NTF_EXT_LEARNED +	{ "ext learned", NTF_EXT_LEARNED }, +#endif +	{ "router", NTF_ROUTER }, +	{ NULL, 0 }, +}; + +static void rtnl_print_neigh(struct nlmsghdr *hdr) +{ +	struct ndmsg *ndm = NLMSG_DATA(hdr); +	uint32_t attrs_len = NDA_PAYLOAD(hdr); +	struct rtattr *attr = NDA_RTA(ndm); +	struct nda_cacheinfo *ci; +	int hz = get_user_hz(); +	char addr_str[256]; +	char hw_addr[30]; +	char states[256]; +	char flags[256]; + +	tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family, +			colorize_start(bold), +			addr_family2str(ndm->ndm_family), +			colorize_end()); +	tprintf(", Link Index %d", ndm->ndm_ifindex); +	tprintf(", State %d (%s%s%s)", ndm->ndm_state, +			colorize_start(bold), +			flags2str(neigh_states, ndm->ndm_state, states, +				sizeof(states)), +			colorize_end()); +	tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags, +			colorize_start(bold), +			flags2str(neigh_flags, ndm->ndm_flags, flags, +				sizeof(flags)), +			colorize_end()); +	tprintf(", Type %d (%s%s%s)", ndm->ndm_type, +			colorize_start(bold), +			route_type2str(ndm->ndm_type), +			colorize_end()); +	tprintf(" ]\n"); + +	for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) { +		switch (attr->rta_type) { +		case NDA_DST: +			attr_fmt(attr, "Address %s", addr2str(ndm->ndm_family, +						RTA_DATA(attr), addr_str, +						sizeof(addr_str))); +			break; +		case NDA_LLADDR: +			attr_fmt(attr, "HW Address %s", +					device_addr2str(RTA_DATA(attr), +						RTA_LEN(attr), 0, hw_addr, +						sizeof(hw_addr))); +			break; +		case NDA_PROBES: +			attr_fmt(attr, "Probes %d", RTA_UINT32(attr)); +			break; +		case NDA_CACHEINFO: +			ci = RTA_DATA(attr); +			tprintf("\tA: Cache ("); +			tprintf("confirmed(%ds)", ci->ndm_confirmed / hz); +			tprintf(", used(%ds)", ci->ndm_used / hz); +			tprintf(", updated(%ds)", ci->ndm_updated / hz); +			tprintf(", refcnt(%d))", ci->ndm_refcnt); +			tprintf(", Len %lu\n", RTA_LEN(attr)); +			break; +		} +	} +} +  static void rtnl_msg_print(struct nlmsghdr *hdr)  {  	switch (hdr->nlmsg_type) { @@ -581,6 +677,11 @@ static void rtnl_msg_print(struct nlmsghdr *hdr)  	case RTM_GETROUTE:  		rtnl_print_route(hdr);  		break; +	case RTM_NEWNEIGH: +	case RTM_DELNEIGH: +	case RTM_GETNEIGH: +		rtnl_print_neigh(hdr); +		break;  	}  } | 
