Last update: 2015-01-18
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.2 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 or DNS information to the screen. SimpleSniffer is a command line utility. It can read PCAP-NG from a file or from standard in. I typically run tcpdump and pipe the data directly to SimpleSniffer.
There are typically two modes I run SimpleSniffer in: connection mode and DNS mode.
The default behavior of SimpleSniffer is to print out the connection information, so connection mode is the default behavior. Two additional options I like to use in connection mode are "-t" (which suppresses subsequent connections to the same server) and "-p" (which pauses the reporting of a new connection if the application information isn't immediately available). If I am on a network that supports IPv6, I also use the "-w" option (for wide) which uses extra space for the client and server addresses to display the potentially lengthy IPv6 addresses.
Here is a typical command I use when running SimpleSniffer in connection mode:
$ sudo tcpdump -p -w - | ./SimpleSniffer -r - -t -w -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. The "-p" option generally prevents Update reports by pausing a report if the application information isn't known until a few packets have been seen.
- 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 which 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 or IPv6 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 or IPv6 address of the computer that received the connection.
- Server port: TCP or UDP port on the server computer.
- DNS names for server: One or more names associated with the server address culled from DNS activity.
The first line in the figure above shows the application com.apple.WebKi(t) on my laptop (192.168.0.4) initiated a connection to 126.96.36.199 on port 443 (HTTPS). Two names, 3951336.fls.doubleclick.net and dart.l.doubleclick.net, are associated with the server address.
Suppressing the output of connection information with the -ns option and printing DNS with either the -dns or -dnsv option puts SimpleSniffer into DNS mode.
Here is a typical command I use when running SimpleSniffer in DNS mode:
$ sudo tcpdump -p -w - | ./SimpleSniffer -r - -ns -dnsv
The following figure shows some output of the command. Two DNS answers are shown. The first answer is for a query for the IPv4 address (type = "A") for clients4.google.com, and the second answer is for a query for the IPv6 address (type = "AAAA") also for clients4.google.com.
For more information on DNS, see RFC 1035.
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.
- -dnsv : print the parsed DNS information in greater detail (DNS Verbose).
- -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).
- -w : print addresses in the wide format. Useful if you generate IPv6 addresses.
- -r <source> : Specify the source of packets, either a path to a PCAP file or '-' to read from standard in.
- -h : print help.
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.
This is my first Swift program, and it is version 0.2. There are no guarantees about the safety, accuracy, or reliability of the program.
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. You will typically need to specify the path to the program. If you are in the same directory, just use ./SimpleSniffer.
Changes for version 0.2
- Fixed a significant memory leak problem.
- Added support for IPv6.
- Stitch together DNS information that crosses multiple DNS record to provide more useful hostname information.