I've been exploring custom IP protocols with Network.framework on macOS and have run into a couple of problems:
Loopback & bridge interfaces
let parameters = NWParameters(customIPProtocolNumber: 123)
let destination = NWEndpoint.hostPort(host: "127.0.0.1", port: 0)
let connection = NWConnection(to: destination, using: parameters)
connection.start(queue: .main)
connection.send(content: Data([1, 2, 3, 4]), completion: .contentProcessed({ error in
print("error", error)
}))
Yields this error when host
is directly connected to a virtual interface like bridge100
(the other end of my connection is a Linux VM) or lo0
(as in the example above):
[connection] nw_socket_connect [C1:1] connectx(12 (guarded), [srcif=0, srcaddr=<NULL>, dstaddr=127.0.0.1], SAE_ASSOCID_ANY, 0, NULL, 0, NULL, SAE_CONNID_ANY) failed: [49: Can't assign requested address]
If I change host
to an address directly connected to en0 (my MacBook's Wi-Fi), I get no errors, and I can see the packet in Wireshark.
Multicast listeners
guard let allSPFRouters = try? NWMulticastGroup(for: [NWEndpoint.hostPort(host: "224.0.0.5", port: 0)]) else {
print("Couldn't create NWMulticastGroup")
return
}
let parameters = NWParameters(customIPProtocolNumber: 123)
let group = NWConnectionGroup(with: allSPFRouters, using: parameters)
group.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: true) { (message, content, isComplete) in
print("received", message, content, isComplete)
}
group.stateUpdateHandler = { print("state", $0) }
group.start(queue: .main)
Yields a number of errors, of which this one seems like the most relevant:
-[nw_listener_inbox_socket initWithParameters:delegate:] Cannot create listener with IP Protocol 123, dumping backtrace:
I did some spelunking in Ghidra, and it seems like nw_listener_inbox_socket_initWithParameters:delegate:
might only allows you to join a multicast group if your protocol number is 6 (TCP) or 17 (UDP).
So, the questions are:
- Is there something obvious I’m doing wrong?
- Are there any clever workarounds?
Here’s a repo with a repro. All the relevant code is in AppDelegate.swift. Tested on macOS 13.0.1 on a 14-inch MacBook Pro, with App Sandbox and Hardened Runtime disabled and an Xcoded-managed provisioning profile with the com.apple.developer.networking.custom-protocol entitlement.
Thanks in advance!