Wireshark has been a beloved swiss knife used by Sys Admins to troubleshoot network problems for years. So, it's not surprising that most devs don't know the magic powers behind this awesome tool when they write their code.

Sure you can use print/echo statements to find out the reason your PHP Curl request isn't working, but what if you don't get a response back? How can you be sure you are setting the right http request headers? How can you be sure you are making a post request and not a Get request. What about the parameters, are they the right ones? DNS? Maybe you just don't have an active internet connection.

If your request is coming from a web form on a browser, or if you are using a RESTFul client like postmap or Insomnia, that's all fine. You can use developer tools on your browser to inspect request and response messages and headers. But not easily when the request is originating from inside the code for instance using PHP Curl for PHP devs.

I am getting comfortable with my new job at Africa's Talking, so I am playing with our awesome APIs. I am using python's great requests library to make GET and POST API requests to AT's SMS API. But my messages were not going through. I doubled checked my code thrice and everything was checking out. What could possibly be the problem? That's when I fired up wireshark.

import requests 
..................
params = {'username': 'awesomeapp', 
			'message': action, 
			'to': '+256787123456'}
		headers = {'Accept':'application/json', 
			'Apikey':'6cc2215d68dfa228eebdcef12e28d252604ebdcfb5df01943e31712859c2'}
		url = 'http://api.africastalking.com/version1/messaging'
		requests.post(url, headers=headers, params=params)

When you start Wireshark, you will have to select a listening interface on which the program should sniff network packets. You should select the interface on which you are making API requests, in this case it's my wireless interface which is connected to the internet.

After you select an interface, wireshark will instantly start to sniff for packets on that interface. Lots of packets.

Wireshark Filters

However, you are only interested in specific traffic -- for devs mostly http(s) traffic. This is where Wireshark filters come in.

Wireshark filters help you search for specific network traffic going through your network interface.

You specify your filters in the search bar. You can filter traffic going to a specific IP address, hostname/domain, traffic based on specific protocol, port, http method etc. Here are sample Wireshark filters.

//address
ip.addr == 192.168.100.100

//protocol
dns or http 
dns and http

//port 
tcp.port == 443

//flags
tcp.analysis.flags

//host 
http.host contains "vpg.visiongroup.co.ug"

//network 
ip.src==192.168.0.0/16 and ip.dst==192.168.0.0/16

//negate 
!(arp or dns or icmp)

//dns queries to facebook 
udp contains facebook

//http headers
http.response.code == 200

//hostname or domain 
http.host matches "\.co.ug$"

//You can apply the following display filters to the captured traffic:

http.host=="exact.name.here"
http.host contains "partial.name.here"

//Get post and get data 
(ip.addr == 185.3.93.202 or ip.addr == 23.221.54.155) and http.request
 ip.addr == 185.3.93.202 and http.request.method == "GET"

 ip.addr == 173.193.201.18  and http and http.request.method == POST

So to troubleshoot my API request issue, I wanted to see traffic going to the API hostname api.africastalking.com. So I use the hostname filter http.host == "api.africastalking.com" and then fireup the code.

Wireshark will show lots of information, some of it is too low-level like tcp protocol headers and not so useful for our troubleshooting purposes.

We are interested in http traffic. And you can see Wireshark will show you timestamp, source ip, destination ip and network protocol. In the lower tab, you will see more information relating to http protocol like request headers, url, query parameters etc.

To see more information relating to a particular packet, simply right click on it, then select follow stream and the select http. Wireshark will give you more detailed user-friendly information akin to the one you see when you open developer console on Google chrome.


As you can see Wireshark shows request I made and response I got from the API server. It said I was missing a required field "username". However, I had actually specified the username field.

It then dawned on me that even though I was rightfully making POST requests, I was sending query string parameters instead of form field data. I then realized that I had used the wrong argument in my requests method. Instead using "data" argument which sets form field data, I used "params" which sets the data to query string.

So my code should have been this requests.post(url, headers=headers, data=params) instead of requests.post(url, headers=headers, params=params).

Notice now that Content-Type is now set to application/x-www-form-urlencoded and Wireshark even shows us form data we should expect instead of query string parameters. Now I got a successful request to the Africa's Talking SMS API. Problem solved!

Maybe Wireshark is an overkill for this particular example. You could still echo/print back the response to the console for error messages. However, when you want to really know what's going on with your http post/get request over the wire, then Wireshark is the tool. You could find it useful inspecting software you have not written for instance where you don't have access to the actual source code. It's really a great tool you want to keep around.

Image: Pixabay