com.apple.networkextension.filter-packet does not work

Hi,


I downloaded FilteringNetworkTraffic and added a FilterPacketProvider to intercept network packet with following info.plist:


<key>NEProviderClasses</key>

<dict>

<key>com.apple.networkextension.filter-packet</key>

<string>$(PRODUCT_MODULE_NAME).FilterPacketProvider</string>

</dict>


but the callback function and packetHandler closure do not work at all? thanks!


Accepted Reply

You can’t just change the extension point here. There’s a bunch of other things you need to do as well, including:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

When bringing up a new NetworkExtension (NE) provider, my experience is that it’s best to start by confirming whether your provider started executing at all. See this post for an example of how to do this.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks eskimo.

I tried and confirmed that FilterPacketProvider is not initialized at all.


override init() {

super.init()

os_log("filter packet provider init")

}


but it would be initialized if I change the filter-packet to filter-data in info.plist:

<key>NEProviderClasses</key>

<dict>

<key>com.apple.networkextension.filter-data</key>

<string>$(PRODUCT_MODULE_NAME).FilterPacketProvider</string>

</dict>

You can’t just change the extension point here. There’s a bunch of other things you need to do as well, including:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, eskimo.

I found the same yesterday, it works after changing filterPackets to true.

Hi,

Could you please post the working code of callback function, packetHandler closure and list of methods that we need to override. I am stuck with this.

Thanks.

Could you please post the working code

The problem here is your definition of “working”. If you want a ‘do nothing’ packet filter, you can get one by creating a new target from the template built in to Xcode. This gives you a file like this:

class FilterPacketProvider: NEFilterPacketProvider {

    override func startFilter(completionHandler: @escaping (Error?) -> Void) {

        packetHandler = { (context, interface, direction, packetBytes, packetLength) in
            return .allow
        }
        completionHandler(nil)
    }

    override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {

        // Add code here to tear down the filter
        completionHandler()
    }
}

If you want to do more than that, you’ll have to explain your requirements in more depth.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo,

Thanks for the code, really useful.

(a) W.r.t firewall I want to filter ICMP, IGMP protocol as well. With NEFilterDataProvider I can able to control only TCP and UDP protocols alone. So I am checking whether I can do that with NEFilterPacketProvider. If possible please let me know how to filter those NON TCP and UDP based protocols.


(b) How to extract data/info from packetBytes (UnsafeRawPointer) and NEFilterPacketContext provided by packetHandler closure


Thanks.

W.r.t firewall I want to filter ICMP, IGMP protocol as well. … So I am checking whether I can do that with

NEFilterPacketProvider
.

Packet filters work at the IP layer, and thus should see all IP packets. Take a look at WWDC 2019 Session 714 Network Extensions for the Modern Mac, and specifically the content around slide 20.

How to extract data/info from

packetBytes
(
UnsafeRawPointer
) and
NEFilterPacketContext
provided by
packetHandler
closure

The

packetBytes
parameter is just a pointer to the raw bytes of the packet. Most folks building network packet filters are quite familiar with such constructs. Are you more used to doing this sort of thing in a C-based language? If so, you don’t have to use Swift here. It’s perfectly fine to create a packet filter in Objective-C.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

In Plist NEProviderClasses:

com.apple.networkextension.filter-packet -> $(PRODUCT_MODULE_NAME).FilterPacketProvider


class FilterPacketProvider: NEFilterPacketProvider {
    
    override init() {

        super.init()
        os_log("filter packet provider init")

    }
  
    override func startFilter(completionHandler: @escaping (Error?) -> Void) {
        
        filterConfiguration.filterPackets = true
        filterConfiguration.filterPacketProviderBundleIdentifier = "com.example.apple-samplecode.SimpleFirewall2V8AEFFU8N.SimpleFirewallExtension"
        os_log("FilterPacketProvider::startFilter")
        packetHandler = { (context, interface, direction, packetBytes, packetLength) in
            os_log("FilterPacketProvider::allow")

            return .allow
        }
        completionHandler(nil)
    }
  
    override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
  
        // Add code here to tear down the filter
        completionHandler()
    }
}

I don't see any of the log messages. Am i still missing some parts?

I recommend that you use a unique log subsystem to make it easier to search for your log messages. For example:

final class PacketFilterProvider: NEFilterPacketProvider {

    override init() {
        os_log(.debug, log: self.log, "init")
        super.init()
    }

    private let log = OSLog(subsystem: "com.example.apple-samplecode.PacketFilterTest", category: "provider")

    …
}

That way I can search on my subsystem and see all my log messages, grouped by category.

If you still can’t see your log messages, it means that your provider isn’t even starting to load. There’s a whole world of ways that this can go wrong. First things first, are you sure your system extension started correctly? I have a similar log point at the start of

main
in my sysex so that I can confirm that it loaded.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks eskimo,

Had configuration issues now it is working.

@rishr can you share what's the configuration issue you faced?