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 <linux/if_arp.h>
16 #include <arpa/inet.h>
25 #define INFINITY 0xFFFFFFFFU
27 #define RTA_LEN(attr) ((int)RTA_PAYLOAD(attr))
28 #define RTA_INT(attr) (*(int *)RTA_DATA(attr))
29 #define RTA_UINT(attr) (*(unsigned int *)RTA_DATA(attr))
30 #define RTA_UINT8(attr) (*(uint8_t *)RTA_DATA(attr))
31 #define RTA_UINT32(attr) (*(uint32_t *)RTA_DATA(attr))
32 #define RTA_STR(attr) ((char *)RTA_DATA(attr))
36 ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
40 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
44 #define NLA_LENGTH(len) (NLA_ALIGN(sizeof(struct nlattr)) + (len))
48 #define NLA_DATA(nla) ((void*)(((char*)(nla)) + NLA_LENGTH(0)))
52 #define NLA_PAYLOAD(nla) ((int)((nla)->nla_len) - NLA_LENGTH(0))
55 #define NLA_LEN(attr) ((int)NLA_PAYLOAD(attr))
56 #define NLA_INT(attr) (*(int *)NLA_DATA(attr))
57 #define NLA_UINT(attr) (*(unsigned int *)NLA_DATA(attr))
58 #define NLA_UINT8(attr) (*(uint8_t *)NLA_DATA(attr))
59 #define NLA_UINT16(attr) (*(uint16_t *)NLA_DATA(attr))
60 #define NLA_UINT32(attr) (*(uint32_t *)NLA_DATA(attr))
61 #define NLA_STR(attr) ((char *)NLA_DATA(attr))
64 #define GEN_NLA(n) ((struct nlattr*)(((char*)(n)) + GENL_HDRLEN))
68 #define NLA_OK(nla,len) \
69 ((len) >= (int)sizeof(struct nlattr) && \
70 (nla)->nla_len >= sizeof(struct nlattr) && \
71 (nla)->nla_len <= (len))
75 #define NLA_NEXT(nla,attrlen) \
76 ((attrlen) -= NLA_ALIGN((nla)->nla_len), \
77 (struct nlattr*)(((char*)(nla)) + NLA_ALIGN((nla)->nla_len)))
80 #define rta_fmt(attr, fmt, ...) \
81 tprintf("\tA: "fmt, ##__VA_ARGS__); \
82 tprintf(", Len %d\n", RTA_LEN(attr));
84 #define nla_fmt(attr, fmt, ...) \
85 tprintf("\tA: "fmt, ##__VA_ARGS__); \
86 tprintf(", Len %d\n", NLA_LEN(attr));
88 #define nla_fmt_nested(attr, fmt, ...) \
89 tprintf("[ "fmt, ##__VA_ARGS__); \
90 tprintf(", Len %d] ", NLA_LEN(attr));
92 #define nla_fmt_nested_start(attr, fmt, ...) \
93 tprintf("\t A: "fmt, ##__VA_ARGS__); \
94 tprintf(", Len %d ", NLA_LEN(attr));
96 #define nla_fmt_nested_end() tprintf("\n")
103 static const char *flags2str(struct flag_name
*tbl
, unsigned int flags
,
106 int bits_stay
= flags
;
110 for (; tbl
&& tbl
->name
; tbl
++) {
111 if (!(tbl
->flag
& flags
))
114 bits_stay
&= ~tbl
->flag
;
115 strncat(buf
, tbl
->name
, len
- strlen(buf
) - 1);
117 if (bits_stay
& flags
)
118 strncat(buf
, ",", len
- strlen(buf
) - 1);
124 static void nlmsg_print_raw(struct nlmsghdr
*hdr
)
126 u32 len
= hdr
->nlmsg_len
;
129 _ascii((uint8_t *) hdr
+ NLMSG_HDRLEN
, len
- NLMSG_HDRLEN
);
130 _hex((uint8_t *) hdr
+ NLMSG_HDRLEN
, len
- NLMSG_HDRLEN
);
134 static const char *nlmsg_family2str(uint16_t family
)
137 case NETLINK_ROUTE
: return "routing";
138 case NETLINK_UNUSED
: return "unused";
139 case NETLINK_USERSOCK
: return "user-mode socket";
140 case NETLINK_FIREWALL
: return "unused, formerly ip_queue";
141 /* NETLINK_INET_DIAG was renamed to NETLINK_SOCK_DIAG in Linux kernel 3.10 */
142 #if defined(NETLINK_SOCK_DIAG)
143 case NETLINK_SOCK_DIAG
: return "socket monitoring";
144 #elif defined(NETLINK_INET_DIAG)
145 case NETLINK_INET_DIAG
: return "INET socket monitoring";
147 case NETLINK_NFLOG
: return "netfilter ULOG";
148 case NETLINK_XFRM
: return "IPsec";
149 case NETLINK_SELINUX
: return "SELinux event notification";
150 case NETLINK_ISCSI
: return "Open-iSCSI";
151 case NETLINK_AUDIT
: return "auditing";
152 case NETLINK_FIB_LOOKUP
: return "FIB lookup";
153 case NETLINK_CONNECTOR
: return "Kernel connector";
154 case NETLINK_NETFILTER
: return "Netfilter";
155 case NETLINK_IP6_FW
: return "unused, formerly ip6_queue";
156 case NETLINK_DNRTMSG
: return "DECnet routing";
157 case NETLINK_KOBJECT_UEVENT
: return "Kernel messages";
158 case NETLINK_GENERIC
: return "Generic";
159 case NETLINK_SCSITRANSPORT
: return "SCSI transports";
160 case NETLINK_ECRYPTFS
: return "ecryptfs";
161 case NETLINK_RDMA
: return "RDMA";
162 case NETLINK_CRYPTO
: return "Crypto layer";
163 default: return "Unknown";
167 static const char *nlmsg_rtnl_type2str(uint16_t type
)
170 case RTM_NEWLINK
: return "new link";
171 case RTM_DELLINK
: return "del link";
172 case RTM_GETLINK
: return "get link";
173 case RTM_SETLINK
: return "set link";
175 case RTM_NEWADDR
: return "new addr";
176 case RTM_DELADDR
: return "del addr";
177 case RTM_GETADDR
: return "get addr";
179 case RTM_NEWROUTE
: return "new route";
180 case RTM_DELROUTE
: return "del route";
181 case RTM_GETROUTE
: return "get route";
183 case RTM_NEWNEIGH
: return "new neigh";
184 case RTM_DELNEIGH
: return "del neigh";
185 case RTM_GETNEIGH
: return "get neigh";
187 case RTM_NEWRULE
: return "new rule";
188 case RTM_DELRULE
: return "del rule";
189 case RTM_GETRULE
: return "get rule";
191 case RTM_NEWQDISC
: return "new tc qdisc";
192 case RTM_DELQDISC
: return "del tc qdisc";
193 case RTM_GETQDISC
: return "get tc qdisc";
195 case RTM_NEWTCLASS
: return "new tc class";
196 case RTM_DELTCLASS
: return "del tc class";
197 case RTM_GETTCLASS
: return "get tc class";
199 case RTM_NEWTFILTER
: return "new tc filter";
200 case RTM_DELTFILTER
: return "del tc filter";
201 case RTM_GETTFILTER
: return "get tc filter";
203 case RTM_NEWACTION
: return "new tc action";
204 case RTM_DELACTION
: return "del tc action";
205 case RTM_GETACTION
: return "get tc action";
207 case RTM_NEWPREFIX
: return "new prefix";
209 case RTM_GETMULTICAST
: return "get mcast addr";
211 case RTM_GETANYCAST
: return "get anycast addr";
213 case RTM_NEWNEIGHTBL
: return "new neigh table";
214 case RTM_GETNEIGHTBL
: return "get neigh table";
215 case RTM_SETNEIGHTBL
: return "set neigh table";
217 case RTM_NEWNDUSEROPT
: return "new ndisc user option";
219 case RTM_NEWADDRLABEL
: return "new addr label";
220 case RTM_DELADDRLABEL
: return "del addr label";
221 case RTM_GETADDRLABEL
: return "get addr label";
223 case RTM_GETDCB
: return "get data-center-bridge";
224 case RTM_SETDCB
: return "set data-center-bridge";
226 #if defined(RTM_NEWNETCONF)
227 case RTM_NEWNETCONF
: return "new netconf";
228 case RTM_GETNETCONF
: return "get netconf";
231 #if defined(RTM_NEWMDB)
232 case RTM_NEWMDB
: return "new bridge mdb";
233 case RTM_DELMDB
: return "del bridge mdb";
234 case RTM_GETMDB
: return "get bridge mdb";
236 default: return NULL
;
240 static const char *nlmsg_genl_type2str(uint16_t type
)
243 case GENL_ID_GENERATE
: return "id gen";
244 case GENL_ID_CTRL
: return "id ctrl";
245 default: return NULL
;
249 static char *nlmsg_type2str(uint16_t proto
, uint16_t type
, char *buf
, int len
)
251 const char *name
= NULL
;
253 if (proto
== NETLINK_ROUTE
&& type
< RTM_MAX
)
254 name
= nlmsg_rtnl_type2str(type
);
255 else if (proto
== NETLINK_GENERIC
)
256 name
= nlmsg_genl_type2str(type
);
259 strncpy(buf
, name
, len
);
263 return nl_nlmsgtype2str(type
, buf
, len
);
266 static const char *addr_family2str(uint16_t family
)
269 case AF_INET
: return "ipv4";
270 case AF_INET6
: return "ipv6";
271 case AF_DECnet
: return "decnet";
272 case AF_IPX
: return "ipx";
273 default: return "Unknown";
277 static const char *addr2str(uint16_t af
, const void *addr
, char *buf
, int blen
)
279 if (af
== AF_INET
|| af
== AF_INET6
)
280 return inet_ntop(af
, addr
, buf
, blen
);
285 static const char *scope2str(uint8_t scope
)
288 case RT_SCOPE_UNIVERSE
: return "global";
289 case RT_SCOPE_LINK
: return "link";
290 case RT_SCOPE_HOST
: return "host";
291 case RT_SCOPE_NOWHERE
: return "nowhere";
293 default: return "Unknown";
297 static void rtnl_print_ifinfo(struct nlmsghdr
*hdr
)
299 struct ifinfomsg
*ifi
= NLMSG_DATA(hdr
);
300 struct rtattr
*attr
= IFLA_RTA(ifi
);
301 uint32_t attrs_len
= IFLA_PAYLOAD(hdr
);
303 char if_addr
[64] = {};
304 char *af_link
= "unknown";
306 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifi
)))
309 if (ifi
->ifi_family
== AF_UNSPEC
)
311 else if (ifi
->ifi_family
== AF_BRIDGE
)
314 tprintf(" [ Link Family %d (%s%s%s)", ifi
->ifi_family
,
315 colorize_start(bold
), af_link
, colorize_end());
316 tprintf(", Type %d (%s%s%s)", ifi
->ifi_type
,
317 colorize_start(bold
),
318 device_type2str(ifi
->ifi_type
),
320 tprintf(", Index %d", ifi
->ifi_index
);
321 tprintf(", Flags 0x%x (%s%s%s)", ifi
->ifi_flags
,
322 colorize_start(bold
),
323 rtnl_link_flags2str(ifi
->ifi_flags
, flags
,
326 tprintf(", Change 0x%x (%s%s%s) ]\n", ifi
->ifi_change
,
327 colorize_start(bold
),
328 rtnl_link_flags2str(ifi
->ifi_change
, flags
,
332 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
333 switch (attr
->rta_type
) {
335 rta_fmt(attr
, "Address %s",
336 device_addr2str(RTA_DATA(attr
),
337 RTA_LEN(attr
), ifi
->ifi_type
,
338 if_addr
, sizeof(if_addr
)));
341 rta_fmt(attr
, "Broadcast %s",
342 device_addr2str(RTA_DATA(attr
),
343 RTA_LEN(attr
), ifi
->ifi_type
,
344 if_addr
, sizeof(if_addr
)));
347 rta_fmt(attr
, "Name %s%s%s",
348 colorize_start(bold
), RTA_STR(attr
),
352 rta_fmt(attr
, "MTU %d", RTA_INT(attr
));
355 rta_fmt(attr
, "Link %d", RTA_INT(attr
));
358 rta_fmt(attr
, "QDisc %s", RTA_STR(attr
));
362 uint8_t st
= RTA_UINT8(attr
);
365 rta_fmt(attr
, "Operation state 0x%x (%s%s%s)",
367 colorize_start(bold
),
368 rtnl_link_operstate2str(st
,
369 states
, sizeof(states
)),
375 uint8_t mode
= RTA_UINT8(attr
);
378 rta_fmt(attr
, "Mode 0x%x (%s%s%s)", mode
,
379 colorize_start(bold
),
380 rtnl_link_mode2str(mode
, str
,
386 rta_fmt(attr
, "Group %d", RTA_INT(attr
));
389 rta_fmt(attr
, "Tx queue len %d", RTA_INT(attr
));
391 case IFLA_NET_NS_PID
:
392 rta_fmt(attr
, "Network namespace pid %d",
396 rta_fmt(attr
, "Network namespace fd %d", RTA_INT(attr
));
399 rta_fmt(attr
, "0x%x", attr
->rta_type
);
405 static void rtnl_print_ifaddr(struct nlmsghdr
*hdr
)
407 struct ifaddrmsg
*ifa
= NLMSG_DATA(hdr
);
408 uint32_t attrs_len
= IFA_PAYLOAD(hdr
);
409 struct rtattr
*attr
= IFA_RTA(ifa
);
410 struct ifa_cacheinfo
*ci
;
414 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ifa
)))
417 tprintf(" [ Address Family %d (%s%s%s)", ifa
->ifa_family
,
418 colorize_start(bold
),
419 addr_family2str(ifa
->ifa_family
),
421 tprintf(", Prefix Len %d", ifa
->ifa_prefixlen
);
422 tprintf(", Flags %d (%s%s%s)", ifa
->ifa_flags
,
423 colorize_start(bold
),
424 rtnl_addr_flags2str(ifa
->ifa_flags
, flags
,
427 tprintf(", Scope %d (%s%s%s)", ifa
->ifa_scope
,
428 colorize_start(bold
),
429 scope2str(ifa
->ifa_scope
),
431 tprintf(", Link Index %d ]\n", ifa
->ifa_index
);
433 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
434 switch (attr
->rta_type
) {
436 rta_fmt(attr
, "Local %s", addr2str(ifa
->ifa_family
,
437 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
440 rta_fmt(attr
, "Address %s", addr2str(ifa
->ifa_family
,
441 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
444 rta_fmt(attr
, "Broadcast %s",
445 addr2str(ifa
->ifa_family
,
446 RTA_DATA(attr
), addr_str
,
450 rta_fmt(attr
, "Multicast %s",
451 addr2str(ifa
->ifa_family
,
452 RTA_DATA(attr
), addr_str
,
456 rta_fmt(attr
, "Anycast %s", addr2str(ifa
->ifa_family
,
457 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
461 rta_fmt(attr
, "Flags %d (%s%s%s)", RTA_INT(attr
),
462 colorize_start(bold
),
463 rtnl_addr_flags2str(RTA_INT(attr
),
464 flags
, sizeof(flags
)),
469 rta_fmt(attr
, "Label %s", RTA_STR(attr
));
473 tprintf("\tA: Cache (");
475 if (ci
->ifa_valid
== INFINITY
)
476 tprintf("valid lft(forever)");
478 tprintf("valid lft(%us)", ci
->ifa_valid
);
480 if (ci
->ifa_prefered
== INFINITY
)
481 tprintf(", prefrd lft(forever)");
483 tprintf(", prefrd lft(%us)", ci
->ifa_prefered
);
485 tprintf(", created on(%.2fs)", (double)ci
->cstamp
/ 100);
486 tprintf(", updated on(%.2fs))", (double)ci
->cstamp
/ 100);
487 tprintf(", Len %d\n", RTA_LEN(attr
));
490 rta_fmt(attr
, "0x%x", attr
->rta_type
);
496 static const char *route_table2str(uint8_t table
)
499 case RT_TABLE_UNSPEC
: return "unspec";
500 case RT_TABLE_COMPAT
: return "compat";
501 case RT_TABLE_DEFAULT
: return "default";
502 case RT_TABLE_MAIN
: return "main";
503 case RT_TABLE_LOCAL
: return "local";
505 default: return "Unknown";
509 static const char *route_proto2str(uint8_t proto
)
512 case RTPROT_UNSPEC
: return "unspec";
513 case RTPROT_REDIRECT
: return "redirect";
514 case RTPROT_KERNEL
: return "kernel";
515 case RTPROT_BOOT
: return "boot";
516 case RTPROT_STATIC
: return "static";
517 case RTPROT_GATED
: return "gated";
518 case RTPROT_RA
: return "ra";
519 case RTPROT_MRT
: return "mrt";
520 case RTPROT_ZEBRA
: return "zebra";
521 case RTPROT_BIRD
: return "bird";
522 case RTPROT_DNROUTED
: return "DECnet";
523 case RTPROT_XORP
: return "xorp";
524 case RTPROT_NTK
: return "netsukuku";
525 case RTPROT_DHCP
: return "dhcpc";
526 #ifdef RTPROT_MROUTED
527 case RTPROT_MROUTED
: return "mrouted";
530 default: return "Unknown";
534 static const char *route_type2str(uint8_t type
)
537 case RTN_UNSPEC
: return "unspec";
538 case RTN_UNICAST
: return "unicast";
539 case RTN_LOCAL
: return "local";
540 case RTN_BROADCAST
: return "broadcast";
541 case RTN_ANYCAST
: return "anycast";
542 case RTN_MULTICAST
: return "multicast";
543 case RTN_BLACKHOLE
: return "blackhole";
544 case RTN_UNREACHABLE
: return "unreach";
545 case RTN_PROHIBIT
: return "prohibit";
546 case RTN_THROW
: return "throw";
547 case RTN_NAT
: return "nat";
548 case RTN_XRESOLVE
: return "xresolve";
549 default: return "Unknown";
553 static struct flag_name route_flags
[] = {
554 { "notify", RTM_F_NOTIFY
},
555 { "cloned", RTM_F_CLONED
},
556 { "equalize", RTM_F_EQUALIZE
},
557 { "prefix", RTM_F_PREFIX
},
558 { "dead", RTNH_F_DEAD
},
559 { "pervasive", RTNH_F_PERVASIVE
},
560 { "onlink", RTNH_F_ONLINK
},
564 static void rtnl_print_route(struct nlmsghdr
*hdr
)
566 struct rtmsg
*rtm
= NLMSG_DATA(hdr
);
567 uint32_t attrs_len
= RTM_PAYLOAD(hdr
);
568 struct rtattr
*attr
= RTM_RTA(rtm
);
569 struct rta_cacheinfo
*ci
;
570 int hz
= get_user_hz();
574 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*rtm
)))
577 tprintf(" [ Route Family %d (%s%s%s)", rtm
->rtm_family
,
578 colorize_start(bold
),
579 addr_family2str(rtm
->rtm_family
),
581 tprintf(", Dst Len %d", rtm
->rtm_dst_len
);
582 tprintf(", Src Len %d", rtm
->rtm_src_len
);
583 tprintf(", ToS %d", rtm
->rtm_tos
);
584 tprintf(", Table %d (%s%s%s)", rtm
->rtm_table
,
585 colorize_start(bold
),
586 route_table2str(rtm
->rtm_table
),
588 tprintf(", Proto %d (%s%s%s)", rtm
->rtm_protocol
,
589 colorize_start(bold
),
590 route_proto2str(rtm
->rtm_protocol
),
592 tprintf(", Scope %d (%s%s%s)", rtm
->rtm_scope
,
593 colorize_start(bold
),
594 scope2str(rtm
->rtm_scope
),
596 tprintf(", Type %d (%s%s%s)", rtm
->rtm_type
,
597 colorize_start(bold
),
598 route_type2str(rtm
->rtm_type
),
600 tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm
->rtm_flags
,
601 colorize_start(bold
),
602 flags2str(route_flags
, rtm
->rtm_flags
, flags
,
606 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
607 switch (attr
->rta_type
) {
609 rta_fmt(attr
, "Dst %s", addr2str(rtm
->rtm_family
,
610 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
613 rta_fmt(attr
, "Src %s", addr2str(rtm
->rtm_family
,
614 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
617 rta_fmt(attr
, "Iif %d", RTA_INT(attr
));
620 rta_fmt(attr
, "Oif %d", RTA_INT(attr
));
623 rta_fmt(attr
, "Gateway %s", addr2str(rtm
->rtm_family
,
624 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
627 rta_fmt(attr
, "Priority %u", RTA_UINT32(attr
));
630 rta_fmt(attr
, "Pref Src %s", addr2str(rtm
->rtm_family
,
631 RTA_DATA(attr
), addr_str
, sizeof(addr_str
)));
634 rta_fmt(attr
, "Mark 0x%x", RTA_UINT(attr
));
637 rta_fmt(attr
, "Flow 0x%x", RTA_UINT(attr
));
640 rta_fmt(attr
, "Table %d (%s%s%s)", RTA_UINT32(attr
),
641 colorize_start(bold
),
642 route_table2str(RTA_UINT32(attr
)),
647 tprintf("\tA: Cache (");
648 tprintf("expires(%ds)", ci
->rta_expires
/ hz
);
649 tprintf(", error(%d)", ci
->rta_error
);
650 tprintf(", users(%d)", ci
->rta_clntref
);
651 tprintf(", used(%d)", ci
->rta_used
);
652 tprintf(", last use(%ds)", ci
->rta_lastuse
/ hz
);
653 tprintf(", id(%d)", ci
->rta_id
);
654 tprintf(", ts(%d)", ci
->rta_ts
);
655 tprintf(", ts age(%ds))", ci
->rta_tsage
);
656 tprintf(", Len %d\n", RTA_LEN(attr
));
659 rta_fmt(attr
, "0x%x", attr
->rta_type
);
665 static struct flag_name neigh_states
[] = {
666 { "incomplete", NUD_INCOMPLETE
},
667 { "reachable", NUD_REACHABLE
},
668 { "stale", NUD_STALE
},
669 { "delay", NUD_DELAY
},
670 { "probe", NUD_PROBE
},
671 { "failed", NUD_FAILED
},
672 { "noarp", NUD_NOARP
},
673 { "permanent", NUD_PERMANENT
},
674 { "none", NUD_NONE
},
678 /* Copied from linux/neighbour.h */
680 # define NTF_USE 0x01
683 # define NTF_SELF 0x02
686 # define NTF_MASTER 0x04
689 # define NTF_PROXY 0x08
691 #ifndef NTF_EXT_LEARNED
692 # define NTF_EXT_LEARNED 0x10
695 # define NTF_ROUTER 0x80
698 static struct flag_name neigh_flags
[] = {
700 { "self", NTF_SELF
},
701 { "master", NTF_MASTER
},
702 { "proxy", NTF_PROXY
},
703 { "ext learned", NTF_EXT_LEARNED
},
704 { "router", NTF_ROUTER
},
708 static void rtnl_print_neigh(struct nlmsghdr
*hdr
)
710 struct ndmsg
*ndm
= NLMSG_DATA(hdr
);
711 uint32_t attrs_len
= NDA_PAYLOAD(hdr
);
712 struct rtattr
*attr
= NDA_RTA(ndm
);
713 struct nda_cacheinfo
*ci
;
714 int hz
= get_user_hz();
720 if (hdr
->nlmsg_len
< NLMSG_LENGTH(sizeof(*ndm
)))
723 tprintf(" [ Neigh Family %d (%s%s%s)", ndm
->ndm_family
,
724 colorize_start(bold
),
725 addr_family2str(ndm
->ndm_family
),
727 tprintf(", Link Index %d", ndm
->ndm_ifindex
);
728 tprintf(", State %d (%s%s%s)", ndm
->ndm_state
,
729 colorize_start(bold
),
730 flags2str(neigh_states
, ndm
->ndm_state
, states
,
733 tprintf(", Flags %d (%s%s%s)", ndm
->ndm_flags
,
734 colorize_start(bold
),
735 flags2str(neigh_flags
, ndm
->ndm_flags
, flags
,
738 tprintf(", Type %d (%s%s%s)", ndm
->ndm_type
,
739 colorize_start(bold
),
740 route_type2str(ndm
->ndm_type
),
744 for (; RTA_OK(attr
, attrs_len
); attr
= RTA_NEXT(attr
, attrs_len
)) {
745 switch (attr
->rta_type
) {
747 rta_fmt(attr
, "Address %s", addr2str(ndm
->ndm_family
,
748 RTA_DATA(attr
), addr_str
,
752 rta_fmt(attr
, "HW Address %s",
753 device_addr2str(RTA_DATA(attr
),
754 RTA_LEN(attr
), 0, hw_addr
,
758 rta_fmt(attr
, "Probes %d", RTA_UINT32(attr
));
762 tprintf("\tA: Cache (");
763 tprintf("confirmed(%ds)", ci
->ndm_confirmed
/ hz
);
764 tprintf(", used(%ds)", ci
->ndm_used
/ hz
);
765 tprintf(", updated(%ds)", ci
->ndm_updated
/ hz
);
766 tprintf(", refcnt(%d))", ci
->ndm_refcnt
);
767 tprintf(", Len %d\n", RTA_LEN(attr
));
770 rta_fmt(attr
, "0x%x", attr
->rta_type
);
776 static void rtnl_msg_print(struct nlmsghdr
*hdr
)
778 switch (hdr
->nlmsg_type
) {
783 rtnl_print_ifinfo(hdr
);
788 rtnl_print_ifaddr(hdr
);
793 rtnl_print_route(hdr
);
798 rtnl_print_neigh(hdr
);
803 static const char *genl_cmd2str(uint8_t table
)
806 case CTRL_CMD_UNSPEC
: return "unspec";
807 case CTRL_CMD_NEWFAMILY
: return "new family";
808 case CTRL_CMD_DELFAMILY
: return "del family";
809 case CTRL_CMD_GETFAMILY
: return "get family";
810 case CTRL_CMD_NEWOPS
: return "new ops";
811 case CTRL_CMD_DELOPS
: return "del ops";
812 case CTRL_CMD_GETOPS
: return "get ops";
813 case CTRL_CMD_NEWMCAST_GRP
: return "new mcast group";
814 case CTRL_CMD_DELMCAST_GRP
: return "del mcast group";
815 case CTRL_CMD_GETMCAST_GRP
: return "get mcast group";
817 default: return "Unknown";
821 static struct flag_name genl_ops_flags
[] = {
822 { "admin", GENL_ADMIN_PERM
},
823 { "doit", GENL_CMD_CAP_DO
},
824 { "dumpit", GENL_CMD_CAP_DUMP
},
825 { "policy", GENL_CMD_CAP_HASPOL
},
829 static void genl_print_ops_attr(struct nlattr
*attr
, uint32_t attr_len
)
834 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
835 switch (attr
->nla_type
) {
836 case CTRL_ATTR_OP_ID
:
837 nla_fmt_nested(attr
, "Id 0x%x", NLA_UINT32(attr
));
840 case CTRL_ATTR_OP_FLAGS
:
841 flags
= NLA_UINT32(attr
);
843 nla_fmt_nested(attr
, "Flags 0x%x (%s%s%s)", flags
,
844 colorize_start(bold
),
845 flags2str(genl_ops_flags
, flags
, str
, sizeof(str
)),
849 nla_fmt_nested(attr
, "0x%x", attr
->nla_type
);
855 static void genl_print_ops_list(struct nlattr
*attr
, uint32_t attr_len
)
857 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
858 nla_fmt_nested_start(attr
, "0x%x", attr
->nla_type
);
859 genl_print_ops_attr(NLA_DATA(attr
), NLA_LEN(attr
));
860 nla_fmt_nested_end();
864 static void genl_print_mcast_group(struct nlattr
*attr
, uint32_t attr_len
)
866 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
867 switch (attr
->nla_type
) {
868 case CTRL_ATTR_MCAST_GRP_ID
:
869 nla_fmt_nested(attr
, "Id 0x%x", NLA_UINT32(attr
));
872 case CTRL_ATTR_MCAST_GRP_NAME
:
873 nla_fmt_nested(attr
, "Name %s", NLA_STR(attr
));
876 nla_fmt_nested(attr
, "0x%x", attr
->nla_type
);
882 static void genl_print_mc_groups(struct nlattr
*attr
, uint32_t attr_len
)
884 for (; NLA_OK(attr
, attr_len
); attr
= NLA_NEXT(attr
, attr_len
)) {
885 nla_fmt_nested_start(attr
, "0x%x", attr
->nla_type
);
886 genl_print_mcast_group(NLA_DATA(attr
), NLA_LEN(attr
));
887 nla_fmt_nested_end();
891 static void genl_print_ctrl_attrs(struct nlmsghdr
*hdr
)
893 struct genlmsghdr
*genl
= NLMSG_DATA(hdr
);
894 struct nlattr
*attr
= GEN_NLA(genl
);
895 uint32_t attrs_len
= NLMSG_PAYLOAD(hdr
, sizeof(struct genlmsghdr
));
897 for (; NLA_OK(attr
, attrs_len
); attr
= NLA_NEXT(attr
, attrs_len
)) {
898 switch (attr
->nla_type
) {
899 case CTRL_ATTR_FAMILY_ID
:
900 nla_fmt(attr
, "Family Id 0x%x", NLA_UINT16(attr
));
902 case CTRL_ATTR_FAMILY_NAME
:
903 nla_fmt(attr
, "Family Name %s", NLA_STR(attr
));
905 case CTRL_ATTR_VERSION
:
906 nla_fmt(attr
, "Version %u", NLA_UINT32(attr
));
908 case CTRL_ATTR_HDRSIZE
:
909 nla_fmt(attr
, "Header size %u", NLA_UINT32(attr
));
911 case CTRL_ATTR_MAXATTR
:
912 nla_fmt(attr
, "Max attr value 0x%x", NLA_UINT32(attr
));
915 nla_fmt(attr
, "Ops list");
916 genl_print_ops_list(NLA_DATA(attr
), NLA_LEN(attr
));
918 case CTRL_ATTR_MCAST_GROUPS
:
919 nla_fmt(attr
, "Mcast groups");
920 genl_print_mc_groups(NLA_DATA(attr
), NLA_LEN(attr
));
923 nla_fmt(attr
, "0x%x", attr
->nla_type
);
929 static void genl_msg_print(struct nlmsghdr
*hdr
)
931 struct genlmsghdr
*genl
;
933 if (hdr
->nlmsg_type
!= GENL_ID_CTRL
) {
934 nlmsg_print_raw(hdr
);
938 genl
= NLMSG_DATA(hdr
);
940 tprintf(" [ Cmd %u (%s%s%s)", genl
->cmd
,
941 colorize_start(bold
), genl_cmd2str(genl
->cmd
), colorize_end());
942 tprintf(", Version %u", genl
->version
);
943 tprintf(", Reserved %u", genl
->reserved
);
946 genl_print_ctrl_attrs(hdr
);
949 static void nlmsg_print(uint16_t family
, struct nlmsghdr
*hdr
)
951 u16 nlmsg_flags
= hdr
->nlmsg_flags
;
954 char procname
[PATH_MAX
];
956 /* Look up the process name if message is not coming from the kernel.
958 * Note that the port id is not necessarily equal to the PID of the
959 * receiving process (e.g. if the application is multithreaded or using
960 * multiple sockets). In these cases we're not able to find a matching
961 * PID and the information will not be printed.
963 if (hdr
->nlmsg_pid
!= 0) {
964 if (proc_get_cmdline(hdr
->nlmsg_pid
, procname
, sizeof(procname
)) < 0)
965 snprintf(procname
, sizeof(procname
), "unknown process");
967 snprintf(procname
, sizeof(procname
), "kernel");
969 tprintf(" [ NLMSG ");
970 tprintf("Family %d (%s%s%s), ", family
,
971 colorize_start(bold
),
972 nlmsg_family2str(family
),
974 tprintf("Len %u, ", hdr
->nlmsg_len
);
975 tprintf("Type 0x%.4x (%s%s%s), ", hdr
->nlmsg_type
,
976 colorize_start(bold
),
977 nlmsg_type2str(family
, hdr
->nlmsg_type
, type
, sizeof(type
)),
979 tprintf("Flags 0x%.4x (%s%s%s), ", nlmsg_flags
,
980 colorize_start(bold
),
981 nlmsg_flags
? nl_nlmsg_flags2str(nlmsg_flags
, flags
, sizeof(flags
)) : "none",
983 tprintf("Seq-Nr %u, ", hdr
->nlmsg_seq
);
984 tprintf("PID %u", hdr
->nlmsg_pid
);
986 tprintf(" (%s%s%s)", colorize_start(bold
), basename(procname
),
994 case NETLINK_GENERIC
:
998 nlmsg_print_raw(hdr
);
1002 static void nlmsg(struct pkt_buff
*pkt
)
1004 struct nlmsghdr
*hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1005 unsigned int trim_len
= pkt_len(pkt
);
1008 trim_len
-= hdr
->nlmsg_len
;
1009 nlmsg_print(ntohs(pkt
->sll
->sll_protocol
), hdr
);
1011 if (!pkt_pull(pkt
, NLMSG_ALIGN(hdr
->nlmsg_len
) - NLMSG_HDRLEN
))
1014 hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1017 if (hdr
->nlmsg_len
== 0)
1020 if (hdr
->nlmsg_type
!= NLMSG_DONE
&&
1021 (hdr
->nlmsg_flags
& NLM_F_MULTI
))
1025 /* mmaped packet? */
1026 if (hdr
&& hdr
->nlmsg_len
== 0)
1027 pkt_trim(pkt
, trim_len
);
1030 static void nlmsg_less(struct pkt_buff
*pkt
)
1032 struct nlmsghdr
*hdr
= (struct nlmsghdr
*) pkt_pull(pkt
, NLMSG_HDRLEN
);
1033 uint16_t family
= ntohs(pkt
->sll
->sll_protocol
);
1039 tprintf(" NLMSG Family %d (%s%s%s), ", family
,
1040 colorize_start(bold
),
1041 nlmsg_family2str(family
),
1043 tprintf("Type %u (%s%s%s)", hdr
->nlmsg_type
,
1044 colorize_start(bold
),
1045 nlmsg_type2str(family
, hdr
->nlmsg_type
, type
, sizeof(type
)),
1049 struct protocol nlmsg_ops
= {
1050 .print_full
= nlmsg
,
1051 .print_less
= nlmsg_less
,