自己写的netlink通信程序,使用strace的时候,发现不能解析负载数据,很不好分析。如下:
sendmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=44, type=0x26 /* NLMSG_??? */, flags=NLM_F_REQUEST|0x300, seq=0, pid=0}, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x0a\x00\x01\x00\x00\x00"}, iov_len=44}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 44
发现type显示为 NLMSG_???
对比发现tc程序使用strace程序,可以正常解析:
sendmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=40, type=RTM_GETQDISC, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1686654530, pid=0}, {tcm_family=AF_UNSPEC, tcm_ifindex=0, tcm_handle=0, tcm_parent=0, tcm_info=0}, {nla_len=4, nla_type=TCA_DUMP_INVISIBLE}}, iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
通过排查发现,需要:
1 套接字绑定
struct sockaddr_nl addr = {
.nl_family = AF_NETLINK,
.nl_pid = getpid(),
};
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(sock);
return -ERR_BIND;
}
2 sendmsg的时候,需要指定 msg_name
struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
struct iovec iov = {
.iov_base = (void *)buf,
.iov_len = buflen,
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
修改之后,可以正常解析netlink数据:
getpid() = 290
socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) = 4
bind(4, {sa_family=AF_NETLINK, nl_pid=290, nl_groups=00000000}, 12) = 0
sendmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base={{len=40, type=RTM_GETQDISC, flags=N
LM_F_REQUEST|NLM_F_DUMP, seq=1, pid=0}, {tcm_family=AF_UNSPEC, tcm_ifindex=0, tcm_handle=0, tcm_parent=0, tcm_info=0}, {nla_len=4, nla_type=TCA_DU
MP_INVISIBLE}}, iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 40
recvmsg(4, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=[{{len=148, type=RTM_NEWQDISC, flags
=NLM_F_MULTI, seq=1, pid=290}, {tcm_family=AF_UNSPEC, tcm_ifindex=if_nametoindex("lo"), tcm_handle=0, tcm_parent=4294967295, tcm_info=2}, [{{nla_l
en=12, nla_type=TCA_KIND}, "noqueue"}, {{nla_len=5, nla_type=TCA_HW_OFFLOAD}, 0}, {{nla_len=48, nla_type=TCA_STATS2}, [{{nla_len=20, nla_type=TCA_
STATS_BASIC}, {bytes=0, packets=0}}, {{nla_len=24, nla_type=TCA_STATS_QUEUE}, {qlen=0, backlog=0, drops=0, requeues=0, overlimits=0}}]}, {{nla_len
=44, nla_type=TCA_STATS}, {bytes=0, packets=0, drops=0, overlimits=0, bps=0, pps=0, qlen=0, backlog=0}}]}, {{len=180, type=RTM_NEWQDISC, flags=NLM
_F_MULTI, seq=1, pid=290}, {tcm_family=AF_UNSPEC, tcm_ifindex=if_nametoindex("veth1"), tcm_handle=65536, tcm_parent=4294967295, tcm_info=15}, [{{n
la_len=8, nla_type=TCA_KIND}, "htb"}, {{nla_len=36, nla_type=TCA_OPTIONS}, "\x18\x00\x02\x00\x11\x00\x03\x00\x0a\x00\x00\x00\x00\x50\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x08\x00\x05\x00\xe8\x03\x00\x00"}, {{nla_len=5, nla_type=TCA_HW_OFFLOAD}, 0}, {{nla_len=48, nla_type=TCA_STATS2}, [{{nl
a_len=20, nla_type=TCA_STATS_BASIC}, {bytes=0, packets=0}}, {{nla_len=24, nla_type=TCA_STATS_QUEUE}, {qlen=0, backlog=0, drops=0, requeues=0, over
limits=0}}]}, {{nla_len=44, nla_type=TCA_STATS}, {bytes=0, packets=0, drops=0, overlimits=0, bps=0, pps=0, qlen=0, backlog=0}}]}, {{len=148, type=
RTM_NEWQDISC, flags=NLM_F_MULTI, seq=1, pid=290}, {tcm_family=AF_UNSPEC, tcm_ifindex=if_nametoindex("br-lan"), tcm_handle=0, tcm_parent=4294967295
, tcm_info=2}, [{{nla_len=12, nla_type=TCA_KIND}, "noqueue"}, {{nla_len=5, nla_type=TCA_HW_OFFLOAD}, 0}, {{nla_len=48, nla_type=TCA_STATS2}, [{{nl
a_len=20, nla_type=TCA_STATS_BASIC}, {bytes=0, packets=0}}, {{nla_len=24, nla_type=TCA_STATS_QUEUE}, {qlen=0, backlog=0, drops=0, requeues=0, over
limits=0}}]}, {{nla_len=44, nla_type=TCA_STATS}, {bytes=0, packets=0, drops=0, overlimits=0, bps=0, pps=0, qlen=0, backlog=0}}]}], iov_len=32768}]
, msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 476