Basically I want a simple C code which illustrates capturing packet in promiscuous mode and extracts out ssid from them.
Edit1
I am writing the code which I wrote to perform basic sniffing.
#include <stdio.h>
#include <pcap.h>
int main(int argc, char *argv[]){
pcap_t *handle;
struct pcap_pkthdr header;
const u_char *packet;
int i;
char *dev, errbuf[PCAP_ERRBUF_SIZE];
// dev = pcap_lookupdev(errbuf);
dev = argv[1];
if( dev == NULL ){
fprintf(stderr, "Couldn't find default device\n");
return 0;
}
printf("Device: %s\n", dev);
handle = pcap_open_live( dev , BUFSIZ , 0 , 1000 , errbuf);
if( handle == NULL ){
fprintf(stderr , "couldn't open device %s: %s\n" , dev , errbuf);
return 0;
}
else{
packet = pcap_next( handle, &header );
printf( "Grabbed a packet with length %d\n" , header.len );
for( i = 0; i < header.len; i++ )
printf( "Packet's content %s\n" , packet + i );
pcap_close( handle );
}
return 0;
}
TLD;DR: You're fundamentally taking the wrong direction. Packet capture with libpcap simply does not work this way for Wi-Fi.
- Because the SSID are in 802.11 management frames, you want to capture in monitor mode, not promiscuous mode.
- You then need to use a pcap filter on management frames, specifically for the beacons and/or probe-requests and/or probe responses. That's where the SSID are.
- Then, and only then, you'll have to code the parsing of these specific packets. There's no fixed format (lots of optionnal fields, as can be seen from looking a capture with wireshark), so there's no "one size fits all parsing". But it's no too hard to get the SSID.
Still, you're far from this SSID parsing. It's actually the last of your problems so far. So now the gory details.
You have 3 possibilities regarding libpcap on Wi-Fi:
1/ Normal mode (not promiscuous, not monitor):
You will see packets to/from your interface. Not to/from other APs (Access Points) or STAs (Stations).
These packets will look like "regular Ethernet frames", without the 802.11 parts nor the pure 802.11 managing packet, so if your goal is to get the SSIDs around you that's no good, you simply won't see these. The only usable use case for this is that your wlan0 is a STA or the AP itself, and you want to capture the traffic between network application(s) running on the same machine that run your capture program.
2/ Promiscuous mode.
Again, you'll need to be either a STA or the AP, and pcap will give you what's look like regular Ethernet frames, not the 802.11 management part, so again that's useless for SSID. If you're a STA: you won't see much as compare to case 1/normal mode. What you'll see more are the broadcast (from a layer 2/layer 3) frames from other STA. For example ARP requests, multicast/broadcast UDP. But not the unicast traffic from these others STAs. If you are the AP, then yes, you will see the traffic from the connected STAs (note: unless you use Wi-Fi direct https://en.wikipedia.org/wiki/Wi-Fi_Direct, where stations communicate directly without packets passing through an AP).
3/ Monitor mode. Now we're talking.
You'll put your interface in monitor mode using libpcap API, see some example directions here:
Why is pcap_datalink() always returning 1 (Ethernet), even on wireless device?
...or you'll create a monitoring interface beforehand and will launch your pcap process on this. Read:
https://wiki.wireshark.org/CaptureSetup/WLAN#Turning_on_monitor_mode
You will not be connected (neither as STA or AP) *and you can capture everything (but... + see my final warning lower): 802.11 management frames including beacons, probe requests and probe responses, with your precious SSIDs. And all data.* If you have some access points without encrypton, the TCP/IP of data frames from these will be in clear.
Now, the "but" parts:
3.1 - What you will capture will not be regular Ethernet-like frames. You'll have a radiotap header (some meta-information added by the kernel) and then a bunch off 802.11 fields. This can be quite tedious to parse, but if you're just interested in SSID it can be just a few tens of line of C code.
3.2 - Saddly, there is no "SSID filter" from pcap filters syntax that you can apply and just go.
http://www.tcpdump.org/manpages/pcap-filter.7.html
And this is because there is simply no "SSID field" per see, it depends on the type/context of the packet. Still, pcap filters can help you: what you can do is capture beacons using a "type mgt subtype beacon
" filter. You may also be interested in "type mgt subtype probe-resp
" and "type mgt subtype probe-resp
". Then, you'll have to manually parse these: the format is kind of "elastic". Fortunately the SSID is among the first fields and it's a few tens of lines of C code to get it.
Once you'll get to that, but you're still far from it, if you encounter problems with parsing the beacons, then you may come back with a more specific question.
Final warning: be warned that if you want to go beyond SSID and capture applicative data traffic, even put aside the question of encryption, and the parsing work to go from your 802.11+radiotap packet to the layer 3 and above juicy parts, well... the result is not garanteed. In my experience: my environment is extremely noisy (dozens of busy APs and STAs), and most of the time the capture misses some bits: wireshark dissection on such a capture show "ACKed unseen segment", TCP sequence numbers have gaps and "follow TCP dialog" on such a capture shows some "[NNN missing bytes from capture]".
You could use something like exec()
or system()
to invoke the relevant CLI tools/commands and parse the output. You could also look into libpcap, which might be what you are looking for(?).