Last year when analyzing raw PCAP-NG data from Yosemite, I noticed Apple embedded application name data in the PCAP data. The PCAP-NG format lets vendors create their own extensions to the data, and I thought Apple created a clever and handy extension. Last month I finally sat down to start learning Swift, so I did what I usually do when learning a new language - I wrote a network analyzer.
Version 0.1 of SimpleSniffer can be downloaded at the end of this page.
SimpleSniffer is a simple network analyzer that identifies TCP connections and UDP sessions in raw Apple PCAP-NG data stream and prints the connection information to the screen. If the application name associated with the connection is available, the name is included in the connection. Also, if DNS information about the server IP address can be gleaned from the DNS data in the PCAP data, the names associated with the server is also printed.
SimpleSniffer is a command line utility. It can read PCAP-NG data from a file or from standard in. I typically run tcpdump and pipe the data directly to SimpleSniffer. For example, here is the current command I am running:
$ sudo tcpdump -s 5000 -p -w - | ./SimpleSniffer -r - -t -p
The tcpdump option "-w -" writes the PCAP data to standard out, and the SimpleSniffer option "-r -" reads the PCAP data from standard in.
The following is some annotated output from the program:
The columns of the output are as follows:
- N or U: Indicates if this is a new connection report (N) or an update of a previously reported connection (U). An update occurs when the application information comes after the first packet few packets for the connection.
- Application: The application that generated the packets. Apple only supplies the first 15 characters of an application's name, and sometimes (I haven't figured out when) the application is never provided. If your tcpdump is watching packets for that are neither to nor from your computer, tcpdump has no way of knowing what application is generating the traffic. tcpdump's "-p" (lowercase 'p') can restrict the packets to just those to or from your computer.
- Client addr: IPv4 address of the computer that initiated the connection. SimpleSniffer uses a couple of heuristics to determine which host is acting as the client (initiator) and which is acting as the server (receiver).
- Client port: TCP or UDP port on the client computer.
- Server addr: IPv4 address of the computer that received the connection.
- Server port: TCP or UDP port on the server computer.
- Requested DNS: The hostname last queried that returned the server IP address. This can be interpreted as the hostname the client thinks it is connecting to.
- Redirected DNS: The hostname in a DNS answer that returned the server IP address. Often a host is redirected from the original query name to a new name. A typical use case is when a query gets redirected to a content delivery network (CDN) like Akamai.
The first line in the example above, the application locationd on the computer with the IP address 18.104.22.168 initiated an HTTPS connection to gs-loc.apple.com, which redirected the computer to the hostname gs-loc.ls-apple.com.akadns.net with the IP address 22.214.171.124.
SimpleSniffer supports the following options
- -t : Apply throttles to suppress the number of connections reported for a given data path. A data path (dating back to the NSM/ASIM's profiling system) is defined as the 4-tuple <application, client-addr, server-addr, server-port> (the original NSM did not have an application field). If Webkit connects to the same web server 100 times, only the first connection will be reported.
- -dns : print the parsed DNS information. This creates a lot of clutter, but it can be fascinating to watch to. If you only want to watch DNS activity, use this option along with the -ns option.
- -p : pause reporting of a new connection if the application isn't initially known. Often the application data will appear in the PCAP data stream after the first few packets for a new connection. This option reduces the clutter of a 'N' connection report immediately followed by an 'U' connection report.
- -c <count> : process at most <count> packets.
- -ns : Suppress reporting of sessions ("no sessions"). This option is useful when you just want to watch DNS activity (see -dns).
- -r <source> : Specify the source of packets, either a path to a PCAP file or '-' to read from standard in.
- -h : print help.
Run tcpdump with a large snap length (e.g., -s 5000). This isn't needed on the Mac because OS X defaults to a huge snap length (65535 bytes), but too often I switch to another operating system, forget to use a large snap length, and tcpdump ends up chopping off half the payload data in packets.
Watch the DNS traffic for fun. You can learn a lot about how the Internet is put together and how it behaves behind the scenes just by watching the DNS traffic.
$ sudo tcpdump -p -w - | ./SimpleSniffer -r - -dns -ns
SimpleSniffer assumes you are comfortable with running tcpdump and running UNIX commands from the Terminal.
When you first start SimpleSniffer, the DNS fields are frequently empty. This is because SimpleSniffer learns hostnames by watching DNS traffic, and if a connection already exists when the program is started, or if the computer is revisiting a host it had queried before SimpleSniffer started (and still remembers the DNS answer), there is simply no DNS enrichment data SimpleSniffer can add to the connection record.
There are plenty of bugs. This is my first Swift program, and it is version 0.1
The following link downloads a Disk Image containing the application. Drag the application to a known location (e.g., your Desktop), and then run the application from there in a Terminal window.