Reading packets with NEPacketTunnelProvider without proxy

Viewed 1746

I would like to inspect packets with NEPacketTunnelProvider without a specified proxy. Unfortunately my readPacketObjects completion handler is never being called and I don't understand why. My regular internet connection stops and Wireshark shows nothing on the new interface obviously and I don't see any of my HTTP connection on en0 either.

Is this possible? Apple Developer Forums suggests it might not be... but Charles Proxy for iOS seems to be able to inspect everything.

My code is below:

class TunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]? = nil, completionHandler: @escaping (Error?) -> Void) {
    os_log("starting tunnel")

    let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")

    settings.tunnelOverheadBytes = 80
    settings.mtu = 1200

    settings.ipv4Settings = NEIPv4Settings(addresses: ["127.0.0.1", "0.0.0.0"], subnetMasks: ["0.0.0.0", "0.0.0.0"]) // all addresses
    settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()] // all routes
    settings.ipv4Settings?.excludedRoutes = [NEIPv4Route(destinationAddress: "127.0.0.1", subnetMask: "255.255.255.255")] // avoid local routes

    settings.dnsSettings = NEDNSSettings(servers: ["1.1.1.1", "8.8.8.8", "8.8.4.4"])
    settings.dnsSettings?.matchDomains = [""] // if blank don't use this DNS, use system; if "" then use this

    NSLog("default/included route %@:%@", NEIPv4Route.default().destinationAddress, NEIPv4Route.default().destinationSubnetMask)

    self.setTunnelNetworkSettings(settings) { error in
        if let e = error {
            NSLog("Settings error %@", e.localizedDescription)
            completionHandler(e)
        } else {
            os_log("Settings set without error")

            completionHandler(nil)
        }
    }

    self.readPacketObjects()
}

private func readPacketObjects() {
    NSLog("Inside readPacketObjects %@", self.packetFlow)
    self.packetFlow.readPacketObjects() { packets in
        NSLog("Inside readPacketObjects completionHandler %@", packets)

        self.packetFlow.writePacketObjects(packets)

        self.readPacketObjects()
    }
}

Console output

default 10:31:03.177424 -0400   tunnel  starting tunnel
default 10:31:03.177796 -0400   tunnel  default/included route 0.0.0.0:0.0.0.0
default 10:31:03.178602 -0400   tunnel  Inside readPacketObjects <NEPacketTunnelFlow: 0x7f9a69d135e0>
default 10:31:03.356006 -0400   tunnel  Settings set without error

Edit 1
I am able to read packets after modifying settings.ipv4Settings to a local address with a more specific subnet mask. However the internet connection is still down and route get outputs bad address.

Edit 2
I was able to get DNS to work by adding the DNS servers to the excludedRoutes as seen here. Writing to the packetFlow with no modifications still doesn't enable full routing tho.

0 Answers
Related