Skip to main content

Capturing a Packet Trace from an iOS Device

Capturing a Packet Trace from an iOS Device

Debugging network activity on an iOS device can be challenging.  There are fantastic tools built into Xcode that allow you to to see the data flowing in and out of the device, but troubleshooting network activity at the TCP level can be difficult.  Often the best option you have is to perform a packet capture at the router level, but this presents it’s own set of challenges. Capturing packets at the router level casts a wide net and you end up capturing a lot of noise at the router level that can make debugging iOS TCP traffic very time consuming.  Also, capturing TCP traffic at the router level does not give you a true perspective of what your cellular traffic looks like as WiFi traffic is often much faster. Luckily, within the last week, I learned that there is a way to expose a remote virtual interface on a iOS device from macOS.  Exposing a virtual interface allows you to directly capture TCP traffic that is flowing in and out of the device's network interface.  This is a true look at your network traffic from the TCP level, no matter if your traffic is over cellular or WiFi. And that is why I wanted to write this article, to give a brief explanation on how to expose a remote virtual interface on an iOS device and then run a packet capture from that interface.  Let's get started!

 

Exposing a Remote Virtual Interface 📱

Exposing a Remote Virtual Interface

A complete writeup on exposing a remote virtual interface is available on Apple's developer documentation, but I wanted to take just the core steps and provide example of them below.  To begin, make sure you have the iOS device plugged in and you can see your network interfaces on macOS and the iOS device by typing the following command:  

$ ifconfig -l
lo0 gif0 stf0 XHC20 en0 p2p0 awdl0 en1 en2 bridge0 utun0 utun1 utun2 utun3 en5

Next, open up Xcode and navigate to Window -> Devices and Simulators.  Here Xcode should have your connected device and your device identifier.  Copy down your device identifier because you will need it in the next step.

Xcode Devices

Next, use the rvictl tool to create and expose a remote virtual interface on your iOS device with your device identifier.  To do this run the following command below.

$ rvictl -s 3fef456ab1664ca0b2a18e0550e27f4a9115b804
 
Starting device 3fef456ab1664ca0b2a18e0550e27f4a9115b804 [SUCCEEDED] with interface rvi0

From here you should now be able to see the newly created network interface once you run the ipconfig -l command again.  On the terminal again, run that same command as before to see the new interface,  rvi0.  This is the network interface on the iOS device that you will be able to perform packet capture on!

$ ifconfig -l
lo0 gif0 stf0 XHC20 en0 p2p0 awdl0 en1 en2 bridge0 utun0 utun1 utun2 utun3 en5 rvi0

 

Running a Packet Capture 🖥

Now for the fun part, capturing the TCP packet trace into a pcap.  To do this, queue up your iOS application on your device that will be running your network activity.  Next, on the terminal, type this command in to use the TCPDUMP tool to capture the network activity on the remote virtual interface that you just exposed (rvi0):

$ sudo tcpdump -i rvi0 -vvv -w packet_trace.pcap
Packet capture

You are all set now to run your network activity on your iOS device and see TCPDUMP capturing your network packets from the terminal.  In this example I ran two network requests.  The following screen shot below shows a sample of one of my tcp streams in Wireshark.

Wireshark

After you are finished, the last thing I recommend doing is removing your remote virtual interface on your iOS device.  To do that, run the command below and you should be all set.

$ rvictl -x 3fef456ab1664ca0b2a18e0550e27f4a9115b804

 

In Summary ⌛️

In summary, I hope you have now learned a bit more about how to capture a packet trace directly from an iOS device.  I would be interested to hear if this technique also works on tvOS or watchOS?  Please write in and let me know if you test this out and you are successful or not.

Network debugging to me is fascinating. One of the most important things is that you need though to be successful is just the data you need about your TCP traffic and this technique can be very helpful for iOS debugging to eliminate network noise at the router level.  I hope you have enjoyed this post and please if you have any questions comments or concerns, leave a comment, and I will get back to you as soon as possible.  Thank you!

Member for

3 years 9 months
Matt Eaton

Long time mobile team lead with a love for network engineering, security, IoT, oss, writing, wireless, and mobile.  Avid runner and determined health nut living in the greater Chicagoland area.

Comments

Ian Wilkinson

Thu, 05/03/2018 - 02:37 PM

Thanks for your informative post! I am interesting in simulating packet loss at the iOS app level (not the entire system level, so I can’t use Link Conditioner), to see how my app performs in bad network scenarios. Is there any way to do that?

Thank you very much, Ian!  If I am understanding you correctly you should be able to simulate packet loss with the Link Conditioner and run a packet trace with the technique described in this article all at the same time.  The remote virtual interface should pick up this TCP traffic the same way.

Daniele - Nexo…

Thu, 05/03/2018 - 10:47 PM

Nice article. if you like to spend money :) there is Charles for iOS (and macOS). Of course, the output is not easy to be exported, i mean from ios to mac.

Anthony Wade

Mon, 12/03/2018 - 01:41 AM

Does the IPHONE need to be physically connected to the PC that has Xcode or just the wireless network on it to see the identifier?

Regards

Anthony,

Great question.  I have only ever tested this connected to a computer running macOS.  I have never tested this doing remote debugging on the same network and would be interested to hear if that works.

Thanks!

Matt

Hi Matt,

Something on my iPhone is making DNS queries to resolve a domain name that has no business being queried (it's for a bank and I suspect it's left over from when I deleted their apps). I run an Ad Block VPN DNS proxy which logs DNS queries every six or so hours to www.bankname.com and secure.bankname.com. Short of leaving my iPhone tethered to a Mac and capturing an Instruments network trace, is there a way to capture the trace while untethered? Or some way to find out all the installed apps/modules?

Thanks!

Olte,

Thank you for question.  I am not aware of a way to capture a packet trace without your iPhone tethered to the mac.  This allows the mac to see the virtual interface to capture from.  One thing to try would be Wireless Debugging to see if this gives your mac any visibility into your iPhone's interface to run a capture.  If that does not work then I would suggest connecting your iPhone to a router that you have access to and performing a rolling packet capture on that router.  This is more of a needle in a haystack approach but it should capture outbound DNS queries and connections coming to and from your iPhone.  Just make sure your capture files are rolling and that there is enough disk space on the capturing machine.  I hope that helps.

Matt

Minh Pham

Wed, 06/17/2020 - 12:29 AM

when there is a VOLTE Call going on, can you capture RTP pkts?