2 * Copyright (c) 2018 Rafael Zalamena
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #if defined(HAVE_NETLINK) && defined(NETLINK_DEBUG)
21 #include <sys/socket.h>
23 #include <linux/netlink.h>
24 #include <linux/nexthop.h>
25 #include <linux/rtnetlink.h>
26 #include <net/if_arp.h>
31 #include "zebra/rt_netlink.h"
33 const char *nlmsg_type2str(uint16_t type
)
96 const char *af_type2str(int type
)
116 return "AF_BLUETOOTH";
128 const char *ifi_type2str(int type
)
147 case ARPHRD_APPLETLK
:
153 case ARPHRD_METRICOM
:
155 case ARPHRD_IEEE1394
:
159 case ARPHRD_INFINIBAND
:
195 case ARPHRD_LOOPBACK
:
197 case ARPHRD_LOCALTLK
:
225 case ARPHRD_FCFABRIC
:
227 case ARPHRD_IEEE802_TR
:
229 case ARPHRD_IEEE80211
:
231 case ARPHRD_IEEE80211_PRISM
:
232 return "IEEE80211_PRISM";
233 case ARPHRD_IEEE80211_RADIOTAP
:
234 return "IEEE80211_RADIOTAP";
235 case ARPHRD_IEEE802154
:
237 #ifdef ARPHRD_VSOCKMON
238 case ARPHRD_VSOCKMON
:
240 #endif /* ARPHRD_VSOCKMON */
250 const char *rta_type2str(int type
)
291 case IFLA_NET_NS_PID
:
297 case IFLA_VFINFO_LIST
:
298 return "VFINFO_LIST";
313 case IFLA_PROMISCUITY
:
314 return "PROMISCUITY";
315 case IFLA_NUM_TX_QUEUES
:
316 return "NUM_TX_QUEUES";
317 case IFLA_NUM_RX_QUEUES
:
318 return "NUM_RX_QUEUES";
321 case IFLA_PHYS_PORT_ID
:
322 return "PHYS_PORT_ID";
323 case IFLA_CARRIER_CHANGES
:
324 return "CARRIER_CHANGES";
325 case IFLA_PHYS_SWITCH_ID
:
326 return "PHYS_SWITCH_ID";
327 case IFLA_LINK_NETNSID
:
328 return "LINK_NETNSID";
329 case IFLA_PHYS_PORT_NAME
:
330 return "PHYS_PORT_NAME";
331 case IFLA_PROTO_DOWN
:
333 #ifdef IFLA_GSO_MAX_SEGS
334 case IFLA_GSO_MAX_SEGS
:
335 return "GSO_MAX_SEGS";
336 #endif /* IFLA_GSO_MAX_SEGS */
337 #ifdef IFLA_GSO_MAX_SIZE
338 case IFLA_GSO_MAX_SIZE
:
339 return "GSO_MAX_SIZE";
340 #endif /* IFLA_GSO_MAX_SIZE */
344 #endif /* IFLA_PAD */
348 #endif /* IFLA_XDP */
352 #endif /* IFLA_EVENT */
358 const char *rtm_type2str(int type
)
375 case RTN_UNREACHABLE
:
376 return "UNREACHABLE";
390 const char *rtm_protocol2str(int type
)
395 case RTPROT_REDIRECT
:
413 case RTPROT_DNROUTED
:
430 const char *rtm_scope2str(int type
)
433 case RT_SCOPE_UNIVERSE
:
441 case RT_SCOPE_NOWHERE
:
448 const char *rtm_rta2str(int type
)
492 const char *neigh_rta2str(int type
)
515 case NDA_LINK_NETNSID
:
516 return "LINK_NETNSID";
522 const char *ifa_rta2str(int type
)
548 const char *nhm_rta2str(int type
)
578 static inline void flag_write(int flags
, int flag
, const char *flagstr
,
579 char *buf
, size_t buflen
)
581 if (CHECK_FLAG(flags
, flag
) == 0)
585 strlcat(buf
, ",", buflen
);
587 strlcat(buf
, flagstr
, buflen
);
590 const char *nlmsg_flags2str(uint16_t flags
, char *buf
, size_t buflen
)
592 const char *bufp
= buf
;
595 /* Specific flags. */
596 flag_write(flags
, NLM_F_REQUEST
, "REQUEST", buf
, buflen
);
597 flag_write(flags
, NLM_F_MULTI
, "MULTI", buf
, buflen
);
598 flag_write(flags
, NLM_F_ACK
, "ACK", buf
, buflen
);
599 flag_write(flags
, NLM_F_ECHO
, "ECHO", buf
, buflen
);
600 flag_write(flags
, NLM_F_DUMP
, "DUMP", buf
, buflen
);
602 /* Netlink family type dependent. */
603 flag_write(flags
, 0x0100, "(ROOT|REPLACE|CAPPED)", buf
, buflen
);
604 flag_write(flags
, 0x0200, "(MATCH|EXCLUDE|ACK_TLVS)", buf
, buflen
);
605 flag_write(flags
, 0x0400, "(ATOMIC|CREATE)", buf
, buflen
);
606 flag_write(flags
, 0x0800, "(DUMP|APPEND)", buf
, buflen
);
611 const char *if_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
613 const char *bufp
= buf
;
616 flag_write(flags
, IFF_UP
, "UP", buf
, buflen
);
617 flag_write(flags
, IFF_BROADCAST
, "BROADCAST", buf
, buflen
);
618 flag_write(flags
, IFF_DEBUG
, "DEBUG", buf
, buflen
);
619 flag_write(flags
, IFF_LOOPBACK
, "LOOPBACK", buf
, buflen
);
620 flag_write(flags
, IFF_POINTOPOINT
, "POINTOPOINT", buf
, buflen
);
621 flag_write(flags
, IFF_NOTRAILERS
, "NOTRAILERS", buf
, buflen
);
622 flag_write(flags
, IFF_RUNNING
, "RUNNING", buf
, buflen
);
623 flag_write(flags
, IFF_NOARP
, "NOARP", buf
, buflen
);
624 flag_write(flags
, IFF_PROMISC
, "PROMISC", buf
, buflen
);
625 flag_write(flags
, IFF_ALLMULTI
, "ALLMULTI", buf
, buflen
);
626 flag_write(flags
, IFF_MASTER
, "MASTER", buf
, buflen
);
627 flag_write(flags
, IFF_SLAVE
, "SLAVE", buf
, buflen
);
628 flag_write(flags
, IFF_MULTICAST
, "MULTICAST", buf
, buflen
);
629 flag_write(flags
, IFF_PORTSEL
, "PORTSEL", buf
, buflen
);
630 flag_write(flags
, IFF_AUTOMEDIA
, "AUTOMEDIA", buf
, buflen
);
631 flag_write(flags
, IFF_DYNAMIC
, "DYNAMIC", buf
, buflen
);
636 const char *rtm_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
638 const char *bufp
= buf
;
641 flag_write(flags
, RTM_F_NOTIFY
, "NOTIFY", buf
, buflen
);
642 flag_write(flags
, RTM_F_CLONED
, "CLONED", buf
, buflen
);
643 flag_write(flags
, RTM_F_EQUALIZE
, "EQUALIZE", buf
, buflen
);
648 const char *neigh_state2str(uint32_t flags
, char *buf
, size_t buflen
)
650 const char *bufp
= buf
;
653 flag_write(flags
, NUD_INCOMPLETE
, "INCOMPLETE", buf
, buflen
);
654 flag_write(flags
, NUD_REACHABLE
, "REACHABLE", buf
, buflen
);
655 flag_write(flags
, NUD_STALE
, "STALE", buf
, buflen
);
656 flag_write(flags
, NUD_DELAY
, "DELAY", buf
, buflen
);
657 flag_write(flags
, NUD_PROBE
, "PROBE", buf
, buflen
);
658 flag_write(flags
, NUD_FAILED
, "FAILED", buf
, buflen
);
659 flag_write(flags
, NUD_NOARP
, "NOARP", buf
, buflen
);
660 flag_write(flags
, NUD_PERMANENT
, "PERMANENT", buf
, buflen
);
665 const char *neigh_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
667 const char *bufp
= buf
;
670 flag_write(flags
, NTF_USE
, "USE", buf
, buflen
);
671 flag_write(flags
, NTF_SELF
, "SELF", buf
, buflen
);
672 flag_write(flags
, NTF_MASTER
, "MASTER", buf
, buflen
);
673 flag_write(flags
, NTF_PROXY
, "PROXY", buf
, buflen
);
674 flag_write(flags
, NTF_EXT_LEARNED
, "EXT_LEARNED", buf
, buflen
);
676 flag_write(flags
, NTF_OFFLOADED
, "OFFLOADED", buf
, buflen
);
677 #endif /* NTF_OFFLOADED */
678 flag_write(flags
, NTF_ROUTER
, "ROUTER", buf
, buflen
);
683 const char *ifa_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
685 const char *bufp
= buf
;
688 flag_write(flags
, IFA_F_SECONDARY
, "SECONDARY", buf
, buflen
);
689 flag_write(flags
, IFA_F_NODAD
, "NODAD", buf
, buflen
);
690 flag_write(flags
, IFA_F_OPTIMISTIC
, "OPTIMISTIC", buf
, buflen
);
691 flag_write(flags
, IFA_F_DADFAILED
, "DADFAILED", buf
, buflen
);
692 flag_write(flags
, IFA_F_HOMEADDRESS
, "HOMEADDRESS", buf
, buflen
);
693 flag_write(flags
, IFA_F_DEPRECATED
, "DEPRECATED", buf
, buflen
);
694 flag_write(flags
, IFA_F_TENTATIVE
, "TENTATIVE", buf
, buflen
);
695 flag_write(flags
, IFA_F_PERMANENT
, "PERMANENT", buf
, buflen
);
696 flag_write(flags
, IFA_F_MANAGETEMPADDR
, "MANAGETEMPADDR", buf
, buflen
);
697 flag_write(flags
, IFA_F_NOPREFIXROUTE
, "NOPREFIXROUTE", buf
, buflen
);
698 flag_write(flags
, IFA_F_MCAUTOJOIN
, "MCAUTOJOIN", buf
, buflen
);
699 flag_write(flags
, IFA_F_STABLE_PRIVACY
, "STABLE_PRIVACY", buf
, buflen
);
704 const char *nh_flags2str(uint32_t flags
, char *buf
, size_t buflen
)
706 const char *bufp
= buf
;
709 flag_write(flags
, RTNH_F_DEAD
, "DEAD", buf
, buflen
);
710 flag_write(flags
, RTNH_F_PERVASIVE
, "PERVASIVE", buf
, buflen
);
711 flag_write(flags
, RTNH_F_ONLINK
, "ONLINK", buf
, buflen
);
712 flag_write(flags
, RTNH_F_OFFLOAD
, "OFFLOAD", buf
, buflen
);
713 flag_write(flags
, RTNH_F_LINKDOWN
, "LINKDOWN", buf
, buflen
);
714 flag_write(flags
, RTNH_F_UNRESOLVED
, "UNRESOLVED", buf
, buflen
);
720 * Netlink abstractions.
722 static void nllink_linkinfo_dump(struct rtattr
*rta
, size_t msglen
)
728 /* Check the header for valid length and for outbound access. */
729 if (RTA_OK(rta
, msglen
) == 0)
732 plen
= RTA_PAYLOAD(rta
);
733 zlog_debug(" linkinfo [len=%d (payload=%zu) type=(%d) %s]",
734 rta
->rta_len
, plen
, rta
->rta_type
,
735 rta_type2str(rta
->rta_type
));
736 switch (rta
->rta_type
) {
739 zlog_debug(" invalid length");
743 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
744 zlog_debug(" %s", dbuf
);
746 case IFLA_INFO_SLAVE_KIND
:
748 zlog_debug(" invalid length");
752 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
753 zlog_debug(" %s", dbuf
);
757 /* NOTHING: unhandled. */
761 /* Get next pointer and start iteration again. */
762 rta
= RTA_NEXT(rta
, msglen
);
766 static void nllink_dump(struct ifinfomsg
*ifi
, size_t msglen
)
775 /* Get the first attribute and go from there. */
778 /* Check the header for valid length and for outbound access. */
779 if (RTA_OK(rta
, msglen
) == 0)
782 plen
= RTA_PAYLOAD(rta
);
783 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
784 plen
, rta
->rta_type
, rta_type2str(rta
->rta_type
));
785 switch (rta
->rta_type
) {
789 zlog_debug(" invalid length");
793 snprintf(dbuf
, sizeof(dbuf
), "%s", (char *)RTA_DATA(rta
));
794 zlog_debug(" %s", dbuf
);
799 case IFLA_NUM_TX_QUEUES
:
800 case IFLA_NUM_RX_QUEUES
:
802 case IFLA_PROMISCUITY
:
803 #ifdef IFLA_GSO_MAX_SEGS
804 case IFLA_GSO_MAX_SEGS
:
805 #endif /* IFLA_GSO_MAX_SEGS */
806 #ifdef IFLA_GSO_MAX_SIZE
807 case IFLA_GSO_MAX_SIZE
:
808 #endif /* IFLA_GSO_MAX_SIZE */
809 case IFLA_CARRIER_CHANGES
:
811 if (plen
< sizeof(uint32_t)) {
812 zlog_debug(" invalid length");
816 u32v
= *(uint32_t *)RTA_DATA(rta
);
817 zlog_debug(" %u", u32v
);
821 datap
= RTA_DATA(rta
);
823 for (it
= 0; it
< plen
; it
++) {
824 snprintf(bytestr
, sizeof(bytestr
), "%02X:", *datap
);
825 strlcat(dbuf
, bytestr
, sizeof(dbuf
));
828 /* Remove trailing ':'. */
830 dbuf
[strlen(dbuf
) - 1] = 0;
832 zlog_debug(" %s", dbuf
[0] ? dbuf
: "<empty>");
836 nllink_linkinfo_dump(RTA_DATA(rta
), msglen
);
840 /* NOTHING: unhandled. */
844 /* Get next pointer and start iteration again. */
845 rta
= RTA_NEXT(rta
, msglen
);
849 static void nlroute_dump(struct rtmsg
*rtm
, size_t msglen
)
855 /* Get the first attribute and go from there. */
858 /* Check the header for valid length and for outbound access. */
859 if (RTA_OK(rta
, msglen
) == 0)
862 plen
= RTA_PAYLOAD(rta
);
863 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
864 plen
, rta
->rta_type
, rtm_rta2str(rta
->rta_type
));
865 switch (rta
->rta_type
) {
871 u32v
= *(uint32_t *)RTA_DATA(rta
);
872 zlog_debug(" %u", u32v
);
880 case sizeof(struct in_addr
):
882 (struct in_addr
*)RTA_DATA(rta
));
884 case sizeof(struct in6_addr
):
886 (struct in6_addr
*)RTA_DATA(rta
));
894 /* NOTHING: unhandled. */
898 /* Get next pointer and start iteration again. */
899 rta
= RTA_NEXT(rta
, msglen
);
903 static void nlneigh_dump(struct ndmsg
*ndm
, size_t msglen
)
913 #define NDA_RTA(ndm) \
914 /* struct ndmsg *ndm; */ \
915 ((struct rtattr *)(((uint8_t *)(ndm)) \
916 + NLMSG_ALIGN(sizeof(struct ndmsg))))
919 /* Get the first attribute and go from there. */
922 /* Check the header for valid length and for outbound access. */
923 if (RTA_OK(rta
, msglen
) == 0)
926 plen
= RTA_PAYLOAD(rta
);
927 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
928 plen
, rta
->rta_type
, neigh_rta2str(rta
->rta_type
));
929 switch (rta
->rta_type
) {
931 datap
= RTA_DATA(rta
);
933 for (it
= 0; it
< plen
; it
++) {
934 snprintf(bytestr
, sizeof(bytestr
), "%02X:", *datap
);
935 strlcat(dbuf
, bytestr
, sizeof(dbuf
));
938 /* Remove trailing ':'. */
940 dbuf
[strlen(dbuf
) - 1] = 0;
942 zlog_debug(" %s", dbuf
[0] ? dbuf
: "<empty>");
947 case sizeof(struct in_addr
):
949 (struct in_addr
*)RTA_DATA(rta
));
951 case sizeof(struct in6_addr
):
953 (struct in6_addr
*)RTA_DATA(rta
));
961 vid
= *(uint16_t *)RTA_DATA(rta
);
962 zlog_debug(" %d", vid
);
966 /* NOTHING: unhandled. */
970 /* Get next pointer and start iteration again. */
971 rta
= RTA_NEXT(rta
, msglen
);
975 static void nlifa_dump(struct ifaddrmsg
*ifa
, size_t msglen
)
981 /* Get the first attribute and go from there. */
984 /* Check the header for valid length and for outbound access. */
985 if (RTA_OK(rta
, msglen
) == 0)
988 plen
= RTA_PAYLOAD(rta
);
989 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
990 plen
, rta
->rta_type
, ifa_rta2str(rta
->rta_type
));
991 switch (rta
->rta_type
) {
993 u32v
= *(uint32_t *)RTA_DATA(rta
);
994 zlog_debug(" %u", u32v
);
998 zlog_debug(" %s", (const char *)RTA_DATA(rta
));
1007 (struct in_addr
*)RTA_DATA(rta
));
1011 (struct in6_addr
*)RTA_DATA(rta
));
1019 /* NOTHING: unhandled. */
1023 /* Get next pointer and start iteration again. */
1024 rta
= RTA_NEXT(rta
, msglen
);
1028 static void nlnh_dump(struct nhmsg
*nhm
, size_t msglen
)
1035 unsigned long count
, i
;
1036 struct nexthop_grp
*nhgrp
;
1040 /* Check the header for valid length and for outbound access. */
1041 if (RTA_OK(rta
, msglen
) == 0)
1044 plen
= RTA_PAYLOAD(rta
);
1045 zlog_debug(" rta [len=%d (payload=%zu) type=(%d) %s]", rta
->rta_len
,
1046 plen
, rta
->rta_type
, nhm_rta2str(rta
->rta_type
));
1047 switch (rta
->rta_type
) {
1049 u32v
= *(uint32_t *)RTA_DATA(rta
);
1050 zlog_debug(" %u", u32v
);
1053 nhgrp
= (struct nexthop_grp
*)RTA_DATA(rta
);
1054 count
= (RTA_PAYLOAD(rta
) / sizeof(*nhgrp
));
1056 || (count
* sizeof(*nhgrp
)) != RTA_PAYLOAD(rta
)) {
1057 zlog_debug(" invalid nexthop group received");
1061 for (i
= 0; i
< count
; i
++)
1062 zlog_debug(" id %d weight %d", nhgrp
[i
].id
,
1065 case NHA_ENCAP_TYPE
:
1066 case NHA_GROUP_TYPE
:
1067 u16v
= *(uint16_t *)RTA_DATA(rta
);
1068 zlog_debug(" %d", u16v
);
1074 ifindex
= *(int *)RTA_DATA(rta
);
1075 zlog_debug(" %d", ifindex
);
1078 switch (nhm
->nh_family
) {
1081 (struct in_addr
*)RTA_DATA(rta
));
1085 (struct in6_addr
*)RTA_DATA(rta
));
1089 zlog_debug(" invalid family %d", nhm
->nh_family
);
1094 /* TODO: handle MPLS labels. */
1095 zlog_debug(" unparsed MPLS labels");
1098 /* TODO: handle this message. */
1099 zlog_debug(" unparsed GROUPS message");
1103 /* NOTHING: unhandled. */
1107 /* Get next pointer and start iteration again. */
1108 rta
= RTA_NEXT(rta
, msglen
);
1112 void nl_dump(void *msg
, size_t msglen
)
1114 struct nlmsghdr
*nlmsg
= msg
;
1115 struct nlmsgerr
*nlmsgerr
;
1116 struct rtgenmsg
*rtgen
;
1117 struct ifaddrmsg
*ifa
;
1121 struct ifinfomsg
*ifi
;
1127 "nlmsghdr [len=%u type=(%d) %s flags=(0x%04x) {%s} seq=%u pid=%u]",
1128 nlmsg
->nlmsg_len
, nlmsg
->nlmsg_type
,
1129 nlmsg_type2str(nlmsg
->nlmsg_type
), nlmsg
->nlmsg_flags
,
1130 nlmsg_flags2str(nlmsg
->nlmsg_flags
, fbuf
, sizeof(fbuf
)),
1131 nlmsg
->nlmsg_seq
, nlmsg
->nlmsg_pid
);
1133 switch (nlmsg
->nlmsg_type
) {
1138 nlmsgerr
= NLMSG_DATA(nlmsg
);
1139 zlog_debug(" nlmsgerr [error=(%d) %s]", nlmsgerr
->error
,
1140 strerror(-nlmsgerr
->error
));
1151 ifi
= NLMSG_DATA(nlmsg
);
1153 " ifinfomsg [family=%d type=(%d) %s "
1154 "index=%d flags=0x%04x {%s}]",
1155 ifi
->ifi_family
, ifi
->ifi_type
,
1156 ifi_type2str(ifi
->ifi_type
), ifi
->ifi_index
,
1158 if_flags2str(ifi
->ifi_flags
, ibuf
, sizeof(ibuf
)));
1159 nllink_dump(ifi
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifi
)));
1162 rtgen
= NLMSG_DATA(nlmsg
);
1163 zlog_debug(" rtgen [family=(%d) %s]", rtgen
->rtgen_family
,
1164 af_type2str(rtgen
->rtgen_family
));
1170 rtm
= NLMSG_DATA(nlmsg
);
1172 " rtmsg [family=(%d) %s dstlen=%d srclen=%d tos=%d "
1173 "table=%d protocol=(%d) %s scope=(%d) %s "
1174 "type=(%d) %s flags=0x%04x {%s}]",
1175 rtm
->rtm_family
, af_type2str(rtm
->rtm_family
),
1176 rtm
->rtm_dst_len
, rtm
->rtm_src_len
, rtm
->rtm_tos
,
1177 rtm
->rtm_table
, rtm
->rtm_protocol
,
1178 rtm_protocol2str(rtm
->rtm_protocol
), rtm
->rtm_scope
,
1179 rtm_scope2str(rtm
->rtm_scope
), rtm
->rtm_type
,
1180 rtm_type2str(rtm
->rtm_type
), rtm
->rtm_flags
,
1181 rtm_flags2str(rtm
->rtm_flags
, fbuf
, sizeof(fbuf
)));
1183 nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*rtm
)));
1188 ndm
= NLMSG_DATA(nlmsg
);
1190 " ndm [family=%d (%s) ifindex=%d state=0x%04x {%s} "
1191 "flags=0x%04x {%s} type=%d (%s)]",
1192 ndm
->ndm_family
, af_type2str(ndm
->ndm_family
),
1193 ndm
->ndm_ifindex
, ndm
->ndm_state
,
1194 neigh_state2str(ndm
->ndm_state
, ibuf
, sizeof(ibuf
)),
1196 neigh_flags2str(ndm
->ndm_flags
, fbuf
, sizeof(fbuf
)),
1197 ndm
->ndm_type
, rtm_type2str(ndm
->ndm_type
));
1199 nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ndm
)));
1204 ifa
= NLMSG_DATA(nlmsg
);
1206 " ifa [family=(%d) %s prefixlen=%d "
1207 "flags=0x%04x {%s} scope=%d index=%u]",
1208 ifa
->ifa_family
, af_type2str(ifa
->ifa_family
),
1209 ifa
->ifa_prefixlen
, ifa
->ifa_flags
,
1210 if_flags2str(ifa
->ifa_flags
, fbuf
, sizeof(fbuf
)),
1211 ifa
->ifa_scope
, ifa
->ifa_index
);
1212 nlifa_dump(ifa
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
1215 case RTM_NEWNEXTHOP
:
1216 case RTM_DELNEXTHOP
:
1217 case RTM_GETNEXTHOP
:
1218 nhm
= NLMSG_DATA(nlmsg
);
1220 " nhm [family=(%d) %s scope=(%d) %s "
1221 "protocol=(%d) %s flags=0x%08x {%s}]",
1222 nhm
->nh_family
, af_type2str(nhm
->nh_family
),
1223 nhm
->nh_scope
, rtm_scope2str(nhm
->nh_scope
),
1224 nhm
->nh_protocol
, rtm_protocol2str(nhm
->nh_protocol
),
1226 nh_flags2str(nhm
->nh_flags
, fbuf
, sizeof(fbuf
)));
1227 nlnh_dump(nhm
, nlmsg
->nlmsg_len
- NLMSG_LENGTH(sizeof(*nhm
)));
1235 * Try to get the next header. There should only be more
1236 * messages if this header was flagged as MULTI, otherwise just
1239 nlmsg
= NLMSG_NEXT(nlmsg
, msglen
);
1240 if (NLMSG_OK(nlmsg
, msglen
) == 0)
1246 #endif /* NETLINK_DEBUG */