NEPacketTunnelProvider can't get device's packets

Hi, I'm new in this area. I have several questions to ask. I'm implementing a vpn client by using NETunnelProviderProtocol(). After I start the tunnel successfully, I can't get any packets from self.packetFlow.readPacketObjects. Is the NETunnelProviderProtocol able to gather the packet from whole device ?(just work like a normal vpn client)
Is it safe to turn includeAllNetworks() to true?
thanks

Accepted Answer

I have several questions to ask.

OK, let’s start with some basics. What platform are you targeting?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
hi, I'm targeting on macOS platform.
sorry! I accidentally press the solved button, but I still have problems. plz help me to solve them.
A packet tunnel provider can operate in one of two modes:
  • Destination IP (NETunnelProviderRoutingMethodDestinationIP)

  • Source app (NETunnelProviderRoutingMethodSourceApplication)

The latter is one of two flavours of per-app VPN (the other being an app proxy provider).

Which mode are you planning to use?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I think for now I will use Destination IP as the default choice.

I think for now I will use Destination IP as the default choice.

That’s a good place to start (-:

When you test this, make sure the the destination address of the connection that you want to go over the VPN is in the set of IP networks your VPN claims when it initialises the includedRoutes property of the NEIPv{4,6}Settings it uses to set up the tunnel.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I set tunnel like these
Code Block settings.ipv4Settings = NEIPv4Settings(addresses: ["127.0.0.1", "0.0.0.0"], subnetMasks: ["255.255.255.0", "255.255.255.0"])
        settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]
        settings.ipv4Settings?.excludedRoutes = [NEIPv4Route(destinationAddress: "127.0.0.1", subnetMask: "255.255.255.255")]

and read packets
Code Block self.queue.async {
                while(true){
                    self.packetFlow.readPackets{
                        (packets: [Data], protocols: [NSNumber]) in
                        for packet in packets{
                            self.handle_packet(data: packet)
                        }
                    }
                }
            }

but I still get nothing

Code Block
settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]


Are you sure that ipv4Settings is not nil? If it is, the ? will cause this code to act as a no-op.

A better way to write this is:

Code Block
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: …)
let settings4 = NEIPv4Settings(addresses: […], subnetMasks: […])
settings4.includedRoutes = [NEIPv4Route.default()]
// … fill in the rest of `settings4` …
settings.ipv4Settings = settings4


That way settings4 is never nil and you don’t need all the question marks.



Apropos the above, what are you supply for the tunnelRemoteAddress, addresses, and subnetMasks values?



Code Block
settings.ipv4Settings?.excludedRoutes = [NEIPv4Route(destinationAddress: "127.0.0.1", subnetMask: "255.255.255.255")]


Why are you excluding the loopback address here? Generally that’s not necessary and it suggests that you’re trying to use the packet tunnel provider infrastructure for something that isn’t a VPN.



Code Block
while (true) {
}


I’m not sure what you trying to do here but this is definitely wrong. Worse yet, depending on what thread you’re running on here it may end up completely wedging your provider.

The standard approach for this is to do all your reading asynchronously. For example:

Code Block
func startNextRead() {
self.packetFlow.readPacketObjects { packets in
… process `packets` …
self.startNextRead()
}
}


Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I use a fake ip address for tunnel remote address for testing only right now. (like 192.168.0.1 or a local address)
Would this cause problem?
( As I know NETunnelProviderProtocol can finish the start tunnel step by just call a function call setTunnelNetworkSettings, after this function called the status in my vpn tunnel shows start.I assume it should start working.)
cause all my code works fine the only problem is I still can't read the packets.

thanks for all of your helps.

I use a fake ip address for tunnel remote address for testing only
right now … Would this cause problem?

It’s hard to say without more info. Earlier I wrote:

what are you supply for the tunnelRemoteAddress, addresses, and
subnetMasks values?

and I was hoping to get all that info, along with the destination address of a packet that you expect to receive but don’t.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I use tunnelRemoteAddress: 192.168.1.128 , addresses: ["127.0.0.1"], subnetMasks: ["255.255.255.255"].
I want to get all the packet that is going to leave my device.
now I get nothing.
I have a little confuse about the functionality of addresses and subnetMask here, could you please explain that for mee too.

I want to get all the packet that is going to leave my device.

To be clear, that’s not going to happen no matter what you do here. The best you can do with an iOS packet tunnel is claim the default route. Traffic that’s bound to a specific interface will no go through your tunnel.

What are you trying to build? A VPN client? Or something else? The reason I ask is that most VPN client developers don’t ever need to reference 127.0.0.1.

Share and Enjoy

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

Well the reason I use 127.0.0.1 is because I kind have a misunderstanding of how these numbers work. According to my understanding, the Array in "address:" include the Dest address of the packet. So if the Dest address is in the array I assume it will route to my TUN, am I correct? Then I will no longer need to add 127.0.0.1 to the array. what I'm trying to do is to have a device work as a middle device that can monitor the packet flow. so I understand there's some packets will be bonded to specific interface. I'm searching for a most wide-range solution.

oh wait a second, I know what the address means. I see another routing method on official website .networkRule could you please explain how this works?

Please answer my question from earlier:

What are you trying to build? A VPN client? Or something else?

Share and Enjoy

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

NEPacketTunnelProvider can't get device's packets
 
 
Q