--- /dev/null
+/**********************************************************************
+This is a wireless pcap capture and parser by example.
+By: Russell Handorf
+**********************************************************************/
+
+#include <pcap.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinet/if_ether.h>
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+#include <netinet/ip.h>
+#include <linux/if.h>
+#include <linux/wireless.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "radiotap.h"
+#include "radiotap_iter.h"
+
+const struct pcap_pkthdr* callback_header;
+
+static const struct radiotap_align_size align_size_000000_00[] = {
+ [0] = { .align = 1, .size = 4, },
+ [52] = { .align = 1, .size = 4, },
+};
+
+typedef struct {
+ u_int8_t it_version;
+ u_int8_t it_pad;
+ u_int16_t it_len;
+ u_int32_t it_present;
+
+ u_int32_t pad;
+ u_int8_t flags;
+ u_int8_t rate;
+ u_int16_t wr_chan_freq;
+ int8_t ant_sig;
+ int8_t lock_quality;
+ u_int8_t ant;
+
+} __attribute__((__packed__)) ieee80211_radiotap;
+
+typedef struct {
+ unsigned short fc;
+ unsigned short durid;
+ u_char a1[6];
+ u_char a2[6];
+ u_char a3[6];
+ unsigned short seq;
+ u_char a4[6];
+} __attribute__((__packed__)) dot11_header;
+
+
+void format_mac(u_char * mac, char * f) {
+ sprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
+
+ //printf("packet size: %d\n", pkthdr->len);
+ //printf("packet: %02x \n", packet);
+ //printf("%u\n", packet);
+ int err, radiotap_header_len, ssid_len, i;
+ int8_t rssi, rate;
+ u_int16_t channel;
+ char client_mac[18];
+ char ssid[38];
+
+ struct ieee80211_radiotap_iterator iter;
+
+ radiotap_header_len = iter._max_length;
+ dot11_header * dot_head = (dot11_header*) (packet + radiotap_header_len * sizeof(char) );
+
+ err = ieee80211_radiotap_iterator_init(&iter, (void*)packet, pkthdr->caplen, NULL);
+ if (err > 0) {
+ }
+
+ radiotap_header_len = iter._max_length;
+
+ while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
+ if (iter.this_arg_index == IEEE80211_RADIOTAP_DBM_ANTSIGNAL) {
+ rssi = (int8_t)iter.this_arg[0];
+ }
+ if (iter.this_arg_index == IEEE80211_RADIOTAP_CHANNEL) {
+ channel = (*(uint16_t *)iter.this_arg);
+ }
+ if (iter.this_arg_index == IEEE80211_RADIOTAP_RATE) {
+ rate = (u_int8_t)iter.this_arg[0];
+ }
+ /* if (iter.this_arg_index == IEEE80211_RADIOTAP_DBM_ANTNOISE) { */
+ /* noise = (int8_t)iter.this_arg[0]; */
+ /* } */
+ };
+
+ if (pkthdr->len >= 24) {
+ u_int8_t hlen;
+ hlen = packet[2]+(packet[3]<<8); //Usually 18 or 13 in some cases
+ switch (packet[hlen]) {
+ case 0x40:
+ //memset(ssid, 0, sizeof(ssid));
+ printf("Probe request\n");
+ printf("probe request client mac: %02x:%02x:%02x:%02x:%02x:%02x\n", packet[44], packet[45],packet[46],packet[47],packet[48],packet[49]);
+ ssid_len=packet[59];
+ printf("probe size: %d\n", ssid_len);
+ if (ssid_len>0) {
+ for (i=0;i<ssid_len;++i){
+ sprintf(ssid+i, "%c", packet[60+i]);
+ }
+ printf("probe ssid: %s\n", ssid);
+ }
+ break;
+ case 0x50:
+ printf("Probe response\n");
+ printf("probe response client mac: %02x:%02x:%02x:%02x:%02x:%02x\n", packet[38], packet[39],packet[40],packet[41],packet[42],packet[43]);
+ printf("probe response bssid mac: %02x:%02x:%02x:%02x:%02x:%02x\n", packet[44], packet[45],packet[46],packet[47],packet[48],packet[49]);
+ ssid_len=packet[71];
+ printf("probe response size: %d\n", ssid_len);
+ for (i=0;i<ssid_len;++i){
+ sprintf(ssid+i, "%c", packet[72+i]);
+ }
+ printf("probe response ssid: %s\n", ssid);
+
+ break;
+ case 0x80:
+ //memset(&ssid[0], 0, sizeof(ssid));
+ printf("Beacon\n");
+ ssid_len=packet[hlen+37];
+ printf("size: %d\n", ssid_len);
+ for (i=0;i<ssid_len;++i){
+ //printf("%c\n", packet[hlen+38+i]);
+ sprintf(ssid+i, "%c", packet[hlen+38+i]);
+ //puts(ssid);
+ //printf("ssid: %c\n", ssid);
+ //memcpy(ssid,packet[hlen+38+i],2);
+ //ssid+=packet[hlen+38+i];
+ //printf("counter: %d - ssid: %c\n", (hlen+38+i), packet[hlen+38+i]);
+ }
+ printf("BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", packet[50], packet[51],packet[52],packet[53],packet[54],packet[55]);
+ printf("ssid: %s\n", ssid);
+ break;
+ }
+ };
+
+ //format_mac(dot_head->a2, client_mac);
+
+ printf("rate: %d channel: %04x rssi: %d\n", rate, channel, rssi);
+}
+
+int main(int argc,char **argv)
+{
+ int c;
+ char *dev = NULL;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ pcap_t* pcap;
+ struct bpf_program fp; /* hold compiled program */
+ bpf_u_int32 maskp; /* subnet mask */
+ bpf_u_int32 netp; /* ip */
+ u_char* args = NULL;
+ char filter_exp[] = "";
+ char *totpacket = NULL;
+
+ while ((c = getopt (argc, argv, "ha:i:")) != -1)
+ switch (c) {
+ case 'a':
+ totpacket = optarg;
+ break;
+ case 'i':
+ dev = optarg;
+ break;
+ case 'h':
+ printf("./disect -a -i\n\t-a : number of packets to sniff. (default 10)\n\t-i : wlan interface.\n");
+ exit(0);
+ default:
+ return 0;
+ }
+
+ if (totpacket == NULL) {
+ totpacket="-1";
+ printf("-a not specified... setting to 10.\n");
+ }
+
+ if (dev == NULL) {
+ printf("You forgot -i\n");
+ exit(0);
+ }
+
+ printf ("%s %s\n", totpacket, dev);
+
+ if(dev == NULL) {
+ printf("%s\n",errbuf);
+ exit(1);
+ }
+
+ /* ask pcap for the network address and mask of the device */
+ pcap_lookupnet(dev,&netp,&maskp,errbuf);
+
+ /* open device for reading. NOTE: defaulting to
+ * promiscuous mode*/
+ pcap = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
+ pcap_set_promisc(pcap, 1);
+
+ if(pcap == NULL) {
+ printf("pcap_open_live(): %s\n",errbuf);
+ exit(1);
+ }
+
+ pcap_set_datalink(pcap, DLT_IEEE802_11);
+ pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO_AVS);
+ pcap_set_datalink(pcap, DLT_IEEE802_11_RADIO);
+
+ pcap_setnonblock(pcap, 1, errbuf);
+
+ int link_layer_type = pcap_datalink(pcap);
+
+ //printf("type: %d\n", link_layer_type);
+
+ if (link_layer_type == DLT_PRISM_HEADER ||
+ link_layer_type == DLT_IEEE802_11_RADIO ||
+ link_layer_type == DLT_IEEE802_11_RADIO_AVS ||
+ link_layer_type == DLT_IEEE802_11 ||
+ link_layer_type == DLT_PPI ||
+ link_layer_type == 127 ) {
+ if (pcap_compile(pcap, &fp, filter_exp, 0, netp) == -1) {
+ fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(pcap));
+ exit(EXIT_FAILURE);
+ }
+ if (pcap_setfilter(pcap, &fp) == -1) {
+ fprintf(stderr, "Couldn't install filter %s: %s\n",
+ filter_exp, pcap_geterr(pcap));
+ exit(EXIT_FAILURE);
+ }
+ printf("starting\n");
+
+ pcap_loop(pcap,atoi(totpacket),my_callback,NULL);
+ } else {
+ fprintf(stderr, "Not using the Wi-Fi interface, are you testing something?\n");
+ }
+ fprintf(stdout,"\nfinished\n");
+ return 0;
+}
+