trafgen: Make sure yyin is set before close it
[netsniff-ng.git] / proto_nlmsg.c
blobc9238c8b8070160cd5a589acefd663946d9eaa75
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2014 Tobias Klauser.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <limits.h>
11 #include <libgen.h>
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>
18 #include "dev.h"
19 #include "pkt_buff.h"
20 #include "proc.h"
21 #include "proto.h"
22 #include "protos.h"
23 #include "timer.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))
34 #ifndef NDA_RTA
35 #define NDA_RTA(r) \
36 ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
37 #endif
39 #ifndef NDA_PAYLOAD
40 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
41 #endif
43 #ifndef NLA_LENGTH
44 #define NLA_LENGTH(len) (NLA_ALIGN(sizeof(struct nlattr)) + (len))
45 #endif
47 #ifndef NLA_DATA
48 #define NLA_DATA(nla) ((void*)(((char*)(nla)) + NLA_LENGTH(0)))
49 #endif
51 #ifndef NLA_PAYLOAD
52 #define NLA_PAYLOAD(nla) ((int)((nla)->nla_len) - NLA_LENGTH(0))
53 #endif
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))
63 #ifndef GEN_NLA
64 #define GEN_NLA(n) ((struct nlattr*)(((char*)(n)) + GENL_HDRLEN))
65 #endif
67 #ifndef NLA_OK
68 #define NLA_OK(nla,len) \
69 ((len) >= (int)sizeof(struct nlattr) && \
70 (nla)->nla_len >= sizeof(struct nlattr) && \
71 (nla)->nla_len <= (len))
72 #endif
74 #ifndef NLA_NEXT
75 #define NLA_NEXT(nla,attrlen) \
76 ((attrlen) -= NLA_ALIGN((nla)->nla_len), \
77 (struct nlattr*)(((char*)(nla)) + NLA_ALIGN((nla)->nla_len)))
78 #endif
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 struct flag_name {
89 const char *name;
90 unsigned int flag;
93 static const char *flags2str(struct flag_name *tbl, unsigned int flags,
94 char *buf, int len)
96 int bits_stay = flags;
98 memset(buf, 0, len);
100 for (; tbl && tbl->name; tbl++) {
101 if (!(tbl->flag & flags))
102 continue;
104 bits_stay &= ~tbl->flag;
105 strncat(buf, tbl->name, len - strlen(buf) - 1);
107 if (bits_stay & flags)
108 strncat(buf, ",", len - strlen(buf) - 1);
111 return buf;
114 static void nlmsg_print_raw(struct nlmsghdr *hdr)
116 u32 len = hdr->nlmsg_len;
118 if (len) {
119 _ascii((uint8_t *) hdr + NLMSG_HDRLEN, len - NLMSG_HDRLEN);
120 _hex((uint8_t *) hdr + NLMSG_HDRLEN, len - NLMSG_HDRLEN);
124 static const char *nlmsg_family2str(uint16_t family)
126 switch (family) {
127 case NETLINK_ROUTE: return "routing";
128 case NETLINK_UNUSED: return "unused";
129 case NETLINK_USERSOCK: return "user-mode socket";
130 case NETLINK_FIREWALL: return "unused, formerly ip_queue";
131 /* NETLINK_INET_DIAG was renamed to NETLINK_SOCK_DIAG in Linux kernel 3.10 */
132 #if defined(NETLINK_SOCK_DIAG)
133 case NETLINK_SOCK_DIAG: return "socket monitoring";
134 #elif defined(NETLINK_INET_DIAG)
135 case NETLINK_INET_DIAG: return "INET socket monitoring";
136 #endif
137 case NETLINK_NFLOG: return "netfilter ULOG";
138 case NETLINK_XFRM: return "IPsec";
139 case NETLINK_SELINUX: return "SELinux event notification";
140 case NETLINK_ISCSI: return "Open-iSCSI";
141 case NETLINK_AUDIT: return "auditing";
142 case NETLINK_FIB_LOOKUP: return "FIB lookup";
143 case NETLINK_CONNECTOR: return "Kernel connector";
144 case NETLINK_NETFILTER: return "Netfilter";
145 case NETLINK_IP6_FW: return "unused, formerly ip6_queue";
146 case NETLINK_DNRTMSG: return "DECnet routing";
147 case NETLINK_KOBJECT_UEVENT: return "Kernel messages";
148 case NETLINK_GENERIC: return "Generic";
149 case NETLINK_SCSITRANSPORT: return "SCSI transports";
150 case NETLINK_ECRYPTFS: return "ecryptfs";
151 case NETLINK_RDMA: return "RDMA";
152 case NETLINK_CRYPTO: return "Crypto layer";
153 default: return "Unknown";
157 static const char *nlmsg_rtnl_type2str(uint16_t type)
159 switch (type) {
160 case RTM_NEWLINK: return "new link";
161 case RTM_DELLINK: return "del link";
162 case RTM_GETLINK: return "get link";
163 case RTM_SETLINK: return "set link";
165 case RTM_NEWADDR: return "new addr";
166 case RTM_DELADDR: return "del addr";
167 case RTM_GETADDR: return "get addr";
169 case RTM_NEWROUTE: return "new route";
170 case RTM_DELROUTE: return "del route";
171 case RTM_GETROUTE: return "get route";
173 case RTM_NEWNEIGH: return "new neigh";
174 case RTM_DELNEIGH: return "del neigh";
175 case RTM_GETNEIGH: return "get neigh";
177 case RTM_NEWRULE: return "new rule";
178 case RTM_DELRULE: return "del rule";
179 case RTM_GETRULE: return "get rule";
181 case RTM_NEWQDISC: return "new tc qdisc";
182 case RTM_DELQDISC: return "del tc qdisc";
183 case RTM_GETQDISC: return "get tc qdisc";
185 case RTM_NEWTCLASS: return "new tc class";
186 case RTM_DELTCLASS: return "del tc class";
187 case RTM_GETTCLASS: return "get tc class";
189 case RTM_NEWTFILTER: return "new tc filter";
190 case RTM_DELTFILTER: return "del tc filter";
191 case RTM_GETTFILTER: return "get tc filter";
193 case RTM_NEWACTION: return "new tc action";
194 case RTM_DELACTION: return "del tc action";
195 case RTM_GETACTION: return "get tc action";
197 case RTM_NEWPREFIX: return "new prefix";
199 case RTM_GETMULTICAST: return "get mcast addr";
201 case RTM_GETANYCAST: return "get anycast addr";
203 case RTM_NEWNEIGHTBL: return "new neigh table";
204 case RTM_GETNEIGHTBL: return "get neigh table";
205 case RTM_SETNEIGHTBL: return "set neigh table";
207 case RTM_NEWNDUSEROPT: return "new ndisc user option";
209 case RTM_NEWADDRLABEL: return "new addr label";
210 case RTM_DELADDRLABEL: return "del addr label";
211 case RTM_GETADDRLABEL: return "get addr label";
213 case RTM_GETDCB: return "get data-center-bridge";
214 case RTM_SETDCB: return "set data-center-bridge";
216 #if defined(RTM_NEWNETCONF)
217 case RTM_NEWNETCONF: return "new netconf";
218 case RTM_GETNETCONF: return "get netconf";
219 #endif
221 #if defined(RTM_NEWMDB)
222 case RTM_NEWMDB: return "new bridge mdb";
223 case RTM_DELMDB: return "del bridge mdb";
224 case RTM_GETMDB: return "get bridge mdb";
225 #endif
226 default: return NULL;
230 static const char *nlmsg_genl_type2str(uint16_t type)
232 switch (type) {
233 case GENL_ID_GENERATE: return "id gen";
234 case GENL_ID_CTRL: return "id ctrl";
235 default: return NULL;
239 static char *nlmsg_type2str(uint16_t proto, uint16_t type, char *buf, int len)
241 const char *name = NULL;
243 if (proto == NETLINK_ROUTE && type < RTM_MAX)
244 name = nlmsg_rtnl_type2str(type);
245 else if (proto == NETLINK_GENERIC)
246 name = nlmsg_genl_type2str(type);
248 if (name) {
249 strncpy(buf, name, len);
250 return buf;
253 return nl_nlmsgtype2str(type, buf, len);
256 static const char *addr_family2str(uint16_t family)
258 switch (family) {
259 case AF_INET: return "ipv4";
260 case AF_INET6: return "ipv6";
261 case AF_DECnet: return "decnet";
262 case AF_IPX: return "ipx";
263 default: return "Unknown";
267 static const char *addr2str(uint16_t af, const void *addr, char *buf, int blen)
269 if (af == AF_INET || af == AF_INET6)
270 return inet_ntop(af, addr, buf, blen);
272 return "???";
275 static const char *scope2str(uint8_t scope)
277 switch (scope) {
278 case RT_SCOPE_UNIVERSE: return "global";
279 case RT_SCOPE_LINK: return "link";
280 case RT_SCOPE_HOST: return "host";
281 case RT_SCOPE_NOWHERE: return "nowhere";
283 default: return "Unknown";
287 static void rtnl_print_ifinfo(struct nlmsghdr *hdr)
289 struct ifinfomsg *ifi = NLMSG_DATA(hdr);
290 struct rtattr *attr = IFLA_RTA(ifi);
291 uint32_t attrs_len = IFLA_PAYLOAD(hdr);
292 char flags[256];
293 char if_addr[64] = {};
294 char *af_link = "unknown";
296 if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifi)))
297 return;
299 if (ifi->ifi_family == AF_UNSPEC)
300 af_link = "unspec";
301 else if (ifi->ifi_family == AF_BRIDGE)
302 af_link = "bridge";
304 tprintf(" [ Link Family %d (%s%s%s)", ifi->ifi_family,
305 colorize_start(bold), af_link, colorize_end());
306 tprintf(", Type %d (%s%s%s)", ifi->ifi_type,
307 colorize_start(bold),
308 device_type2str(ifi->ifi_type),
309 colorize_end());
310 tprintf(", Index %d", ifi->ifi_index);
311 tprintf(", Flags 0x%x (%s%s%s)", ifi->ifi_flags,
312 colorize_start(bold),
313 rtnl_link_flags2str(ifi->ifi_flags, flags,
314 sizeof(flags)),
315 colorize_end());
316 tprintf(", Change 0x%x (%s%s%s) ]\n", ifi->ifi_change,
317 colorize_start(bold),
318 rtnl_link_flags2str(ifi->ifi_change, flags,
319 sizeof(flags)),
320 colorize_end());
322 for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
323 switch (attr->rta_type) {
324 case IFLA_ADDRESS:
325 rta_fmt(attr, "Address %s",
326 device_addr2str(RTA_DATA(attr),
327 RTA_LEN(attr), ifi->ifi_type,
328 if_addr, sizeof(if_addr)));
329 break;
330 case IFLA_BROADCAST:
331 rta_fmt(attr, "Broadcast %s",
332 device_addr2str(RTA_DATA(attr),
333 RTA_LEN(attr), ifi->ifi_type,
334 if_addr, sizeof(if_addr)));
335 break;
336 case IFLA_IFNAME:
337 rta_fmt(attr, "Name %s%s%s",
338 colorize_start(bold), RTA_STR(attr),
339 colorize_end());
340 break;
341 case IFLA_MTU:
342 rta_fmt(attr, "MTU %d", RTA_INT(attr));
343 break;
344 case IFLA_LINK:
345 rta_fmt(attr, "Link %d", RTA_INT(attr));
346 break;
347 case IFLA_QDISC:
348 rta_fmt(attr, "QDisc %s", RTA_STR(attr));
349 break;
350 case IFLA_OPERSTATE:
352 uint8_t st = RTA_UINT8(attr);
353 char states[256];
355 rta_fmt(attr, "Operation state 0x%x (%s%s%s)",
357 colorize_start(bold),
358 rtnl_link_operstate2str(st,
359 states, sizeof(states)),
360 colorize_end());
362 break;
363 case IFLA_LINKMODE:
365 uint8_t mode = RTA_UINT8(attr);
366 char str[32];
368 rta_fmt(attr, "Mode 0x%x (%s%s%s)", mode,
369 colorize_start(bold),
370 rtnl_link_mode2str(mode, str,
371 sizeof(str)),
372 colorize_end());
374 break;
375 case IFLA_GROUP:
376 rta_fmt(attr, "Group %d", RTA_INT(attr));
377 break;
378 case IFLA_TXQLEN:
379 rta_fmt(attr, "Tx queue len %d", RTA_INT(attr));
380 break;
381 case IFLA_NET_NS_PID:
382 rta_fmt(attr, "Network namespace pid %d",
383 RTA_INT(attr));
384 break;
385 case IFLA_NET_NS_FD:
386 rta_fmt(attr, "Network namespace fd %d", RTA_INT(attr));
387 break;
388 default:
389 rta_fmt(attr, "0x%x", attr->rta_type);
390 break;
395 static void rtnl_print_ifaddr(struct nlmsghdr *hdr)
397 struct ifaddrmsg *ifa = NLMSG_DATA(hdr);
398 uint32_t attrs_len = IFA_PAYLOAD(hdr);
399 struct rtattr *attr = IFA_RTA(ifa);
400 struct ifa_cacheinfo *ci;
401 char addr_str[256];
402 char flags[256];
404 if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifa)))
405 return;
407 tprintf(" [ Address Family %d (%s%s%s)", ifa->ifa_family,
408 colorize_start(bold),
409 addr_family2str(ifa->ifa_family),
410 colorize_end());
411 tprintf(", Prefix Len %d", ifa->ifa_prefixlen);
412 tprintf(", Flags %d (%s%s%s)", ifa->ifa_flags,
413 colorize_start(bold),
414 rtnl_addr_flags2str(ifa->ifa_flags, flags,
415 sizeof(flags)),
416 colorize_end());
417 tprintf(", Scope %d (%s%s%s)", ifa->ifa_scope,
418 colorize_start(bold),
419 scope2str(ifa->ifa_scope),
420 colorize_end());
421 tprintf(", Link Index %d ]\n", ifa->ifa_index);
423 for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
424 switch (attr->rta_type) {
425 case IFA_LOCAL:
426 rta_fmt(attr, "Local %s", addr2str(ifa->ifa_family,
427 RTA_DATA(attr), addr_str, sizeof(addr_str)));
428 break;
429 case IFA_ADDRESS:
430 rta_fmt(attr, "Address %s", addr2str(ifa->ifa_family,
431 RTA_DATA(attr), addr_str, sizeof(addr_str)));
432 break;
433 case IFA_BROADCAST:
434 rta_fmt(attr, "Broadcast %s",
435 addr2str(ifa->ifa_family,
436 RTA_DATA(attr), addr_str,
437 sizeof(addr_str)));
438 break;
439 case IFA_MULTICAST:
440 rta_fmt(attr, "Multicast %s",
441 addr2str(ifa->ifa_family,
442 RTA_DATA(attr), addr_str,
443 sizeof(addr_str)));
444 break;
445 case IFA_ANYCAST:
446 rta_fmt(attr, "Anycast %s", addr2str(ifa->ifa_family,
447 RTA_DATA(attr), addr_str, sizeof(addr_str)));
448 break;
449 #ifdef IFA_FLAGS
450 case IFA_FLAGS:
451 rta_fmt(attr, "Flags %d (%s%s%s)", RTA_INT(attr),
452 colorize_start(bold),
453 rtnl_addr_flags2str(RTA_INT(attr),
454 flags, sizeof(flags)),
455 colorize_end());
456 break;
457 #endif
458 case IFA_LABEL:
459 rta_fmt(attr, "Label %s", RTA_STR(attr));
460 break;
461 case IFA_CACHEINFO:
462 ci = RTA_DATA(attr);
463 tprintf("\tA: Cache (");
465 if (ci->ifa_valid == INFINITY)
466 tprintf("valid lft(forever)");
467 else
468 tprintf("valid lft(%us)", ci->ifa_valid);
470 if (ci->ifa_prefered == INFINITY)
471 tprintf(", prefrd lft(forever)");
472 else
473 tprintf(", prefrd lft(%us)", ci->ifa_prefered);
475 tprintf(", created on(%.2fs)", (double)ci->cstamp / 100);
476 tprintf(", updated on(%.2fs))", (double)ci->cstamp / 100);
477 tprintf(", Len %d\n", RTA_LEN(attr));
478 break;
479 default:
480 rta_fmt(attr, "0x%x", attr->rta_type);
481 break;
486 static const char *route_table2str(uint8_t table)
488 switch (table) {
489 case RT_TABLE_UNSPEC: return "unspec";
490 case RT_TABLE_COMPAT: return "compat";
491 case RT_TABLE_DEFAULT: return "default";
492 case RT_TABLE_MAIN: return "main";
493 case RT_TABLE_LOCAL: return "local";
495 default: return "Unknown";
499 static const char *route_proto2str(uint8_t proto)
501 switch (proto) {
502 case RTPROT_UNSPEC: return "unspec";
503 case RTPROT_REDIRECT: return "redirect";
504 case RTPROT_KERNEL: return "kernel";
505 case RTPROT_BOOT: return "boot";
506 case RTPROT_STATIC: return "static";
507 case RTPROT_GATED: return "gated";
508 case RTPROT_RA: return "ra";
509 case RTPROT_MRT: return "mrt";
510 case RTPROT_ZEBRA: return "zebra";
511 case RTPROT_BIRD: return "bird";
512 case RTPROT_DNROUTED: return "DECnet";
513 case RTPROT_XORP: return "xorp";
514 case RTPROT_NTK: return "netsukuku";
515 case RTPROT_DHCP: return "dhcpc";
516 #ifdef RTPROT_MROUTED
517 case RTPROT_MROUTED: return "mrouted";
518 #endif
520 default: return "Unknown";
524 static const char *route_type2str(uint8_t type)
526 switch (type) {
527 case RTN_UNSPEC: return "unspec";
528 case RTN_UNICAST: return "unicast";
529 case RTN_LOCAL: return "local";
530 case RTN_BROADCAST: return "broadcast";
531 case RTN_ANYCAST: return "anycast";
532 case RTN_MULTICAST: return "multicast";
533 case RTN_BLACKHOLE: return "blackhole";
534 case RTN_UNREACHABLE: return "unreach";
535 case RTN_PROHIBIT: return "prohibit";
536 case RTN_THROW: return "throw";
537 case RTN_NAT: return "nat";
538 case RTN_XRESOLVE: return "xresolve";
539 default: return "Unknown";
543 static struct flag_name route_flags[] = {
544 { "notify", RTM_F_NOTIFY },
545 { "cloned", RTM_F_CLONED },
546 { "equalize", RTM_F_EQUALIZE },
547 { "prefix", RTM_F_PREFIX },
548 { "dead", RTNH_F_DEAD },
549 { "pervasive", RTNH_F_PERVASIVE },
550 { "onlink", RTNH_F_ONLINK },
551 { NULL, 0 },
554 static void rtnl_print_route(struct nlmsghdr *hdr)
556 struct rtmsg *rtm = NLMSG_DATA(hdr);
557 uint32_t attrs_len = RTM_PAYLOAD(hdr);
558 struct rtattr *attr = RTM_RTA(rtm);
559 struct rta_cacheinfo *ci;
560 int hz = get_user_hz();
561 char addr_str[256];
562 char flags[256];
564 if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*rtm)))
565 return;
567 tprintf(" [ Route Family %d (%s%s%s)", rtm->rtm_family,
568 colorize_start(bold),
569 addr_family2str(rtm->rtm_family),
570 colorize_end());
571 tprintf(", Dst Len %d", rtm->rtm_dst_len);
572 tprintf(", Src Len %d", rtm->rtm_src_len);
573 tprintf(", ToS %d", rtm->rtm_tos);
574 tprintf(", Table %d (%s%s%s)", rtm->rtm_table,
575 colorize_start(bold),
576 route_table2str(rtm->rtm_table),
577 colorize_end());
578 tprintf(", Proto %d (%s%s%s)", rtm->rtm_protocol,
579 colorize_start(bold),
580 route_proto2str(rtm->rtm_protocol),
581 colorize_end());
582 tprintf(", Scope %d (%s%s%s)", rtm->rtm_scope,
583 colorize_start(bold),
584 scope2str(rtm->rtm_scope),
585 colorize_end());
586 tprintf(", Type %d (%s%s%s)", rtm->rtm_type,
587 colorize_start(bold),
588 route_type2str(rtm->rtm_type),
589 colorize_end());
590 tprintf(", Flags 0x%x (%s%s%s) ]\n", rtm->rtm_flags,
591 colorize_start(bold),
592 flags2str(route_flags, rtm->rtm_flags, flags,
593 sizeof(flags)),
594 colorize_end());
596 for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
597 switch (attr->rta_type) {
598 case RTA_DST:
599 rta_fmt(attr, "Dst %s", addr2str(rtm->rtm_family,
600 RTA_DATA(attr), addr_str, sizeof(addr_str)));
601 break;
602 case RTA_SRC:
603 rta_fmt(attr, "Src %s", addr2str(rtm->rtm_family,
604 RTA_DATA(attr), addr_str, sizeof(addr_str)));
605 break;
606 case RTA_IIF:
607 rta_fmt(attr, "Iif %d", RTA_INT(attr));
608 break;
609 case RTA_OIF:
610 rta_fmt(attr, "Oif %d", RTA_INT(attr));
611 break;
612 case RTA_GATEWAY:
613 rta_fmt(attr, "Gateway %s", addr2str(rtm->rtm_family,
614 RTA_DATA(attr), addr_str, sizeof(addr_str)));
615 break;
616 case RTA_PRIORITY:
617 rta_fmt(attr, "Priority %u", RTA_UINT32(attr));
618 break;
619 case RTA_PREFSRC:
620 rta_fmt(attr, "Pref Src %s", addr2str(rtm->rtm_family,
621 RTA_DATA(attr), addr_str, sizeof(addr_str)));
622 break;
623 case RTA_MARK:
624 rta_fmt(attr, "Mark 0x%x", RTA_UINT(attr));
625 break;
626 case RTA_FLOW:
627 rta_fmt(attr, "Flow 0x%x", RTA_UINT(attr));
628 break;
629 case RTA_TABLE:
630 rta_fmt(attr, "Table %d (%s%s%s)", RTA_UINT32(attr),
631 colorize_start(bold),
632 route_table2str(RTA_UINT32(attr)),
633 colorize_end());
634 break;
635 case RTA_CACHEINFO:
636 ci = RTA_DATA(attr);
637 tprintf("\tA: Cache (");
638 tprintf("expires(%ds)", ci->rta_expires / hz);
639 tprintf(", error(%d)", ci->rta_error);
640 tprintf(", users(%d)", ci->rta_clntref);
641 tprintf(", used(%d)", ci->rta_used);
642 tprintf(", last use(%ds)", ci->rta_lastuse / hz);
643 tprintf(", id(%d)", ci->rta_id);
644 tprintf(", ts(%d)", ci->rta_ts);
645 tprintf(", ts age(%ds))", ci->rta_tsage);
646 tprintf(", Len %d\n", RTA_LEN(attr));
647 break;
648 default:
649 rta_fmt(attr, "0x%x", attr->rta_type);
650 break;
655 static struct flag_name neigh_states[] = {
656 { "incomplete", NUD_INCOMPLETE },
657 { "reachable", NUD_REACHABLE },
658 { "stale", NUD_STALE },
659 { "delay", NUD_DELAY },
660 { "probe", NUD_PROBE },
661 { "failed", NUD_FAILED },
662 { "noarp", NUD_NOARP },
663 { "permanent", NUD_PERMANENT },
664 { "none", NUD_NONE },
665 { NULL, 0 },
668 /* Copied from linux/neighbour.h */
669 #ifndef NTF_USE
670 # define NTF_USE 0x01
671 #endif
672 #ifndef NTF_SELF
673 # define NTF_SELF 0x02
674 #endif
675 #ifndef NTF_MASTER
676 # define NTF_MASTER 0x04
677 #endif
678 #ifndef NTF_PROXY
679 # define NTF_PROXY 0x08
680 #endif
681 #ifndef NTF_EXT_LEARNED
682 # define NTF_EXT_LEARNED 0x10
683 #endif
684 #ifndef NTF_ROUTER
685 # define NTF_ROUTER 0x80
686 #endif
688 static struct flag_name neigh_flags[] = {
689 { "use", NTF_USE },
690 { "self", NTF_SELF },
691 { "master", NTF_MASTER },
692 { "proxy", NTF_PROXY },
693 { "ext learned", NTF_EXT_LEARNED },
694 { "router", NTF_ROUTER },
695 { NULL, 0 },
698 static void rtnl_print_neigh(struct nlmsghdr *hdr)
700 struct ndmsg *ndm = NLMSG_DATA(hdr);
701 uint32_t attrs_len = NDA_PAYLOAD(hdr);
702 struct rtattr *attr = NDA_RTA(ndm);
703 struct nda_cacheinfo *ci;
704 int hz = get_user_hz();
705 char addr_str[256];
706 char hw_addr[30];
707 char states[256];
708 char flags[256];
710 if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ndm)))
711 return;
713 tprintf(" [ Neigh Family %d (%s%s%s)", ndm->ndm_family,
714 colorize_start(bold),
715 addr_family2str(ndm->ndm_family),
716 colorize_end());
717 tprintf(", Link Index %d", ndm->ndm_ifindex);
718 tprintf(", State %d (%s%s%s)", ndm->ndm_state,
719 colorize_start(bold),
720 flags2str(neigh_states, ndm->ndm_state, states,
721 sizeof(states)),
722 colorize_end());
723 tprintf(", Flags %d (%s%s%s)", ndm->ndm_flags,
724 colorize_start(bold),
725 flags2str(neigh_flags, ndm->ndm_flags, flags,
726 sizeof(flags)),
727 colorize_end());
728 tprintf(", Type %d (%s%s%s)", ndm->ndm_type,
729 colorize_start(bold),
730 route_type2str(ndm->ndm_type),
731 colorize_end());
732 tprintf(" ]\n");
734 for (; RTA_OK(attr, attrs_len); attr = RTA_NEXT(attr, attrs_len)) {
735 switch (attr->rta_type) {
736 case NDA_DST:
737 rta_fmt(attr, "Address %s", addr2str(ndm->ndm_family,
738 RTA_DATA(attr), addr_str,
739 sizeof(addr_str)));
740 break;
741 case NDA_LLADDR:
742 rta_fmt(attr, "HW Address %s",
743 device_addr2str(RTA_DATA(attr),
744 RTA_LEN(attr), 0, hw_addr,
745 sizeof(hw_addr)));
746 break;
747 case NDA_PROBES:
748 rta_fmt(attr, "Probes %d", RTA_UINT32(attr));
749 break;
750 case NDA_CACHEINFO:
751 ci = RTA_DATA(attr);
752 tprintf("\tA: Cache (");
753 tprintf("confirmed(%ds)", ci->ndm_confirmed / hz);
754 tprintf(", used(%ds)", ci->ndm_used / hz);
755 tprintf(", updated(%ds)", ci->ndm_updated / hz);
756 tprintf(", refcnt(%d))", ci->ndm_refcnt);
757 tprintf(", Len %d\n", RTA_LEN(attr));
758 break;
759 default:
760 rta_fmt(attr, "0x%x", attr->rta_type);
761 break;
766 static void rtnl_msg_print(struct nlmsghdr *hdr)
768 switch (hdr->nlmsg_type) {
769 case RTM_NEWLINK:
770 case RTM_DELLINK:
771 case RTM_GETLINK:
772 case RTM_SETLINK:
773 rtnl_print_ifinfo(hdr);
774 break;
775 case RTM_NEWADDR:
776 case RTM_DELADDR:
777 case RTM_GETADDR:
778 rtnl_print_ifaddr(hdr);
779 break;
780 case RTM_NEWROUTE:
781 case RTM_DELROUTE:
782 case RTM_GETROUTE:
783 rtnl_print_route(hdr);
784 break;
785 case RTM_NEWNEIGH:
786 case RTM_DELNEIGH:
787 case RTM_GETNEIGH:
788 rtnl_print_neigh(hdr);
789 break;
793 static const char *genl_cmd2str(uint8_t table)
795 switch (table) {
796 case CTRL_CMD_UNSPEC: return "unspec";
797 case CTRL_CMD_NEWFAMILY: return "new family";
798 case CTRL_CMD_DELFAMILY: return "del family";
799 case CTRL_CMD_GETFAMILY: return "get family";
800 case CTRL_CMD_NEWOPS: return "new ops";
801 case CTRL_CMD_DELOPS: return "del ops";
802 case CTRL_CMD_GETOPS: return "get ops";
803 case CTRL_CMD_NEWMCAST_GRP: return "new mcast group";
804 case CTRL_CMD_DELMCAST_GRP: return "del mcast group";
805 case CTRL_CMD_GETMCAST_GRP: return "get mcast group";
807 default: return "Unknown";
811 static void genl_print_ctrl_family(struct nlmsghdr *hdr)
813 struct genlmsghdr *genl = NLMSG_DATA(hdr);
814 struct nlattr *attr = GEN_NLA(genl);
815 uint32_t attrs_len = NLMSG_PAYLOAD(hdr, sizeof(struct genlmsghdr));
817 for (; NLA_OK(attr, attrs_len); attr = NLA_NEXT(attr, attrs_len)) {
818 switch (attr->nla_type) {
819 case CTRL_ATTR_FAMILY_ID:
820 nla_fmt(attr, "Family Id 0x%x", NLA_UINT16(attr));
821 break;
823 case CTRL_ATTR_FAMILY_NAME:
824 nla_fmt(attr, "Family Name %s", NLA_STR(attr));
825 break;
827 case CTRL_ATTR_VERSION:
828 nla_fmt(attr, "Version %u", NLA_UINT32(attr));
829 break;
831 case CTRL_ATTR_HDRSIZE:
832 nla_fmt(attr, "Header size %u", NLA_UINT32(attr));
833 break;
835 case CTRL_ATTR_MAXATTR:
836 nla_fmt(attr, "Max attr value 0x%x", NLA_UINT32(attr));
837 break;
839 default:
840 nla_fmt(attr, "0x%x", attr->nla_type);
841 break;
846 static void genl_print_ctrl(struct nlmsghdr *hdr)
848 struct genlmsghdr *genl = NLMSG_DATA(hdr);
850 switch (genl->cmd) {
851 case CTRL_CMD_NEWFAMILY:
852 case CTRL_CMD_DELFAMILY:
853 case CTRL_CMD_GETFAMILY:
854 genl_print_ctrl_family(hdr);
858 static void genl_msg_print(struct nlmsghdr *hdr)
860 struct genlmsghdr *genl;
862 if (hdr->nlmsg_type != GENL_ID_CTRL) {
863 nlmsg_print_raw(hdr);
864 return;
867 genl = NLMSG_DATA(hdr);
869 tprintf(" [ Cmd %u (%s%s%s)", genl->cmd,
870 colorize_start(bold), genl_cmd2str(genl->cmd), colorize_end());
871 tprintf(", Version %u", genl->version);
872 tprintf(", Reserved %u", genl->reserved);
873 tprintf(" ]\n");
875 genl_print_ctrl(hdr);
878 static void nlmsg_print(uint16_t family, struct nlmsghdr *hdr)
880 u16 nlmsg_flags = hdr->nlmsg_flags;
881 char type[32];
882 char flags[128];
883 char procname[PATH_MAX];
885 /* Look up the process name if message is not coming from the kernel.
887 * Note that the port id is not necessarily equal to the PID of the
888 * receiving process (e.g. if the application is multithreaded or using
889 * multiple sockets). In these cases we're not able to find a matching
890 * PID and the information will not be printed.
892 if (hdr->nlmsg_pid != 0) {
893 if (proc_get_cmdline(hdr->nlmsg_pid, procname, sizeof(procname)) < 0)
894 snprintf(procname, sizeof(procname), "unknown process");
895 } else
896 snprintf(procname, sizeof(procname), "kernel");
898 tprintf(" [ NLMSG ");
899 tprintf("Family %d (%s%s%s), ", family,
900 colorize_start(bold),
901 nlmsg_family2str(family),
902 colorize_end());
903 tprintf("Len %u, ", hdr->nlmsg_len);
904 tprintf("Type 0x%.4x (%s%s%s), ", hdr->nlmsg_type,
905 colorize_start(bold),
906 nlmsg_type2str(family, hdr->nlmsg_type, type, sizeof(type)),
907 colorize_end());
908 tprintf("Flags 0x%.4x (%s%s%s), ", nlmsg_flags,
909 colorize_start(bold),
910 nlmsg_flags ? nl_nlmsg_flags2str(nlmsg_flags, flags, sizeof(flags)) : "none",
911 colorize_end());
912 tprintf("Seq-Nr %u, ", hdr->nlmsg_seq);
913 tprintf("PID %u", hdr->nlmsg_pid);
914 if (procname[0])
915 tprintf(" (%s%s%s)", colorize_start(bold), basename(procname),
916 colorize_end());
917 tprintf(" ]\n");
919 switch (family) {
920 case NETLINK_ROUTE:
921 rtnl_msg_print(hdr);
922 break;
923 case NETLINK_GENERIC:
924 genl_msg_print(hdr);
925 break;
926 default:
927 nlmsg_print_raw(hdr);
931 static void nlmsg(struct pkt_buff *pkt)
933 struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, NLMSG_HDRLEN);
934 unsigned int trim_len = pkt_len(pkt);
936 while (hdr) {
937 trim_len -= hdr->nlmsg_len;
938 nlmsg_print(ntohs(pkt->sll->sll_protocol), hdr);
940 if (!pkt_pull(pkt, NLMSG_ALIGN(hdr->nlmsg_len) - NLMSG_HDRLEN))
941 break;
943 hdr = (struct nlmsghdr *) pkt_pull(pkt, NLMSG_HDRLEN);
944 if (hdr == NULL)
945 break;
946 if (hdr->nlmsg_len == 0)
947 break;
949 if (hdr->nlmsg_type != NLMSG_DONE &&
950 (hdr->nlmsg_flags & NLM_F_MULTI))
951 tprintf("\n");
954 /* mmaped packet? */
955 if (hdr && hdr->nlmsg_len == 0)
956 pkt_trim(pkt, trim_len);
959 static void nlmsg_less(struct pkt_buff *pkt)
961 struct nlmsghdr *hdr = (struct nlmsghdr *) pkt_pull(pkt, NLMSG_HDRLEN);
962 uint16_t family = ntohs(pkt->sll->sll_protocol);
963 char type[32];
965 if (hdr == NULL)
966 return;
968 tprintf(" NLMSG Family %d (%s%s%s), ", family,
969 colorize_start(bold),
970 nlmsg_family2str(family),
971 colorize_end());
972 tprintf("Type %u (%s%s%s)", hdr->nlmsg_type,
973 colorize_start(bold),
974 nlmsg_type2str(family, hdr->nlmsg_type, type, sizeof(type)),
975 colorize_end());
978 struct protocol nlmsg_ops = {
979 .print_full = nlmsg,
980 .print_less = nlmsg_less,