Calling a NEProvider directly

I need to a NEProvider directly inside a command line tool, particularly, the NEFilterDataProvider, and found that what was calling was the NEFilterDataExtensionProviderContext class, but it seems like Apple has it blocked off. Is there any way that I can do this? Thanks

I need to a NEProvider directly inside a command line tool

This question makes no sense from an architecture perspective. NEProvider is the base class for the various Network Extension providers. These providers are instantiated inside an extension (an app extension or, on the Mac, a system extension) when the system needs their services. You don’t call this class directly, but rather you subclass it (well, you subclass one of its provider-specific subclasses) and the system calls you.

What do you hope to achieve by calling NEProvider from your command-line tool.

Share and Enjoy

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

What do you hope to achieve by calling NEProvider from your command-line tool.

My goal is to be able to call and run it directly inside the debugger. Plus it has to do with a project that is already written as a command line tool (daemon) and it might be easier to simply have it written inside there so that when the daemon is stopped, the NEFilterDataProvider is stopped as well.

I already tried calling [NEFilterDataExtensionProviderContext startFilterWithOptions:completionHandler:]  directly, but it appears that I can't access this class directly. Any ideas?

I've tried simply running:

#import <Foundation/Foundation.h>
#import <NetworkExtension/NetworkExtension.h>

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    // insert code here...
     
    [NEProvider startSystemExtensionMode];
     
    NSLog(@"Hello, World!");
  }
  dispatch_main();
}

And I got this message in the print:

Bogus event on event stream listener.

Here are my entitlements:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<false/>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>packet-tunnel-provider</string>
		<string>app-proxy-provider</string>
		<string>content-filter-provider</string>
		<string>dns-proxy</string>
	</array>
</dict>
</plist>

And the Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>NetworkExtension</key>
	<dict>
		<key>NEMachServiceName</key>
		<string>$(TeamIdentifierPrefix).SimpleContentFilterExtension</string>
		<key>NEProviderClasses</key>
		<dict>
			<key>com.apple.networkextension.filter-data</key>
			<string>$(PRODUCT_MODULE_NAME).FilterDataProvider</string>
		</dict>
	</dict>
</dict>
</plist>

Any ideas?

My goal is to be able to call and run it directly inside the debugger.

OK.

Plus it has to do with a project that is already written as a command line tool (daemon) and it might be easier to simply have it written inside there

OK.

Neither of these are feasible. The NEProvider architecture only works in the context of an NE appex (or sysex on the Mac). If you try to create a provider outside of that context, the necessary plumbing is absent and the provider simply won’t work.

On the debugging front, my favourite trick is to add a pause system call to the start of my provider. It seems like you’re working with a sysex on the Mac, so that means the start of main. That lets you attach with the debugger and then debug from there [1].

Share and Enjoy

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

[1] The only gotcha here is that you can’t debug stuff that runs before main, but the mechanisms to run code before main (framework initialisers, Objective-C +load methods, and C++ static initialisers) are generally considered poor form anyway.

Calling a NEProvider directly
 
 
Q