-4

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;
 }
Abhishek Singh
  • 87
  • 2
  • 13
  • Then write it in C. Sounds simple. – Drew Feb 19 '16 at 22:36
  • That's what I don't know ! @Drew , and hence asked the question. – Abhishek Singh Feb 19 '16 at 22:44
  • 1
    @AbhishekSingh SO is not a code-writing service. You're expected to do your own research to learn the basics, and try to implement it yourself. If you can't get it working, you post your attempt and we'll try to help you fix it. – Barmar Feb 19 '16 at 23:08
  • 1
    (see my answer bellow) ...and while I think of it, your code does not even capture in promiscuous mode (which I explain is not what you want). I see no call to [pcap_set_promisc()](http://linux.die.net/man/3/pcap_set_promisc) – jbm Feb 21 '16 at 11:22

2 Answers2

7

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]".

Community
  • 1
  • 1
jbm
  • 3,063
  • 1
  • 16
  • 25
  • Really useful answer sir ! just a small doubt that if monitor mode is necessary then how "iwlist scan" (Linux) works, as what I think that it doesn't turn monitor mode on. – Abhishek Singh Feb 23 '16 at 09:56
  • 2
    Yes, very true, and it is because `iw` tool and such communicates with the `nl80211/mac80211` kernel layers using the `libnl` sockets, which is a completely different way of communicating with 802.11 than your original question "How to perform scanning of wifi ap available nearby using pcap". **pcap** - emphasis mine. – jbm Feb 27 '16 at 15:49
  • So is there any way to get SSID of the all APs by capturing beacon frames using Pcap library?. I really need it and I have scanned all the valid results from google and haven't figured out anything useful. – Abhishek Singh Feb 29 '16 at 17:10
  • 1
    @AbhishekSingh YES, it is, did you read my answer? Why do you think I gave precise directions about the monitor mode, the pcap filter to use, the radiotap headers, and the parsing of the beacons? **Because I happen to have coded all this** for my company. That's from experience. I grabbed the SSID, the BSSID, the country code and the channel - that's all the info we needed. Using pcap, in a network Qt application. – jbm Feb 29 '16 at 18:08
  • but I can't afford to open the interface in monitor mode. Unfortunately that's the main problem. As you have said, doing all this will disconnect me from my access point is there any alternative ? – Abhishek Singh Feb 29 '16 at 20:44
  • is there any good place for learning about libnl sockets and nl80211/mac80211 ? – Abhishek Singh Mar 04 '16 at 10:30
  • "where statiojs communicate directly without packets passing through an AP" --> "where *stations* communicate directly without packets passing through an AP"? And "put asside" --> "put *aside*"? What an amazingly informative answer, though. – RastaJedi May 10 '16 at 07:41
  • @RastaJedi Oh! Thanks for noticing, I just fixed that. And thanks for the "amazingly informative". – jbm May 10 '16 at 08:47
2

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(?).

RastaJedi
  • 641
  • 1
  • 6
  • 18
  • I am not interested in running existing programs, I clearly asked for an illustrative code. – Abhishek Singh Feb 19 '16 at 22:37
  • 1
    I don't know the relevant code. I simply wanted to give you the two options about how you could go about this. One method is simple if you already know how to do this via CLI, and the other, I'm sure you could very easily Google for some example libpcap code. I wanted to tell you the two ways you could obtain the results you want, as well as refer you to a library which you may not have known existed. The downvote hurts, I am trying hard to get 50 rep. so I can comment on answers! If I knew the code, I would have wrote it, but I don't, but I wanted to at least *try* to be helpful so that's... – RastaJedi Feb 19 '16 at 22:48
  • ...(continued) why I tried to at least point you in the right direction and give you a couple of options! I can show you some code on how to use exec() or system() . . . but it would have to be for other commands, as I don't have any experience with pcap. If you don't like my answer, can you at least remove the downvote so it doesn't hurt my rep :(. I thought it would be nice to point you in the right direction, also check out http://www.tcpdump.org/pcap.html. – RastaJedi Feb 19 '16 at 22:48
  • sorry from newcomer's side, but thing is I received 3 down-votes on question already while the question is straight forward, I don't understand why people are not able to get it. Even if they don't get it can't they see the tags which I have put. – Abhishek Singh Feb 19 '16 at 22:52
  • I wasn't the one who downvoted you. In fact, I'll upvote (won't be displayed until my rep. is high enough) if you'll remove your downvote on my answer :). And honestly don't be surprised because it's not uncommon for people to downvote questions asking for people to basically do something for them. – RastaJedi Feb 19 '16 at 22:57
  • Now I also have lost my reputation because of this question and can't upvote it, unless I reach 15. – Abhishek Singh Feb 20 '16 at 05:50