I'm trying to implement a packet sniffer similar to Charles for iOS using iOS's NetworkExtension framework.
Objective
So, that's a big goal and I'm breaking it down into a tiny piece right now: I want to see the os_log
from my NEPacketTunnelProvider
(bottom box in diagram)
What I have done so far
- I have created a NetworkExtension target on type PacketTunnel. This is the code snippet in the 3rd box in the diagram titled "NEPacketTunnelProvider".
- I have included the "app groups", "personal VPN", and "Network extension" capabilities from within XCode.
Question
I am looking in the Console.app to see the output from os_log("STARTING TUNNEL!!!!")
. When I load the configuration and make the call to startVPNTunnel()
, why is my TunnelProvider code never called?
I have verified that startVPNTunnel()
is being called by placing a breakpoint in my code.
There are a good number of reasons why your network extension process may not be starting:
- I would put a breakpoint on the
os_log("STARTING TUNNEL!!!!")
and attach to your network extension process in Xcode via Debug -> Attach to Process by PID or Name...
before you attempt to start the VPN
- The network extension must extend the bundle id of the containing app. E.g. if the containing app is
com.example.vpn
then the network extension might be com.example.vpn.tunnel
.
- Ensure that your Network Extension
Info.plist
contains the NSExtension
dictionary with NSExtensionPointIdentifier
and NSExtensionPrincipalClass
containing com.apple.networkextension.packet-tunnel
and your NEPacketTunnelProvider
class (e.g. $(PRODUCT_MODULE_NAME).PacketTunnelProvider
) respectively.
- Is the Packet Tunnel Provider Network Extension entitlement applied to both the containing application and the network extension?
- If you are implementing a Packet Tunnel Provider, you do not want to enable the
Personal VPN
entitlement.
in startVPNTunnel func ,you should call setTunnelNetworkSettings,then the tunnel will started, after that ,you can read/write packet.
setTunnelNetworkSettings(nil) { error in
pendingStartCompletion(error)
}