Skip to content

Problems with examples/new_rule.rs #176

@RussellStrong

Description

@RussellStrong

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions