multicast.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. mod utils;
  2. use std::os::unix::io::AsRawFd;
  3. use smoltcp::iface::{Config, Interface, SocketSet};
  4. use smoltcp::phy::{wait as phy_wait, Device, Medium};
  5. use smoltcp::socket::{raw, udp};
  6. use smoltcp::time::Instant;
  7. use smoltcp::wire::{
  8. EthernetAddress, IgmpPacket, IgmpRepr, IpAddress, IpCidr, IpProtocol, IpVersion, Ipv4Address,
  9. Ipv4Packet, Ipv6Address,
  10. };
  11. const MDNS_PORT: u16 = 5353;
  12. const MDNS_GROUP: Ipv4Address = Ipv4Address::new(224, 0, 0, 251);
  13. fn main() {
  14. utils::setup_logging("warn");
  15. let (mut opts, mut free) = utils::create_options();
  16. utils::add_tuntap_options(&mut opts, &mut free);
  17. utils::add_middleware_options(&mut opts, &mut free);
  18. let mut matches = utils::parse_options(&opts, free);
  19. let device = utils::parse_tuntap_options(&mut matches);
  20. let fd = device.as_raw_fd();
  21. let mut device =
  22. utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
  23. // Create interface
  24. let mut config = match device.capabilities().medium {
  25. Medium::Ethernet => {
  26. Config::new(EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]).into())
  27. }
  28. Medium::Ip => Config::new(smoltcp::wire::HardwareAddress::Ip),
  29. Medium::Ieee802154 => todo!(),
  30. };
  31. config.random_seed = rand::random();
  32. let mut iface = Interface::new(config, &mut device, Instant::now());
  33. iface.update_ip_addrs(|ip_addrs| {
  34. ip_addrs
  35. .push(IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24))
  36. .unwrap();
  37. ip_addrs
  38. .push(IpCidr::new(IpAddress::v6(0xfdaa, 0, 0, 0, 0, 0, 0, 1), 64))
  39. .unwrap();
  40. ip_addrs
  41. .push(IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 0, 0, 0, 1), 64))
  42. .unwrap();
  43. });
  44. iface
  45. .routes_mut()
  46. .add_default_ipv4_route(Ipv4Address::new(192, 168, 69, 100))
  47. .unwrap();
  48. iface
  49. .routes_mut()
  50. .add_default_ipv6_route(Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0x100))
  51. .unwrap();
  52. // Create sockets
  53. let mut sockets = SocketSet::new(vec![]);
  54. // Must fit at least one IGMP packet
  55. let raw_rx_buffer = raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; 2], vec![0; 512]);
  56. // Will not send IGMP
  57. let raw_tx_buffer = raw::PacketBuffer::new(vec![], vec![]);
  58. let raw_socket = raw::Socket::new(
  59. IpVersion::Ipv4,
  60. IpProtocol::Igmp,
  61. raw_rx_buffer,
  62. raw_tx_buffer,
  63. );
  64. let raw_handle = sockets.add(raw_socket);
  65. // Must fit mDNS payload of at least one packet
  66. let udp_rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY; 4], vec![0; 1024]);
  67. // Will not send mDNS
  68. let udp_tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 0]);
  69. let udp_socket = udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
  70. let udp_handle = sockets.add(udp_socket);
  71. // Join a multicast group to receive mDNS traffic
  72. iface.join_multicast_group(MDNS_GROUP).unwrap();
  73. loop {
  74. let timestamp = Instant::now();
  75. iface.poll(timestamp, &mut device, &mut sockets);
  76. let socket = sockets.get_mut::<raw::Socket>(raw_handle);
  77. if socket.can_recv() {
  78. // For display purposes only - normally we wouldn't process incoming IGMP packets
  79. // in the application layer
  80. match socket.recv() {
  81. Err(e) => println!("Recv IGMP error: {e:?}"),
  82. Ok(buf) => {
  83. Ipv4Packet::new_checked(buf)
  84. .and_then(|ipv4_packet| IgmpPacket::new_checked(ipv4_packet.payload()))
  85. .and_then(|igmp_packet| IgmpRepr::parse(&igmp_packet))
  86. .map(|igmp_repr| println!("IGMP packet: {igmp_repr:?}"))
  87. .unwrap_or_else(|e| println!("parse IGMP error: {e:?}"));
  88. }
  89. }
  90. }
  91. let socket = sockets.get_mut::<udp::Socket>(udp_handle);
  92. if !socket.is_open() {
  93. socket.bind(MDNS_PORT).unwrap()
  94. }
  95. if socket.can_recv() {
  96. socket
  97. .recv()
  98. .map(|(data, sender)| {
  99. println!("mDNS traffic: {} UDP bytes from {}", data.len(), sender)
  100. })
  101. .unwrap_or_else(|e| println!("Recv UDP error: {e:?}"));
  102. }
  103. phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
  104. }
  105. }