2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2014 Tobias Klauser.
4 * Subject to the GPL, version 2.
12 #include <netlink/msg.h>
13 #include <netlink/route/link.h>
14 #include <netlink/route/addr.h>
15 #include <arpa/inet.h>
24 #define INFINITY 0xFFFFFFFFU
26 #define RTA_LEN(attr) ((int)RTA_PAYLOAD(attr))
27 #define RTA_INT(attr) (*(int *)RTA_DATA(attr))
28 #define RTA_UINT(attr) (*(unsigned int *)RTA_DATA(attr))
29 #define RTA_UINT8(attr) (*(uint8_t *)RTA_DATA(attr))
30 #define RTA_UINT32(attr) (*(uint32_t *)RTA_DATA(attr))
31 #define RTA_STR(attr) ((char *)RTA_DATA(attr))
35 ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
39 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
43 #define NLA_LENGTH(len) (NLA_ALIGN(sizeof(struct nlattr)) + (len))
47 #define NLA_DATA(nla) ((void*)(((char*)(nla)) + NLA_LENGTH(0)))
51 #define NLA_PAYLOAD(nla) ((int)((nla)->nla_len) - NLA_LENGTH(0))
54 #define NLA_LEN(attr) ((int)NLA_PAYLOAD(attr))
55 #define NLA_INT(attr) (*(int *)NLA_DATA(attr))
56 #define NLA_UINT(attr) (*(unsigned int *)NLA_DATA(attr))
57 #define NLA_UINT8(attr) (*(uint8_t *)NLA_DATA(attr))
58 #define NLA_UINT16(attr) (*(uint16_t *)NLA_DATA(attr))
59 #define NLA_UINT32(attr) (*(uint32_t *)NLA_DATA(attr))
60 #define NLA_STR(attr) ((char *)NLA_DATA(attr))
63 #define GEN_NLA(n) ((struct nlattr*)(((char*)(n)) + GENL_HDRLEN))
67 #define NLA_OK(nla,len) \
68 ((len) >= (int)sizeof(struct nlattr) && \
69 (nla)->nla_len >= sizeof(struct nlattr) && \
70 (nla)->nla_len <= (len))
74 #define NLA_NEXT(nla,attrlen) \
75 ((attrlen) -= NLA_ALIGN((nla)->nla_len), \
76 (struct nlattr*)(((char*)(nla)) + NLA_ALIGN((nla)->nla_len)))
79 #define rta_fmt(attr, fmt, ...) \
80 tprintf("\tA: "fmt, ##__VA_ARGS__); \
81 tprintf(", Len %d\n", RTA_LEN(attr));
83 #define nla_fmt(attr, fmt, ...) \
84 tprintf("\tA: "fmt, ##__VA_ARGS__); \
85 tprintf(", Len %d\n", NLA_LEN(attr));
87 #define nla_fmt_nested(attr, fmt, ...) \
88 tprintf("[ "fmt, ##__VA_ARGS__); \
89 tprintf(", Len %d] ", NLA_LEN(attr));
91 #define nla_fmt_nested_start(attr, fmt, ...) \
92 tprintf("\t A: "fmt, ##__VA_ARGS__); \
93 tprintf(", Len %d ", NLA_LEN(attr));
95 #define nla_fmt_nested_end() tprintf("\n")
102 static const char *flags2str(struct flag_name
*tbl
, unsigned int flags
,
105 int bits_stay
= flags
;
109 for (; tbl
&& tbl
->name
; tbl
++) {
110 if (!(tbl
->flag
& flags
))
113 bits_stay
&= ~tbl
->flag
;
114 strncat(buf
, tbl
->name
, len
- strlen(buf
) - 1);
116 if (bits_stay
& flags
)
117 strncat(buf
, ",", len
- strlen(buf
) - 1);
123 static void nlmsg_print_raw(struct nlmsghdr
*hdr
)
125 u32 len
= hdr
->nlmsg_len
;
128 _ascii((uint8_t *) hdr
+ NLMSG_HDRLEN
, len
- NLMSG_HDRLEN
);
129 _hex((uint8_t *) hdr
+ NLMSG_HDRLEN
, len
- NLMSG_HDRLEN
);
133 static const char *nlmsg_family2str(uint16_t family
)
136 case NETLINK_ROUTE
: return "routing";
137 case NETLINK_UNUSED
: return "unused";
138 case NETLINK_USERSOCK
: return "user-mode socket";
139 case NETLINK_FIREWALL
: return "unused, formerly ip_queue";
140 /* NETLINK_INET_DIAG was renamed to NETLINK_SOCK_DIAG in Linux kernel 3.10 */
141 #if defined(NETLINK_SOCK_DIAG)
142 case NETLINK_SOCK_DIAG
: return "socket monitoring";
143 #elif defined(NETLINK_INET_DIAG)
144 case NETLINK_INET_DIAG
: return "INET socket monitoring";
146 case NETLINK_NFLOG
: return "netfilter ULOG";
147 case NETLINK_XFRM
: return "IPsec";
148 case NETLINK_SELINUX
: return "SELinux event notification";
149 case NETLINK_ISCSI
: return "Open-iSCSI";
150 case NETLINK_AUDIT
: return "auditing";
151 case NETLINK_FIB_LOOKUP
: return "FIB lookup";
152 case NETLINK_CONNECTOR
: return "Kernel connector";
153 case NETLINK_NETFILTER
: return "Netfilter";
154 case NETLINK_IP6_FW
: return "unused, formerly ip6_queue";
155 case NETLINK_DNRTMSG
: return "DECnet routing";
156 case NETLINK_KOBJECT_UEVENT
: return "Kernel messages";
157 case NETLINK_GENERIC
: return "Generic";
158 case NETLINK_SCSITRANSPORT
: return "SCSI transports";
159 case NETLINK_ECRYPTFS
: return "ecryptfs";
160 case NETLINK_RDMA
: return "RDMA";
161 #if defined(NETLINK_CRYPTO)
162 case NETLINK_CRYPTO
: return "Crypto layer";
164 default: return "Unknown";
168 static const char *nlmsg_rtnl_type2str(uint16_t type
)
171 case RTM_NEWLINK
: return "new link";
172 case RTM_DELLINK
: return "del link";
173 case RTM_GETLINK
: return "get link";
174 case RTM_SETLINK
: return "set link";
176 case RTM_NEWADDR
: return "new addr";
177 case RTM_DELADDR
: return "del addr";
178 case RTM_GETADDR
: return "get addr";
180 case RTM_NEWROUTE
: return "new route";
181 case RTM_DELROUTE
: return "del route";
182 case RTM_GETROUTE
: return "get route";
184 case RTM_NEWNEIGH
: return "new neigh";
185 case RTM_DELNEIGH
: return "del neigh";
186 case RTM_GETNEIGH
: return "get neigh";
188 case RTM_NEWRULE
: return "new rule";
189 case RTM_DELRULE
: return "del rule";
190 case RTM_GETRULE
: return "get rule";
192 case RTM_NEWQDISC
: return "new tc qdisc";
193 case RTM_DELQDISC
: return "del tc qdisc";
194 case RTM_GETQDISC
: return "get tc qdisc";
196 case RTM_NEWTCLASS
: return "new tc class";
197 case RTM_DELTCLASS
: return "del tc class";
198 case RTM_GETTCLASS
: return "get tc class";
200 case RTM_NEWTFILTER
: return "new tc filter";
201 case RTM_DELTFILTER
: return "del tc filter";
202 case RTM_GETTFILTER
: return "get tc filter";
204 case RTM_NEWACTION
: return "new tc action";
205 case RTM_DELACTION
: return "del tc action";
206 case RTM_GETACTION
: return "get tc action";
208 case RTM_NEWPREFIX
: return "new prefix";
210 case RTM_GETMULTICAST
: return "get mcast addr";
212 case RTM_GETANYCAST
: return "get anycast addr";
214 case RTM_NEWNEIGHTBL
: return "new neigh table";
215 case RTM_GETNEIGHTBL
: return "get neigh table";
216 case RTM_SETNEIGHTBL
: return "set neigh table";
218 case RTM_NEWNDUSEROPT
: return "new ndisc user option";
220 case RTM_NEWADDRLABEL
: return "new addr label";
221 case RTM_DELADDRLABEL
: return "del addr label";
222 case RTM_GETADDRLABEL
: return "get addr label";
224 case RTM_GETDCB
: return "get data-center-bridge";
225 case RTM_SETDCB
: return "set data-center-bridge";
227 #if defined(RTM_NEWNETCONF)
228 case RTM_NEWNETCONF
: return "new netconf";
229 case RTM_GETNETCONF
: return "get netconf";
232 #if defined(RTM_NEWMDB)
233 case RTM_NEWMDB
: return "new bridge mdb";
234 case RTM_DELMDB
: return "del bridge mdb";
235 case RTM_GETMDB
: return "get bridge mdb";
237 default: return NULL
;
241 static const char *nlmsg_genl_type2str(uint16_t type
)
244 case GENL_ID_CTRL
: return "nlctrl";
245 #if defined(GENL_ID_PCMRAID)
246 case GENL_ID_PCMRAID
: return "pcmraid";
248 #if defined(GENL_ID_VFS_DQUOT)
249 case GENL_ID_VFS_DQUOT
: return "vfs dquot";
251 /* only dynamic family IDs should be used starting with Linux 4.10 */
252 default: return "dynamic";
256 static char *nlmsg_type2str(uint16_t proto
, uint16_t type
, char *buf
, int len
)
258 const char *name
= NULL
;
260 if (proto
== NETLINK_ROUTE
&& type
< RTM_MAX
)
261 name
= nlmsg_rtnl_type2str(type
);
262 else if (proto
== NETLINK_GENERIC
)
263 name
= nlmsg_genl_type2str(type
);
266 strncpy(buf
, name
, len
);
270 return nl_nlmsgtype2str(type
, buf
, len
);
273 static const char *addr_family2str(uint16_t family
)
276 case AF_INET
: return "ipv4";
277 case AF_INET6
: return "ipv6";
278 case AF_DECnet
: return "decnet";
279 case AF_IPX
: return "ipx";
280 default: return "Unknown";
284 static const char *addr2str(uint16_t af
, const void *addr
, char *buf
, int blen
)
286 if (af
== AF_INET
|| af
== AF_INET6
)
287 return inet_ntop(af
, addr
, buf
, blen
);
292 static const char *scope2str(uint8_t scope
)
295 case RT_SCOPE_UNIVERSE
: return "global";
296 case RT_SCOPE_LINK
: return "link";
297 case RT_SCOPE_HOST
: return "host";
298 case RT_SCOPE_NOWHERE
: return "nowhere";
300 default: return "Unknown";
304 static void rtnl_print_ifinfo(struct nlmsghdr
*hdr
)
306 struct ifinfomsg
*ifi
= NLMSG_DATA(hdr
);
307 struct rtattr
*attr
= IFLA_RTA(ifi
);
308 uint32_t attrs_len
= IFLA_PAYLOAD(hdr
);
310 char if_addr
[64] = {};
311 char *af_link
= "unknown";
313 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifi
)))
316 if (ifi
->ifi_family
== AF_UNSPEC
)
318 else if (ifi
->ifi_family
== AF_BRIDGE
)
321 tprintf(" [ Link Family %d (%s%s%s)", ifi
->ifi_family
,
322 colorize_start(bold
), af_link
, colorize_end());
323 tprintf(", Type %d (%s%s%s)", ifi
->ifi_type
,
324 colorize_start(bold
),
325 device_type2str(ifi
->ifi_type
),
327 tprintf(", Index %d", ifi
->ifi_index
);
328 tprintf(", Flags 0x%x (%s%s%s)", ifi
->ifi_flags
,
329 colorize_start(bold
),
330 rtnl_link_flags2str(ifi
->ifi_flags
, flags
,
333 tprintf(", Change 0x%x (%s%s%s) ]\n", ifi
->ifi_change
,
334 colorize_start(bold
),
335 rtnl_link_flags2str(ifi
->ifi_change
, flags
,
339 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
340 switch (attr
->rta_type
) {
342 rta_fmt(attr
, "Address %s",
343 device_addr2str(RTA_DATA(attr
),
344 RTA_LEN(attr
), ifi
->ifi_type
,
345 if_addr
, sizeof(if_addr
)));
348 rta_fmt(attr
, "Broadcast %s",
349 device_addr2str(RTA_DATA(attr
),
350 RTA_LEN(attr
), ifi
->ifi_type
,
351 if_addr
, sizeof(if_addr
)));
354 rta_fmt(attr
, "Name %s%s%s",
355 colorize_start(bold
), RTA_STR(attr
),
359 rta_fmt(attr
, "MTU %d", RTA_INT(attr
));
362 rta_fmt(attr
, "Link %d", RTA_INT(attr
));
365 rta_fmt(attr
, "QDisc %s", RTA_STR(attr
));
369 uint8_t st
= RTA_UINT8(attr
);
372 rta_fmt(attr
, "Operation state 0x%x (%s%s%s)",
374 colorize_start(bold
),
375 rtnl_link_operstate2str(st
,
376 states
, sizeof(states
)),
382 uint8_t mode
= RTA_UINT8(attr
);
385 rta_fmt(attr
, "Mode 0x%x (%s%s%s)", mode
,
386 colorize_start(bold
),
387 rtnl_link_mode2str(mode
, str
,
393 rta_fmt(attr
, "Group %d", RTA_INT(attr
));
396 rta_fmt(attr
, "Tx queue len %d", RTA_INT(attr
));
398 case IFLA_NET_NS_PID
:
399 rta_fmt(attr
, "Network namespace pid %d",
403 rta_fmt(attr
, "Network namespace fd %d", RTA_INT(attr
));
406 rta_fmt(attr
, "0x%x", attr
->rta_type
);
412 static void rtnl_print_ifaddr(struct nlmsghdr
*hdr
)
414 struct ifaddrmsg
*ifa
= NLMSG_DATA(hdr
);
415 uint32_t attrs_len
= IFA_PAYLOAD(hdr
);
416 struct rtattr
*attr
= IFA_RTA(ifa
);
417 struct ifa_cacheinfo
*ci
;
421 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
424 tprintf(" [ Address Family %d (%s%s%s)", ifa
->ifa_family
,
425 colorize_start(bold
),
426 addr_family2str(ifa
->ifa_family
),
428 tprintf(", Prefix Len %d", ifa
->ifa_prefixlen
);
429 tprintf(", Flags %d (%s%s%s)", ifa
->ifa_flags
,
430 colorize_start(bold
),
431 rtnl_addr_flags2str(ifa
->ifa_flags
, flags
,
434 tprintf(", Scope %d (%s%s%s)", ifa
->ifa_scope
,
435 colorize_start(bold
),
436 scope2str(ifa
->ifa_scope
),
438 tprintf(", Link Index %d ]\n", ifa
->ifa_index
);
440 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
441 switch (attr
->rta_type
) {
443 rta_fmt(attr
, "Local %s", addr2str(ifa
->ifa_family
,
444 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
447 rta_fmt(attr
, "Address %s", addr2str(ifa
->ifa_family
,
448 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
451 rta_fmt(attr
, "Broadcast %s",
452 addr2str(ifa
->ifa_family
,
453 RTA_DATA(attr
), addr_str
,
457 rta_fmt(attr
, "Multicast %s",
458 addr2str(ifa
->ifa_family
,
459 RTA_DATA(attr
), addr_str
,
463 rta_fmt(attr
, "Anycast %s", addr2str(ifa
->ifa_family
,
464 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
468 rta_fmt(attr
, "Flags %d (%s%s%s)", RTA_INT(attr
),
469 colorize_start(bold
),
470 rtnl_addr_flags2str(RTA_INT(attr
),
471 flags
, sizeof(flags
)),
476 rta_fmt(attr
, "Label %s", RTA_STR(attr
));
480 tprintf("\tA: Cache (");
482 if (ci
->ifa_valid
== INFINITY
)
483 tprintf("valid lft(forever)");
485 tprintf("valid lft(%us)", ci
->ifa_valid
);
487 if (ci
->ifa_prefered
== INFINITY
)
488 tprintf(", prefrd lft(forever)");
490 tprintf(", prefrd lft(%us)", ci
->ifa_prefered
);
492 tprintf(", created on(%.2fs)", (double)ci
->cstamp
/ 100);
493 tprintf(", updated on(%.2fs))", (double)ci
->cstamp
/ 100);
494 tprintf(", Len %d\n", RTA_LEN(attr
));
497 rta_fmt(attr
, "0x%x", attr
->rta_type
);
503 static const char *route_table2str(uint8_t table
)
506 case RT_TABLE_UNSPEC
: return "unspec";
507 case RT_TABLE_COMPAT
: return "compat";
508 case RT_TABLE_DEFAULT
: return "default";
509 case RT_TABLE_MAIN
: return "main";
510 case RT_TABLE_LOCAL
: return "local";
512 default: return "Unknown";
516 static const char *route_proto2str(uint8_t proto
)
519 case RTPROT_UNSPEC
: return "unspec";
520 case RTPROT_REDIRECT
: return "redirect";
521 case RTPROT_KERNEL
: return "kernel";
522 case RTPROT_BOOT
: return "boot";
523 case RTPROT_STATIC
: return "static";
524 case RTPROT_GATED
: return "gated";
525 case RTPROT_RA
: return "ra";
526 case RTPROT_MRT
: return "mrt";
527 case RTPROT_ZEBRA
: return "zebra";
528 case RTPROT_BIRD
: return "bird";
529 case RTPROT_DNROUTED
: return "DECnet";
530 case RTPROT_XORP
: return "xorp";
531 case RTPROT_NTK
: return "netsukuku";
532 case RTPROT_DHCP
: return "dhcpc";
533 #ifdef RTPROT_MROUTED
534 case RTPROT_MROUTED
: return "mrouted";
537 default: return "Unknown";
541 static const char *route_type2str(uint8_t type
)
544 case RTN_UNSPEC
: return "unspec";
545 case RTN_UNICAST
: return "unicast";
546 case RTN_LOCAL
: return "local";
547 case RTN_BROADCAST
: return "broadcast";
548 case RTN_ANYCAST
: return "anycast";
549 case RTN_MULTICAST
: return "multicast";
550 case RTN_BLACKHOLE
: return "blackhole";
551 case RTN_UNREACHABLE
: return "unreach";
552 case RTN_PROHIBIT
: return "prohibit";
553 case RTN_THROW
: return "throw";
554 case RTN_NAT
: return "nat";
555 case RTN_XRESOLVE
: return "xresolve";
556 default: return "Unknown";
560 static struct flag_name route_flags
[] = {
561 { "notify", RTM_F_NOTIFY
},
562 { "cloned", RTM_F_CLONED
},
563 { "equalize", RTM_F_EQUALIZE
},
564 { "prefix", RTM_F_PREFIX
},
565 { "dead", RTNH_F_DEAD
},
566 { "pervasive", RTNH_F_PERVASIVE
},
567 { "onlink", RTNH_F_ONLINK
},
571 static void rtnl_print_route(struct nlmsghdr
*hdr
)
573 struct rtmsg
*rtm
= NLMSG_DATA(hdr
);
574 uint32_t attrs_len
= RTM_PAYLOAD(hdr
);
575 struct rtattr
*attr
= RTM_RTA(rtm
);
576 struct rta_cacheinfo
*ci
;
577 int hz
= get_user_hz();
581 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*rtm
)))
584 tprintf(" [ Route Family %d (%s%s%s)", rtm
->rtm_family
,
585 colorize_start(bold
),
586 addr_family2str(rtm
->rtm_family
),
588 tprintf(", Dst Len %d", rtm
->rtm_dst_len
);
589 tprintf(", Src Len %d", rtm
->rtm_src_len
);
590 tprintf(", ToS %d", rtm
->rtm_tos
);
591 tprintf(", Table %d (%s%s%s)", rtm
->rtm_table
,
592 colorize_start(bold
),
593 route_table2str(rtm
->rtm_table
),
595 tprintf(", Proto %d (%s%s%s)", rtm
->rtm_protocol
,
596 colorize_start(bold
),
597 route_proto2str(rtm
->rtm_protocol
),
599 tprintf(", Scope %d (%s%s%s)", rtm
->rtm_scope
,
600 colorize_start(bold
),
601 scope2str(rtm
->rtm_scope
),
603 tprintf(", Type %d (%s%s%s)", rtm
->rtm_type
,
604 colorize_start(bold
),
605 route_type2str(rtm
->rtm_type
),
607 tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm
->rtm_flags
,
608 colorize_start(bold
),
609 flags2str(route_flags
, rtm
->rtm_flags
, flags
,
613 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
614 switch (attr
->rta_type
) {
616 rta_fmt(attr
, "Dst %s", addr2str(rtm
->rtm_family
,
617 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
620 rta_fmt(attr
, "Src %s", addr2str(rtm
->rtm_family
,
621 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
624 rta_fmt(attr
, "Iif %d", RTA_INT(attr
));
627 rta_fmt(attr
, "Oif %d", RTA_INT(attr
));
630 rta_fmt(attr
, "Gateway %s", addr2str(rtm
->rtm_family
,
631 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
634 rta_fmt(attr
, "Priority %u", RTA_UINT32(attr
));
637 rta_fmt(attr
, "Pref Src %s", addr2str(rtm
->rtm_family
,
638 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
640 #if defined(RTA_MARK)
642 rta_fmt(attr
, "Mark 0x%x", RTA_UINT(attr
));
646 rta_fmt(attr
, "Flow 0x%x", RTA_UINT(attr
));
649 rta_fmt(attr
, "Table %d (%s%s%s)", RTA_UINT32(attr
),
650 colorize_start(bold
),
651 route_table2str(RTA_UINT32(attr
)),
656 tprintf("\tA: Cache (");
657 tprintf("expires(%ds)", ci
->rta_expires
/ hz
);
658 tprintf(", error(%d)", ci
->rta_error
);
659 tprintf(", users(%d)", ci
->rta_clntref
);
660 tprintf(", used(%d)", ci
->rta_used
);
661 tprintf(", last use(%ds)", ci
->rta_lastuse
/ hz
);
662 tprintf(", id(%d)", ci
->rta_id
);
663 tprintf(", ts(%d)", ci
->rta_ts
);
664 tprintf(", ts age(%ds))", ci
->rta_tsage
);
665 tprintf(", Len %d\n", RTA_LEN(attr
));
668 rta_fmt(attr
, "0x%x", attr
->rta_type
);
674 static struct flag_name neigh_states
[] = {
675 { "incomplete", NUD_INCOMPLETE
},
676 { "reachable", NUD_REACHABLE
},
677 { "stale", NUD_STALE
},
678 { "delay", NUD_DELAY
},
679 { "probe", NUD_PROBE
},
680 { "failed", NUD_FAILED
},
681 { "noarp", NUD_NOARP
},
682 { "permanent", NUD_PERMANENT
},
683 { "none", NUD_NONE
},
687 /* Copied from linux/neighbour.h */
689 # define NTF_USE 0x01
692 # define NTF_SELF 0x02
695 # define NTF_MASTER 0x04
698 # define NTF_PROXY 0x08
700 #ifndef NTF_EXT_LEARNED
701 # define NTF_EXT_LEARNED 0x10
704 # define NTF_ROUTER 0x80
707 static struct flag_name neigh_flags
[] = {
709 { "self", NTF_SELF
},
710 { "master", NTF_MASTER
},
711 { "proxy", NTF_PROXY
},
712 { "ext learned", NTF_EXT_LEARNED
},
713 { "router", NTF_ROUTER
},
717 static void rtnl_print_neigh(struct nlmsghdr
*hdr
)
719 struct ndmsg
*ndm
= NLMSG_DATA(hdr
);
720 uint32_t attrs_len
= NDA_PAYLOAD(hdr
);
721 struct rtattr
*attr
= NDA_RTA(ndm
);
722 struct nda_cacheinfo
*ci
;
723 int hz
= get_user_hz();
729 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ndm
)))
732 tprintf(" [ Neigh Family %d (%s%s%s)", ndm
->ndm_family
,
733 colorize_start(bold
),
734 addr_family2str(ndm
->ndm_family
),
736 tprintf(", Link Index %d", ndm
->ndm_ifindex
);
737 tprintf(", State %d (%s%s%s)", ndm
->ndm_state
,
738 colorize_start(bold
),
739 flags2str(neigh_states
, ndm
->ndm_state
, states
,
742 tprintf(", Flags %d (%s%s%s)", ndm
->ndm_flags
,
743 colorize_start(bold
),
744 flags2str(neigh_flags
, ndm
->ndm_flags
, flags
,
747 tprintf(", Type %d (%s%s%s)", ndm
->ndm_type
,
748 colorize_start(bold
),
749 route_type2str(ndm
->ndm_type
),
753 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
754 switch (attr
->rta_type
) {
756 rta_fmt(attr
, "Address %s", addr2str(ndm
->ndm_family
,
757 RTA_DATA(attr
), addr_str
,
761 rta_fmt(attr
, "HW Address %s",
762 device_addr2str(RTA_DATA(attr
),
763 RTA_LEN(attr
), 0, hw_addr
,
767 rta_fmt(attr
, "Probes %d", RTA_UINT32(attr
));
771 tprintf("\tA: Cache (");
772 tprintf("confirmed(%ds)", ci
->ndm_confirmed
/ hz
);
773 tprintf(", used(%ds)", ci
->ndm_used
/ hz
);
774 tprintf(", updated(%ds)", ci
->ndm_updated
/ hz
);
775 tprintf(", refcnt(%d))", ci
->ndm_refcnt
);
776 tprintf(", Len %d\n", RTA_LEN(attr
));
779 rta_fmt(attr
, "0x%x", attr
->rta_type
);
785 static void rtnl_msg_print(struct nlmsghdr
*hdr
)
787 switch (hdr
->nlmsg_type
) {
792 rtnl_print_ifinfo(hdr
);
797 rtnl_print_ifaddr(hdr
);
802 rtnl_print_route(hdr
);
807 rtnl_print_neigh(hdr
);
812 static const char *genl_cmd2str(uint8_t table
)
815 case CTRL_CMD_UNSPEC
: return "unspec";
816 case CTRL_CMD_NEWFAMILY
: return "new family";
817 case CTRL_CMD_DELFAMILY
: return "del family";
818 case CTRL_CMD_GETFAMILY
: return "get family";
819 case CTRL_CMD_NEWOPS
: return "new ops";
820 case CTRL_CMD_DELOPS
: return "del ops";
821 case CTRL_CMD_GETOPS
: return "get ops";
822 case CTRL_CMD_NEWMCAST_GRP
: return "new mcast group";
823 case CTRL_CMD_DELMCAST_GRP
: return "del mcast group";
824 case CTRL_CMD_GETMCAST_GRP
: return "get mcast group";
826 default: return "Unknown";
830 static struct flag_name genl_ops_flags
[] = {
831 { "admin", GENL_ADMIN_PERM
},
832 { "doit", GENL_CMD_CAP_DO
},
833 { "dumpit", GENL_CMD_CAP_DUMP
},
834 { "policy", GENL_CMD_CAP_HASPOL
},
838 static void genl_print_ops_attr(struct nlattr
*attr
, uint32_t attr_len
)
843 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
844 switch (attr
->nla_type
) {
845 case CTRL_ATTR_OP_ID
:
846 nla_fmt_nested(attr
, "Id 0x%x", NLA_UINT32(attr
));
849 case CTRL_ATTR_OP_FLAGS
:
850 flags
= NLA_UINT32(attr
);
852 nla_fmt_nested(attr
, "Flags 0x%x (%s%s%s)", flags
,
853 colorize_start(bold
),
854 flags2str(genl_ops_flags
, flags
, str
, sizeof(str
)),
858 nla_fmt_nested(attr
, "0x%x", attr
->nla_type
);
864 static void genl_print_ops_list(struct nlattr
*attr
, uint32_t attr_len
)
866 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
867 nla_fmt_nested_start(attr
, "0x%x", attr
->nla_type
);
868 genl_print_ops_attr(NLA_DATA(attr
), NLA_LEN(attr
));
869 nla_fmt_nested_end();
873 static void genl_print_mcast_group(struct nlattr
*attr
, uint32_t attr_len
)
875 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
876 switch (attr
->nla_type
) {
877 case CTRL_ATTR_MCAST_GRP_ID
:
878 nla_fmt_nested(attr
, "Id 0x%x", NLA_UINT32(attr
));
881 case CTRL_ATTR_MCAST_GRP_NAME
:
882 nla_fmt_nested(attr
, "Name %s", NLA_STR(attr
));
885 nla_fmt_nested(attr
, "0x%x", attr
->nla_type
);
891 static void genl_print_mc_groups(struct nlattr
*attr
, uint32_t attr_len
)
893 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
894 nla_fmt_nested_start(attr
, "0x%x", attr
->nla_type
);
895 genl_print_mcast_group(NLA_DATA(attr
), NLA_LEN(attr
));
896 nla_fmt_nested_end();
900 static void genl_print_ctrl_attrs(struct nlmsghdr
*hdr
)
902 struct genlmsghdr
*genl
= NLMSG_DATA(hdr
);
903 struct nlattr
*attr
= GEN_NLA(genl
);
904 uint32_t attrs_len
= NLMSG_PAYLOAD(hdr
, sizeof(struct genlmsghdr
));
906 for (; NLA_OK(attr
, attrs_len
); attr
= NLA_NEXT(attr
, attrs_len
)) {
907 switch (attr
->nla_type
) {
908 case CTRL_ATTR_FAMILY_ID
:
909 nla_fmt(attr
, "Family Id 0x%x", NLA_UINT16(attr
));
911 case CTRL_ATTR_FAMILY_NAME
:
912 nla_fmt(attr
, "Family Name %s", NLA_STR(attr
));
914 case CTRL_ATTR_VERSION
:
915 nla_fmt(attr
, "Version %u", NLA_UINT32(attr
));
917 case CTRL_ATTR_HDRSIZE
:
918 nla_fmt(attr
, "Header size %u", NLA_UINT32(attr
));
920 case CTRL_ATTR_MAXATTR
:
921 nla_fmt(attr
, "Max attr value 0x%x", NLA_UINT32(attr
));
924 nla_fmt(attr
, "Ops list");
925 genl_print_ops_list(NLA_DATA(attr
), NLA_LEN(attr
));
927 case CTRL_ATTR_MCAST_GROUPS
:
928 nla_fmt(attr
, "Mcast groups");
929 genl_print_mc_groups(NLA_DATA(attr
), NLA_LEN(attr
));
932 nla_fmt(attr
, "0x%x", attr
->nla_type
);
938 static void genl_msg_print(struct nlmsghdr
*hdr
)
940 struct genlmsghdr
*genl
;
942 if (hdr
->nlmsg_type
!= GENL_ID_CTRL
) {
943 nlmsg_print_raw(hdr
);
947 genl
= NLMSG_DATA(hdr
);
949 tprintf(" [ Cmd %u (%s%s%s)", genl
->cmd
,
950 colorize_start(bold
), genl_cmd2str(genl
->cmd
), colorize_end());
951 tprintf(", Version %u", genl
->version
);
952 tprintf(", Reserved %u", genl
->reserved
);
955 genl_print_ctrl_attrs(hdr
);
958 static void nlmsg_print(uint16_t family
, struct nlmsghdr
*hdr
)
960 u16 nlmsg_flags
= hdr
->nlmsg_flags
;
963 char procname
[PATH_MAX
];
965 /* Look up the process name if message is not coming from the kernel.
967 * Note that the port id is not necessarily equal to the PID of the
968 * receiving process (e.g. if the application is multithreaded or using
969 * multiple sockets). In these cases we're not able to find a matching
970 * PID and the information will not be printed.
972 if (hdr
->nlmsg_pid
!= 0) {
973 if (proc_get_cmdline(hdr
->nlmsg_pid
, procname
, sizeof(procname
)) < 0)
974 snprintf(procname
, sizeof(procname
), "unknown process");
976 snprintf(procname
, sizeof(procname
), "kernel");
978 tprintf(" [ NLMSG ");
979 tprintf("Family %d (%s%s%s), ", family
,
980 colorize_start(bold
),
981 nlmsg_family2str(family
),
983 tprintf("Len %u, ", hdr
->nlmsg_len
);
984 tprintf("Type 0x%.4x (%s%s%s), ", hdr
->nlmsg_type
,
985 colorize_start(bold
),
986 nlmsg_type2str(family
, hdr
->nlmsg_type
, type
, sizeof(type
)),
988 tprintf("Flags 0x%.4x (%s%s%s), ", nlmsg_flags
,
989 colorize_start(bold
),
990 nlmsg_flags
? nl_nlmsg_flags2str(nlmsg_flags
, flags
, sizeof(flags
)) : "none",
992 tprintf("Seq-Nr %u, ", hdr
->nlmsg_seq
);
993 tprintf("PID %u", hdr
->nlmsg_pid
);
995 tprintf(" (%s%s%s)", colorize_start(bold
), basename(procname
),
1001 rtnl_msg_print(hdr
);
1003 case NETLINK_GENERIC
:
1004 genl_msg_print(hdr
);
1007 nlmsg_print_raw(hdr
);
1011 static void nlmsg(struct pkt_buff
*pkt
)
1013 struct nlmsghdr
*hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1014 unsigned int trim_len
= pkt_len(pkt
);
1017 trim_len
-= hdr
->nlmsg_len
;
1018 nlmsg_print(ntohs(pkt
->sll
->sll_protocol
), hdr
);
1020 if (!pkt_pull(pkt
, NLMSG_ALIGN(hdr
->nlmsg_len
) - NLMSG_HDRLEN
))
1023 hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1026 if (hdr
->nlmsg_len
== 0)
1029 if (hdr
->nlmsg_type
!= NLMSG_DONE
&&
1030 (hdr
->nlmsg_flags
& NLM_F_MULTI
))
1034 /* mmaped packet? */
1035 if (hdr
&& hdr
->nlmsg_len
== 0)
1036 pkt_trim(pkt
, trim_len
);
1039 static void nlmsg_less(struct pkt_buff
*pkt
)
1041 struct nlmsghdr
*hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1042 uint16_t family
= ntohs(pkt
->sll
->sll_protocol
);
1048 tprintf(" NLMSG Family %d (%s%s%s), ", family
,
1049 colorize_start(bold
),
1050 nlmsg_family2str(family
),
1052 tprintf("Type %u (%s%s%s)", hdr
->nlmsg_type
,
1053 colorize_start(bold
),
1054 nlmsg_type2str(family
, hdr
->nlmsg_type
, type
, sizeof(type
)),
1058 struct protocol nlmsg_ops
= {
1059 .print_full
= nlmsg
,
1060 .print_less
= nlmsg_less
,