Filtering IPPROTO_ICMP and IPPROTO_RAW using NetworkExtension

Hi,
I am trying to create an app that filters network events - whether to collect statistics, or to even block some specific flows.

I see that using NEFilterDataProvider I am able to only filter UDP or TCP protocols (when filtering by .any, I see I only receive UDP/TCP). For example, I wish to see the flow of a simple ping 1.1.1.1.
This of course makes the statistics partial (without ICMP packet/raw socket packets), or the flow block being bypass-able (even if with some effort), by using Raw sockets.

Is there a way to add to the filtering also ICMP and RAW flows? Should I use a different provider for those?

Accepted Reply

Filter data providers only see TCP and UDP flows. Filter packet providers see all packets.

Also, in what way can I get packet type in PacketProvider?

Your packet handler function is called with a pointer and length (the packetBytes and packetLength parameters) that denote the entire packet, including link-level header and, assuming it’s IP, the IP header.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Replies

I am trying to create an app that filters network events

What platform are you working on?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Sorry, I forgot to mention that part - macOS
AFAIK, NEFilterPacketProvider should allow you to see all the IPPROTO_ you want.
Thought that too, but I do not see any new flow when calling ping.
Same as with raw sockets.

EDIT: saw you wrote NEFilterPacketProvider. It is not possible using DataProvider?
Also, in what way can I get packet type in PacketProvider?
Filter data providers only see TCP and UDP flows. Filter packet providers see all packets.

Also, in what way can I get packet type in PacketProvider?

Your packet handler function is called with a pointer and length (the packetBytes and packetLength parameters) that denote the entire packet, including link-level header and, assuming it’s IP, the IP header.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks! That will solve our issues with that. Is there a way to extract source app for a packet with packet filter? I see there is a context, but I'm not sure what and how we can extract from it.

Is there a way to extract source app for a packet with packet filter?

I’m not sure.

I see there is a context

Indeed. The context parameter will not give you packet metadata directly. However, you can use it to delay the packet. This results in an NEPacket object and you can try getting metadata from that. However, based on this thread I suspect that won’t help you.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Filter data providers only see TCP and UDP flows.

Is this really the case? I also have a NEFilterDataProvider and until now I got ICMP (remote endpoint 192.168.1.1), ICMP6 (remote endpoint ff02::2), TCP and UDP flows.

Presumably these are NEFilterSocketFlow. What values do you see in socketFamily, socketType, and socketProtocol?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Sorry for my late reply, again I wasn't notified of your response despite watching this thread.

Yes, they are NEFilterSocketFlow. I just got 2 outbound flows from local :: to remote ff02::2 (both port 0) by /usr/libexec/configd: socketType = SOCK_RAW, socketFamily = AF_INET6, socketProtocol = IPPROTO_ICMPV6.

While I was writing my earlier answer I just got 10 new flows from 0.0.0.0 to 192.168.1.1 by /sbin/ping: socketType = SOCK_RAW, socketFamily = AF_INET, socketProtocol = IPPROTO_ICMP.

Filter data providers only see TCP and UDP flows. Filter packet providers see all packets.

I am working on the similar project but for iOS and so far I was able to intercept all UDP/TCP flows, however ICMP packets are still going through (I am using Network Tools app to send ping requests).
Is it possible to intercept all packets on iOS as well?