Hi! I am trying to build a network system extension with NEPacketTunnelProvider. Actually, I want to see all outgoing packets. So, here is my config for NETunnelProviderManager:
let protocolConfiguration = NETunnelProviderProtocol()
protocolConfiguration.providerBundleIdentifier = "bundle id"
protocolConfiguration.serverAddress = "ip address"
protocolConfiguration.providerConfiguration = [:]
manager.protocolConfiguration = protocolConfiguration
manager.isEnabled = true
manager.localizedDescription = "SamplePacketTunnel"
Currently, I want to see logs from packetFlow.readPackets
. I understand that without opening the connection to the server and writing to it, I would see the absence of the Internet on my machine. However, I don't want to create the whole system for my vpn tunnel for now.
The source code inside NEPacketTunnelProvider looks like:
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
os_log(.debug, log: self.log, "Tunnel started")
let tunnelSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "same address as in protocol configuration")
let ipv4Settings = NEIPv4Settings.init(addresses: ["my local ip"], subnetMasks: ["255.255.255.0"])
var includedRoutes: [NEIPv4Route] = []
includedRoutes.append(NEIPv4Route.default())
ipv4Settings.includedRoutes = includedRoutes
tunnelSettings.ipv4Settings = ipv4Settings
setTunnelNetworkSettings(tunnelSettings) { error in
if let error = error {
os_log(.debug, log: self.log, "Error on tunnel start: %@", error.localizedDescription)
completionHandler(error)
return
}
os_log(.debug, log: self.log, "No errors on setTunnelNetworkSettings")
completionHandler(nil)
self.readTraffic()
}
}
and readTraffic:
private func readTraffic() {
os_log(.debug, log: self.log, "Started reading the traffic")
packetFlow.readPackets { dataArray, protocolsArray in
os_log(.debug, log: self.log, "Reading packets. Traffic packets count: %@", dataArray.count)
self.readTraffic()
}
}
By now I managed to see Tunnel started
and Started reading the traffic
logs. But there is no evidence of Reading packets. Traffic packets count
messages. Moreover, in the Console I see crash report:
Thread 1 Crashed:: Dispatch queue: NEPacketTunnelFlow queue
0 libobjc.A.dylib 0x1a6b52588 objc_msgSend + 8
1 libsystem_trace.dylib 0x1a6a3cc5c _os_log_fmt_flatten_object + 132
2 libsystem_trace.dylib 0x1a6a3ac54 _os_log_impl_flatten_and_send + 1852
3 libswiftos.dylib 0x1bb8e06e8 _swift_os_log + 260
4 libswiftos.dylib 0x1bb8e760c specialized withVaList<A>(_:_:) + 452
5 libswiftos.dylib 0x1bb8e7a6c os_log(_:dso:log:_:_:) + 180
6 com.ybelikov.packet.tunnel.sample.network.extension 0x10019a23c closure #1 in PacketTunnelProvider.readTraffic() + 256 (PacketTunnelProvider.swift:50)
7 com.ybelikov.packet.tunnel.sample.network.extension 0x10019a2e4 thunk for @escaping @callee_guaranteed (@guaranteed [Data], @guaranteed [NSNumber]) -> () + 132
8 NetworkExtension 0x1b5427a04 __55-[NEPacketTunnelFlow readPacketsWithCompletionHandler:]_block_invoke + 552
9 NetworkExtension 0x1b5487134 NEVirtualInterfaceReadMultiplePackets + 1024
10 NetworkExtension 0x1b548a970 __NEVirtualInterfaceCreateReadSource_block_invoke_2 + 80
11 libdispatch.dylib 0x1a6b081b4 _dispatch_client_callout + 20
12 libdispatch.dylib 0x1a6b0b670 _dispatch_continuation_pop + 500
13 libdispatch.dylib 0x1a6b1e8e0 _dispatch_source_invoke + 1596
14 libdispatch.dylib 0x1a6b0f784 _dispatch_lane_serial_drain + 376
15 libdispatch.dylib 0x1a6b10404 _dispatch_lane_invoke + 392
16 libdispatch.dylib 0x1a6b1ac98 _dispatch_workloop_worker_thread + 648
17 libsystem_pthread.dylib 0x1a6cc8360 _pthread_wqthread + 288
18 libsystem_pthread.dylib 0x1a6cc7080 start_wqthread + 8
Could you suggest where a mistake in the tunnel settings is? I want only to read outgoing packages for now. I understand that this is not how VPN clients are supposed to work, but I am doing that only for a little experiment, so I know that in such a manner I will break the connection on my computer.
This is just a bug in your logging. This line:
os_log(.debug, log: self.log, "Reading packets. Traffic packets count: %@", dataArray.count)
is wrong. The %@
should be a %zd
.
I make this mistake all the time )-:
If you are able to raise your deployment target then I encourage you to adopt Swift’s Logger
type; that will prevent you from ever having to do with this problem again.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"