Enabling IP Packet Sending/Receiving in Swift Without Root Privilege

I've been working with NIORawSocketBootstrap to send and receive IP packets, such as ICMP pings, in Swift. However, I've encountered an issue: this approach requires root privileges on macOS and Linux. I'm wondering if there's a way to achieve similar functionality while using .datagram as the socketType and still supporting various protocolSubtype , such as .icmp .

In my current local fork of swift-nio, I have the following code snippet in the makeChannel() function:

return try DatagramChannel(eventLoop: eventLoop,
                            protocolFamily: address.protocol,
                            protocolSubtype: .init(ipProtocol),
                            socketType: .datagram)

Is there a way to make this work without requiring root privilege? If not, do you have any suggestions or alternatives for sending and receiving IP packets securely in Swift? I appreciate any insights!

Thanks in advance!

Unfortunately I believe sending raw IP packets always requires root privilege.

The only alternative I can think of is spawning a utun, I believe that doesn't require root. If you are able to give it an IP, it could do the communication for you. But it's quite some fiddling.

Thank you for the clarification. In the context of ICMP , I'm curious if Swift-NIO currently supports or plans to support socket capabilities for both root and non-root users, similar to the functionality available in C.

Regarding the NIORawSocketBootstrap , it would be more user-friendly if it allowed user to select socketType (.raw or .datagram ) rather than being fixed on a raw socket as it currently is.

For instance, in C, you can achieve this functionality for non-root users with the following code:

socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP) // for non-root user

Swift-NIO currently supports the following in NIORawSocketBootstrap



Thanks for the suggestion!

Yes, we'd be open to adding this support. Can you file an issue please?

1 Like

sounds good!