https://github.com/n0-computer/iroh/issues/2306

--- cargo-crates/iroh-net-0.16.2/src/net/interfaces/bsd.rs.orig	2006-07-24 01:21:28 UTC
+++ cargo-crates/iroh-net-0.16.2/src/net/interfaces/bsd.rs
@@ -14,6 +14,8 @@ use macos::*;
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 use macos::*;
+#[cfg(target_os = "freebsd")]
+use freebsd::*;
 
 pub async fn default_route() -> Option<DefaultRouteDetails> {
     let idx = default_route_interface_index()?;
@@ -82,6 +84,7 @@ fn is_default_gateway(rm: &RouteMessage) -> bool {
         return false;
     }
 
+#[cfg(any(target_os = "macos", target_os = "ios"))]
     if rm.flags & libc::RTF_IFSCOPE as u32 != 0 {
         return false;
     }
@@ -128,7 +131,16 @@ fn parse_routing_table(rib: &[u8]) -> Option<Vec<Route
 #[cfg(any(target_os = "freebsd", target_os = "openbsd", target_os = "netbsd",))]
 fn parse_routing_table(rib: &[u8]) -> Option<Vec<RouteMessage>> {
     match parse_rib(libc::NET_RT_IFLIST, rib) {
-        Ok(res) => Some(res),
+        Ok(res) => {
+            let res = res
+                .into_iter()
+                .filter_map(|m| match m {
+                    WireMessage::Route(r) => Some(r),
+                    _ => None,
+                })
+                .collect();
+            Some(res)
+        }
         Err(err) => {
             warn!("parse_rib failed: {:?}", err);
             None
@@ -178,7 +190,7 @@ const fn is_valid_rib_type(typ: RIBType) -> bool {
     true
 }
 
-#[cfg(any(target_os = "free", target_os = "netbsd"))]
+#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
 const fn is_valid_rib_type(typ: RIBType) -> bool {
     true
 }
@@ -305,9 +317,9 @@ impl WireFormat {
                     return Err(RouteError::InvalidMessage);
                 }
 
-                #[cfg(target_arch = "netbsd")]
+                #[cfg(target_os = "netbsd")]
                 let index = u16_from_ne_range(data, 16..18)?;
-                #[cfg(not(target_arch = "netbsd"))]
+                #[cfg(not(target_os = "netbsd"))]
                 let index = u16_from_ne_range(data, 12..14)?;
 
                 let addrs = parse_addrs(
@@ -594,6 +606,116 @@ mod macos {
             (libc::RTM_IFINFO2, ifm2),
             (libc::RTM_NEWMADDR2, ifmam2),
             (libc::RTM_GET2, rtm2),
+        ]
+        .into_iter()
+        .collect();
+
+        RoutingStack {
+            rtm_version,
+            wire_formats,
+            kernel_align: 4,
+        }
+    }
+}
+
+#[cfg(target_os = "freebsd")]
+mod freebsd {
+    use super::*;
+
+    // Hardcoded based on the generated values here: https://cs.opensource.google/go/x/net/+/master:route/zsys_freebsd_amd64.go
+
+    pub(super) const SIZEOF_IF_MSGHDRL_FREEBSD10: usize = 0xb0; // 0x68 for target_pointer_width = 32
+    pub(super) const SIZEOF_IFA_MSGHDR_FREEBSD10: usize = 0x14;
+    pub(super) const SIZEOF_IFA_MSGHDRL_FREEBSD10: usize = 0xb0; // 0x6c for target_pointer_width = 32
+    pub(super) const SIZEOF_IFMA_MSGHDR_FREEBSD10: usize = 0x10;
+    pub(super) const SIZEOF_IF_ANNOUNCEMSGHDR_FREEBSD10: usize = 0x18;
+
+    pub(super) const SIZEOF_RT_MSGHDR_FREEBSD10: usize = 0x98; // 0x5c for target_pointer_width = 32
+    pub(super) const SIZEOF_RT_METRICS_FREEBSD10: usize = 0x70; // 0x38 for target_pointer_width = 32
+
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD7: usize = 0xa8; // 0x60 for target_arch = x86, 0x70 for target_arch = arm
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD8: usize = 0xa8; // 0x60 for target_arch = x86, 0x70 for target_arch = arm
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD9: usize = 0xa8; // 0x60 for target_arch = x86, 0x70 for target_arch = arm
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD10: usize = 0xa8; // 0x64 (!) for target_arch = x86, 0x70 for target_arch = arm
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD11: usize = 0xa8;
+
+    pub(super) const SIZEOF_IF_DATA_FREEBSD7: usize = 0x98; // 0x50 for target_arch = x86, 0x60 for target_arch = arm
+    pub(super) const SIZEOF_IF_DATA_FREEBSD8: usize = 0x98; // 0x50 for target_arch = x86, 0x60 for target_arch = arm
+    pub(super) const SIZEOF_IF_DATA_FREEBSD9: usize = 0x98; // 0x50 for target_arch = x86, 0x60 for target_arch = arm
+    pub(super) const SIZEOF_IF_DATA_FREEBSD10: usize = 0x98; // 0x54 (!) for target_arch = x86, 0x60 for target_arch = arm
+    pub(super) const SIZEOF_IF_DATA_FREEBSD11: usize = 0x98;
+
+    pub(super) const SIZEOF_IF_MSGHDRL_FREEBSD10_EMU: usize = 0xb0;
+    pub(super) const SIZEOF_IFA_MSGHDR_FREEBSD10_EMU: usize = 0x14;
+    pub(super) const SIZEOF_IFA_MSGHDRL_FREEBSD10_EMU: usize = 0xb0;
+    pub(super) const SIZEOF_IFMA_MSGHDR_FREEBSD10_EMU: usize = 0x10;
+    pub(super) const SIZEOF_IF_ANNOUNCEMSGHDR_FREEBSD10_EMU: usize = 0x18;
+
+    pub(super) const SIZEOF_RT_MSGHDR_FREEBSD10_EMU: usize = 0x98;
+    pub(super) const SIZEOF_RT_METRICS_FREEBSD10_EMU: usize = 0x70;
+
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD7_EMU: usize = 0xa8;
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD8_EMU: usize = 0xa8;
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD9_EMU: usize = 0xa8;
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD10_EMU: usize = 0xa8;
+    pub(super) const SIZEOF_IF_MSGHDR_FREEBSD11_EMU: usize = 0xa8;
+
+    pub(super) const SIZEOF_IF_DATA_FREEBSD7_EMU: usize = 0x98;
+    pub(super) const SIZEOF_IF_DATA_FREEBSD8_EMU: usize = 0x98;
+    pub(super) const SIZEOF_IF_DATA_FREEBSD9_EMU: usize = 0x98;
+    pub(super) const SIZEOF_IF_DATA_FREEBSD10_EMU: usize = 0x98;
+    pub(super) const SIZEOF_IF_DATA_FREEBSD11_EMU: usize = 0x98;
+
+    pub(super) const SIZEOF_SOCKADDR_STORAGE: usize = 0x80;
+    pub(super) const SIZEOF_SOCKADDR_INET: usize = 0x10;
+    pub(super) const SIZEOF_SOCKADDR_INET6: usize = 0x1c;
+
+    pub(super) fn probe_routing_stack() -> RoutingStack {
+        let rtm_version = libc::RTM_VERSION;
+
+        let rtm = WireFormat {
+            ext_off: SIZEOF_RT_MSGHDR_FREEBSD10,
+            body_off: SIZEOF_RT_MSGHDR_FREEBSD10,
+            typ: MessageType::Route,
+        };
+        let ifm = WireFormat {
+            ext_off: SIZEOF_IF_MSGHDR_FREEBSD11,
+            body_off: SIZEOF_IF_MSGHDR_FREEBSD11,
+            typ: MessageType::Interface,
+        };
+        let ifam = WireFormat {
+            ext_off: SIZEOF_IFA_MSGHDR_FREEBSD10,
+            body_off: SIZEOF_IFA_MSGHDR_FREEBSD10,
+            typ: MessageType::InterfaceAddr,
+        };
+        let ifmam = WireFormat {
+            ext_off: SIZEOF_IFMA_MSGHDR_FREEBSD10,
+            body_off: SIZEOF_IFMA_MSGHDR_FREEBSD10,
+            typ: MessageType::InterfaceMulticastAddr,
+        };
+        let ifannm = WireFormat {
+            ext_off: SIZEOF_IF_ANNOUNCEMSGHDR_FREEBSD10,
+            body_off: SIZEOF_IF_ANNOUNCEMSGHDR_FREEBSD10,
+            typ: MessageType::Interface,
+        };
+
+        let wire_formats = [
+            (libc::RTM_ADD, rtm),
+            (libc::RTM_DELETE, rtm),
+            (libc::RTM_CHANGE, rtm),
+            (libc::RTM_GET, rtm),
+            (libc::RTM_LOSING, rtm),
+            (libc::RTM_REDIRECT, rtm),
+            (libc::RTM_MISS, rtm),
+            (libc::RTM_LOCK, rtm),
+            (libc::RTM_RESOLVE, rtm),
+            (libc::RTM_NEWADDR, ifam),
+            (libc::RTM_DELADDR, ifam),
+            (libc::RTM_IFINFO, ifm),
+            (libc::RTM_NEWMADDR, ifmam),
+            (libc::RTM_DELMADDR, ifmam),
+            (libc::RTM_IFANNOUNCE, ifannm),
+            (libc::RTM_IEEE80211, ifannm),
         ]
         .into_iter()
         .collect();
