Search code examples
socketsnetworkingrustudpdhcp

Receiving DHCPv6 messages in Rust


I'm trying to receive dhcp6 messages in rust. This is the code I have right now:

use std::net::UdpSocket;
use std::net::Ipv6Addr;

fn main() -> std::io::Result<()> {
    {
        let socket = UdpSocket::bind("[::]:547")?;
        let mult: Ipv6Addr = "ff02::1:2".parse().unwrap();
        socket.join_multicast_v6(&mult, 0)?;
        let mut buf = [0; 65_535];
        let (amt, src) = socket.recv_from(&mut buf)?;
        let res = parser::header(&buf).unwrap();
        println!("{:?}", res);
    }
    Ok(())
}

It manages to receive unicast messages sent with e.g. echo "Hello"| socat -t 10 - udp6:[::1]:547, which show up in tcpdump as IP6 localhost.57028 > localhost.dhcpv6-server: dhcp6 msgtype-72, but for dhcp6 messages (which show up as e.g. IP6 fe80::20e:7bff:febb:a38a.dhcpv6-client > ff02::1:2.dhcpv6-server: dhcp6 solicit in tcpdump), no data is received.

Am I missing something ?


Solution

  • The problem was the following line:

    socket.join_multicast_v6(&mult, 0)?;
    

    The manual states:

    This function specifies a new multicast group for this socket to join. The address must be a valid multicast address, and interface is the index of the interface to join/leave (or 0 to indicate any interface).

    Unfortunately, I read "any interface" as "this will work on all interfaces", which is probably not the case.

    Using for example if_nametoindex("eth1") from the nix crate to resolve the interface name to the interface index worked for me.