1
0

experiment3.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include <stdio.h>
  2. #include <pcap.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. #include "experiment3.h"
  7. //Copied from wireshark. Will be overwritten by firmware
  8. u_char radioTapHeader[36] = "\x00\x00\x24\x00\x2f\x40\x00\xa0\x20\x08\x00\x00\x00\x00\x00\x00" \
  9. "\x9d\x5c\xa0\x15\x01\x00\x00\x00\x10\x02\x6c\x09\xa0\x00\xa7\x00" \
  10. "\x00\x00\xa7\x00";
  11. //Mac address of Atheros Wi-Fi dongle
  12. u_char myMAC[6] = "\x00\x0a\xeb\x2d\x72\x55";
  13. //Returns filter for libpcap
  14. //we want to use as many filters here as possible, since libpcap is closer to the hardware than this user-level program
  15. //we only want to receive Probe requests to only our own MAC address or broadcast address, and ACK frames to our MAC address
  16. const char *getFilterString()
  17. {
  18. //xx:xx:xx:xx:xx:xx will become myMAC
  19. static char filterString[] = "(wlan subtype probe-req and (wlan addr1 xx:xx:xx:xx:xx:xx or wlan addr1 ff:ff:ff:ff:ff:ff)) or ( wlan addr1 xx:xx:xx:xx:xx:xx and wlan subtype ack)";
  20. //convert myMAC to string
  21. char myMacStr[18];
  22. snprintf(myMacStr, sizeof(myMacStr), "%02x:%02x:%02x:%02x:%02x:%02x",
  23. myMAC[0], myMAC[1], myMAC[2], myMAC[3], myMAC[4], myMAC[5]);
  24. //replace placeholder MACs in filterString with correct MACstring
  25. strncpy(filterString+40, myMacStr,17);
  26. strncpy(filterString+108, myMacStr,17);
  27. return filterString;
  28. }
  29. //Returns source address pointer location in packet
  30. u_char *getSourceAddrOfPacket(const u_char *packet)
  31. {
  32. //get header length
  33. u_char headerLength;
  34. headerLength = packet[2];
  35. //calculate offset to address
  36. const u_char *addr;
  37. int offset = headerLength;
  38. offset = offset + 10;
  39. //get pointer to address
  40. addr = packet + offset;
  41. return (u_char*) addr;
  42. }
  43. //Returns Version, Type and Subtype (one byte)
  44. u_char getFrameTypeOfPacket(const u_char *packet)
  45. {
  46. //get header length
  47. u_char headerLength;
  48. headerLength = packet[2];
  49. //calculate offset to frame type
  50. const u_char *frameType;
  51. int offset = headerLength;
  52. offset = offset + 0;
  53. //get pointer to frameType
  54. frameType = packet + offset;
  55. return *frameType;
  56. }
  57. //Sends packet using pcap. Returns status
  58. int sendPacket(pcap_t *pcap_h, u_char *packet, int size)
  59. {
  60. int sendStatus = pcap_sendpacket(pcap_h, packet, size);
  61. //when frame failed to send
  62. if (sendStatus == 1)
  63. {
  64. printf("Failed to send frame:\n");
  65. //print failed frame
  66. int printCounter = 0;
  67. for(int i = 0; i < size; i++)
  68. {
  69. printf("%02X ", packet[i]);
  70. printCounter = printCounter + 1;
  71. if (printCounter == 16)
  72. {
  73. printCounter = 0;
  74. printf("\n");
  75. }
  76. }
  77. printf("\n");
  78. }
  79. return sendStatus;
  80. }
  81. int sendProbeResponse(pcap_t *pcap_h, u_char *dstAddress)
  82. {
  83. #define numberOfProbeInfoElems (3) //number of information elements
  84. //definition of all information elements
  85. infoElem ssid = {
  86. 0, //id
  87. 6, //len
  88. 6, //real length of data
  89. "\x46\x75\x7a\x7a\x41\x50" //data
  90. };
  91. infoElem suppRates = {
  92. 1, //id
  93. 7, //len
  94. 7, //real length of data
  95. "\x96\x18\x24\x30\x48\x60\x6c" //data
  96. };
  97. infoElem dsParam = {
  98. 3, //id
  99. 1, //len
  100. 1, //real length of data
  101. "\x01" //data
  102. };
  103. //create array of information elements
  104. infoElem taggedParams[numberOfProbeInfoElems] = {ssid, suppRates, dsParam};
  105. //length of all info elements, including id and len field
  106. int len_taggedParams = 0;
  107. for(int i = 0; i < numberOfProbeInfoElems; i++)
  108. {
  109. //+2 to include id and len field size
  110. len_taggedParams = len_taggedParams + taggedParams[i].len_data+2;
  111. }
  112. //fill in frame struct
  113. probeResponse probeResp = {
  114. 36, radioTapHeader, //RadioTap hdr (overwritten by firmware)
  115. 1, "\x50", //Type
  116. 1, "\x00", //Flags
  117. 2, "\x3a\x01", //Duration
  118. 6, dstAddress, //DST addr
  119. 6, myMAC, //Source addr
  120. 6, myMAC, //BSS addr
  121. 2, "\x00\x00", //Seq nr (overwritten by firmware)
  122. 8, "\x00\x00\x00\x00\x00\x00\x00\x00", //Timestamp (overwritten by firmware)
  123. 2, "\x64\x00", //Beacon interval
  124. 2, "\x01\x00", //Capab info
  125. len_taggedParams,
  126. taggedParams, //Information elements
  127. 4, "\x00\x00\x00\x00" //FSC (overwritten by firmware)
  128. };
  129. //calculate size of final packet
  130. int packetSize = probeResp.len_radioTapHdr
  131. + probeResp.len_type
  132. + probeResp.len_flags
  133. + probeResp.len_duration
  134. + probeResp.len_destAddr
  135. + probeResp.len_sourceAddr
  136. + probeResp.len_bssAddr
  137. + probeResp.len_seqNr
  138. + probeResp.len_timeStamp
  139. + probeResp.len_beaconInterval
  140. + probeResp.len_capabInfo
  141. + probeResp.len_taggedParams
  142. + probeResp.len_fsc;
  143. //define packet
  144. u_char probeRespPacket[packetSize];
  145. //copy all struct fields into packet
  146. int copyOffset = 0;
  147. memcpy(probeRespPacket + copyOffset, probeResp.radioTapHdr, probeResp.len_radioTapHdr);
  148. copyOffset = copyOffset + probeResp.len_radioTapHdr;
  149. memcpy(probeRespPacket + copyOffset, probeResp.type, probeResp.len_type);
  150. copyOffset = copyOffset + probeResp.len_type;
  151. memcpy(probeRespPacket + copyOffset, probeResp.flags, probeResp.len_flags);
  152. copyOffset = copyOffset + probeResp.len_flags;
  153. memcpy(probeRespPacket + copyOffset, probeResp.duration, probeResp.len_duration);
  154. copyOffset = copyOffset + probeResp.len_duration;
  155. memcpy(probeRespPacket + copyOffset, probeResp.destAddr, probeResp.len_destAddr);
  156. copyOffset = copyOffset + probeResp.len_destAddr;
  157. memcpy(probeRespPacket + copyOffset, probeResp.sourceAddr, probeResp.len_sourceAddr);
  158. copyOffset = copyOffset + probeResp.len_sourceAddr;
  159. memcpy(probeRespPacket + copyOffset, probeResp.bssAddr, probeResp.len_bssAddr);
  160. copyOffset = copyOffset + probeResp.len_bssAddr;
  161. memcpy(probeRespPacket + copyOffset, probeResp.seqNr, probeResp.len_seqNr);
  162. copyOffset = copyOffset + probeResp.len_seqNr;
  163. memcpy(probeRespPacket + copyOffset, probeResp.timeStamp, probeResp.len_timeStamp);
  164. copyOffset = copyOffset + probeResp.len_timeStamp;
  165. memcpy(probeRespPacket + copyOffset, probeResp.beaconInterval, probeResp.len_beaconInterval);
  166. copyOffset = copyOffset + probeResp.len_beaconInterval;
  167. memcpy(probeRespPacket + copyOffset, probeResp.capabInfo, probeResp.len_capabInfo);
  168. copyOffset = copyOffset + probeResp.len_capabInfo;
  169. //copy all information elements
  170. for(int i = 0; i < numberOfProbeInfoElems; i++)
  171. {
  172. memcpy(probeRespPacket + copyOffset, &taggedParams[i].id, 1);
  173. copyOffset = copyOffset + 1;
  174. memcpy(probeRespPacket + copyOffset, &taggedParams[i].len, 1);
  175. copyOffset = copyOffset + 1;
  176. memcpy(probeRespPacket + copyOffset, taggedParams[i].data, taggedParams[i].len_data);
  177. copyOffset = copyOffset + taggedParams[i].len_data;
  178. }
  179. memcpy(probeRespPacket + copyOffset, probeResp.fsc, probeResp.len_fsc);
  180. copyOffset = copyOffset + probeResp.len_fsc;
  181. //send packet
  182. return sendPacket(pcap_h, probeRespPacket, packetSize);
  183. }
  184. int main(int argc, char *argv[])
  185. {
  186. pcap_t *pcap_h;
  187. struct bpf_program fp;
  188. struct pcap_pkthdr header;
  189. char *dev;
  190. char errbuf[PCAP_ERRBUF_SIZE];
  191. //check argument number
  192. if(argc != 2)
  193. {
  194. printf("Usage: %s device\n", argv[0]);
  195. exit(EXIT_FAILURE);
  196. }
  197. dev = argv[1];
  198. //initialize libpcap
  199. if((pcap_h = pcap_create(dev, errbuf)) == NULL)
  200. {
  201. printf("pcap_create() failed: %s\n", errbuf);
  202. exit(EXIT_FAILURE);
  203. }
  204. if(pcap_can_set_rfmon(pcap_h) == 0)
  205. {
  206. printf("Monitor mode can not be set.\n");
  207. exit(EXIT_FAILURE);
  208. }
  209. if(pcap_set_rfmon(pcap_h, 1) != 0)
  210. {
  211. printf("Failed to set monitor mode.\n");
  212. exit(EXIT_FAILURE);
  213. }
  214. if(pcap_activate(pcap_h) != 0)
  215. {
  216. printf("pcap_activate() failed\n");
  217. exit(EXIT_FAILURE);
  218. }
  219. //compile filter for incoming packets
  220. if(pcap_compile(pcap_h, &fp, getFilterString() , 0, PCAP_NETMASK_UNKNOWN) == -1)
  221. {
  222. printf("failed pcap_compile() with error: %s\n", pcap_geterr(pcap_h));
  223. exit(EXIT_FAILURE);
  224. }
  225. //apply filter
  226. if(pcap_setfilter(pcap_h, &fp) == -1)
  227. {
  228. printf("failed pcap_setfilter() with error: %s\n", pcap_geterr(pcap_h));
  229. exit(EXIT_FAILURE);
  230. }
  231. //free memory allocated by pcap_compile()
  232. pcap_freecode(&fp);
  233. //flag to indicate if we have to listen for ACK verification
  234. int waitForACK = 0;
  235. //infinite listen-respond loop
  236. while (1)
  237. {
  238. //receive packet
  239. const u_char *packet = pcap_next(pcap_h, &header);
  240. u_char frameType = getFrameTypeOfPacket(packet);
  241. u_char* sourceAddr;
  242. if (frameType != 0xd4) //ACK frames have no source address
  243. sourceAddr = getSourceAddrOfPacket(packet);
  244. //if we had to wait for an ACK, verify if current frame is an ACK
  245. if (waitForACK != 0)
  246. {
  247. if (frameType == 0xd4)
  248. {
  249. printf("Probe response ACKed\n");
  250. }
  251. else
  252. {
  253. printf("Not sure if Probe Response was ACKed\n");
  254. }
  255. waitForACK = 0;
  256. }
  257. else //Process frame depending on type
  258. {
  259. switch(frameType)
  260. {
  261. case 0x40:
  262. {
  263. sendProbeResponse(pcap_h, sourceAddr);
  264. waitForACK = 1;
  265. break;
  266. }
  267. case 0xd4:
  268. {
  269. break;
  270. }
  271. default: break;
  272. }
  273. }
  274. }
  275. return 0;
  276. }