I am developing a VPN (iOS Network Extension), and using C/C++ to read file-descriptor directly (instead of Swift), currently it successfully captures device's request Packets, but I don't know how to parse iOS's packets, I could not even find what network layer or protocol the packets are formatted in.
I converted Packet's binary into Hex to be able to decode with online tools; below are samples of what I need to parse:
000000024500003B5461000040110C390A07000208080808FA2D0035002739B4DE790100000100000000000003777777056170706C6503636F6D0000010001
000000024500003CBAE200004011A5B60A07000208080808E48A0035002892DAE43B01000001000000000000037777770669636C6F756403636F6D0000010001
00000002450000375324000040110D7A0A07000208080808DD7F003500232BBA841801000001000000000000056170706C6503636F6D0000010001
But when tried parsing with online decoder, they fail saying invalid packet.
What network layer or protocol is above?
Note that above are 3 packet samples (not one splitted by me).
tun
-layer protocol with 4
bytes prefix:1. Once we use C/C++ to read file-descriptor, in NEPacketTunnelProvider
like:
let tunFd = self.packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32
// ... pass above to C/C++ backend
Instead of using Swift
like:
self.packetFlow.readPackets { [weak self] (packets: [Data], protocols: [NSNumber]) in
// Handle packets here...
}
2. There are 4
additional bytes prefixed to the tun-layer
packet (e.g. 00 00 00 02
), each time we read packets.
3. To allow most online-tools to understand the packet, remove those starting 4
bytes, and instead prefix it with Mac-Header-Hex like:
01 00 5E 00 00 09 C2 01 17 23 00 00 08 00
Note that by doing above, we convert initial
tun
-layer packet to atap
-layer packet.Also, remember to prefix again those
4
bytes, once writing a packet into the file-descriptor (after removing Mac-Header).
Update 2021; Apple discourages accessing file-descriptor directly (and it may be removed in future iOS releases).