-
Notifications
You must be signed in to change notification settings - Fork 64
Description
netlink-packet-route examples/new_rule.rs
running as is:
NetlinkMessage { header: NetlinkHeader { length: 60, message_type: 32, flags: 1541, sequence_number: 0, port_number: 0 }, payload: InnerMessage(NewRule(RuleMessage { header: RuleHeader { family: Inet, dst_len: 0, src_len: 0, tos: 0, table: 254, action: ToTable, flags: RuleFlags(0x0) }, attributes: [Table(254), SuppressPrefixLen(4294967295), Priority(1000), Protocol(Kernel)] })) }
<<< Err(DecodeError { inner: invalid netlink buffer: length field says 0 but netlink packets are at least 4132 bytes })
First problem: send is sending too much data.
It is sending the entire buffer rather than just the serialized netlink message.
strace shows:
sendto(3, [[{nlmsg_len=60, nlmsg_type=RTM_NEWRULE, nlmsg_flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, nlmsg_seq=0, nlmsg_pid=0}, {family=AF_INET, dst_len=0, src_len=0, tos=0, table=RT_TABLE_MAIN, action=FR_ACT_TO_TBL, flags=0}, [[{nla_len=8, nla_type=FRA_TABLE}, RT_TABLE_MAIN], [{nla_len=8, nla_type=FRA_SUPPRESS_PREFIXLEN}, 4294967295], [{nla_len=8, nla_type=FRA_PRIORITY}, 1000], [{nla_len=5, nla_type=FRA_PROTOCOL}, RTPROT_KERNEL]]], {nlmsg_len=0, nlmsg_type=0 /* NLMSG_??? */, nlmsg_flags=0, nlmsg_seq=0, nlmsg_pid=0}], 8192, 0, NULL, 0) = 8192
changed statement as line 49:
socket
.send(&buf, 0)
.expect("failed to send netlink message");
to:
socket
.send(&buf[..msg.buffer_len()], 0)
.expect("failed to send netlink message");
strace now shows:
sendto(3, [{nlmsg_len=60, nlmsg_type=RTM_NEWRULE, nlmsg_flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, nlmsg_seq=0, nlmsg_pid=0}, {family=AF_INET, dst_len=0, src_len=0, tos=0, table=RT_TABLE_MAIN, action=FR_ACT_TO_TBL, flags=0}, [[{nla_len=8, nla_type=FRA_TABLE}, RT_TABLE_MAIN], [{nla_len=8, nla_type=FRA_SUPPRESS_PREFIXLEN}, 4294967295], [{nla_len=8, nla_type=FRA_PRIORITY}, 1000], [{nla_len=5, nla_type=FRA_PROTOCOL}, RTPROT_KERNEL]]], 60, 0, NULL, 0) = 60
Second problem: received size does not match header size
socket.recv is appending data to a buffer full of zeros giving a received buffer length
of 4132 instead of something smaller. _size on line 55 has a value of 80.
changing:
let mut receive_buffer = vec![0; 4096];
to
let mut receive_buffer = vec![];
This now has _size on line 55 with a value of 64. Why is this not 80 as before?
Decoding still fails:
<<< Err(DecodeError { inner: invalid netlink buffer: length field says 80 the buffer is 64 bytes long })
Interesting that the header length is 80....
Trying to override the header length to 64...
It now decodes
NetlinkMessage { header: NetlinkHeader { length: 60, message_type: 32, flags: 1541, sequence_number: 0, port_number: 0 }, payload: InnerMessage(NewRule(RuleMessage { header: RuleHeader { family: Inet, dst_len: 0, src_len: 0, tos: 0, table: 254, action: ToTable, flags: RuleFlags(0x0) }, attributes: [Table(254), SuppressPrefixLen(4294967295), Priority(1000), Protocol(Kernel)] })) }
64
<<< Ok(NetlinkMessage { header: NetlinkHeader { length: 64, message_type: 2, flags: 0, sequence_number: 0, port_number: 6481 }, payload: Error(ErrorMessage { code: Some(-17), header: [60, 0, 0, 0, 32, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 254, 0, 0, 1, 0, 0, 0, 0, 8, 0, 15, 0, 254, 0, 0, 0, 8, 0, 14, 0, 255, 255, 255, 255] }) })
ErrorMessage { code: Some(-17), header: [60, 0, 0, 0, 32, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 254, 0, 0, 1, 0, 0, 0, 0, 8, 0, 15, 0, 254, 0, 0, 0, 8, 0, 14, 0, 255, 255, 255, 255] }
What is happening here?
Is 64 the correct length here and the kernel has a bug?