experiment4.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #include <stdio.h>
  2. #include <pcap.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. #include <string.h>
  6. #include "experiment4.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. //Dongle will only ACK frames to its own MAC address
  13. u_char myMAC[6] = "\x00\x0a\xeb\x2d\x72\x55";
  14. //Mac address of SUT, needed to ignore frames from other devices
  15. u_char sutMAC[6] = "\xcc\xfa\x00\xc9\xfc\xad"; //LG Optimus G
  16. //Returns filter for libpcap
  17. //we want to use as many filters here as possible, since libpcap is closer to the hardware than this user-level program
  18. //we only want to receive Probe requests, Authentication frames and Association requests, all to only our own MAC address or broadcast address
  19. //furthermore, all frames except ACK frames (which have no source address) should be sent from the SUT MAC address
  20. //also, it is important not to compile and set the filter between each pcap_next. Otherwise ACK frames will be missed
  21. const char *getFilterString()
  22. {
  23. //xx:xx:xx:xx:xx:xx will become myMAC, yy:yy:yy:yy:yy:yy will become sutMAC
  24. 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) and wlan addr2 yy:yy:yy:yy:yy:yy)" \
  25. " or ( wlan addr1 xx:xx:xx:xx:xx:xx and wlan addr2 yy:yy:yy:yy:yy:yy and ( wlan subtype auth or wlan subtype assoc-req))" \
  26. " or ( wlan addr1 xx:xx:xx:xx:xx:xx and wlan subtype ack)";
  27. //convert myMAC and sutMAC to strings
  28. char myMacStr[18];
  29. char sutMacStr[18];
  30. snprintf(myMacStr, sizeof(myMacStr), "%02x:%02x:%02x:%02x:%02x:%02x",
  31. myMAC[0], myMAC[1], myMAC[2], myMAC[3], myMAC[4], myMAC[5]);
  32. snprintf(sutMacStr, sizeof(sutMacStr), "%02x:%02x:%02x:%02x:%02x:%02x",
  33. sutMAC[0], sutMAC[1], sutMAC[2], sutMAC[3], sutMAC[4], sutMAC[5]);
  34. //replace placeholder MACs in filterString with correct MACstring (hardcoded positions!)
  35. strncpy(filterString+40, myMacStr,17);
  36. strncpy(filterString+106, sutMacStr,17);
  37. strncpy(filterString+141, myMacStr,17);
  38. strncpy(filterString+174, sutMacStr,17);
  39. strncpy(filterString+260, myMacStr,17);
  40. return filterString;
  41. }
  42. //Returns source address pointer location in packet
  43. u_char *getSourceAddrOfPacket(const u_char *packet)
  44. {
  45. //get header length
  46. u_char headerLength;
  47. headerLength = packet[2];
  48. //calculate offset to address
  49. const u_char *addr;
  50. int offset = headerLength;
  51. offset = offset + 10;
  52. //get pointer to address
  53. addr = packet + offset;
  54. return (u_char*) addr;
  55. }
  56. //Returns Version, Type and Subtype (one byte)
  57. u_char getFrameTypeOfPacket(const u_char *packet)
  58. {
  59. //get header length
  60. u_char headerLength;
  61. headerLength = packet[2];
  62. //calculate offset to frame type
  63. const u_char *frameType;
  64. int offset = headerLength;
  65. offset = offset + 0;
  66. //get pointer to frameType
  67. frameType = packet + offset;
  68. return *frameType;
  69. }
  70. //Sends packet using pcap. Returns status
  71. int sendPacket(pcap_t *pcap_h, u_char *packet, int size)
  72. {
  73. int sendStatus = pcap_sendpacket(pcap_h, packet, size);
  74. //when frame failed to send
  75. if (sendStatus == 1)
  76. {
  77. printf("Failed to send frame:\n");
  78. //print failed frame
  79. int printCounter = 0;
  80. for(int i = 0; i < size; i++)
  81. {
  82. printf("%02X ", packet[i]);
  83. printCounter = printCounter + 1;
  84. if (printCounter == 16)
  85. {
  86. printCounter = 0;
  87. printf("\n");
  88. }
  89. }
  90. printf("\n");
  91. }
  92. return sendStatus;
  93. }
  94. //Creates Authentication frame and sends it
  95. int sendAuthResponse(pcap_t *pcap_h, u_char *dstAddress)
  96. {
  97. //fill in struct
  98. authResponse authResp = {
  99. 36, radioTapHeader, //RadioTap hdr (overwritten by firmware)
  100. 1, "\xb0", //Type
  101. 1, "\x00", //Subtype
  102. 2, "\x3a\x01", //Duration
  103. 6, dstAddress, //DST addr
  104. 6, myMAC, //Source addr
  105. 6, myMAC, //BSS addr
  106. 2, "\x00\x00", //Seq nr (overwritten by firmware)
  107. 2, "\x00\x00", //Auth alg
  108. 2, "\x02\x00", //Auth seq
  109. 2, "\x00\x00", //Status code
  110. 4, "\x00\x00\x00\x00" //FSC (overwritten by firmware)
  111. };
  112. //calculate size of final packet
  113. int packetSize = authResp.len_radioTapHdr
  114. + authResp.len_type
  115. + authResp.len_flags
  116. + authResp.len_duration
  117. + authResp.len_destAddr
  118. + authResp.len_sourceAddr
  119. + authResp.len_bssAddr
  120. + authResp.len_seqNr
  121. + authResp.len_authAlg
  122. + authResp.len_authSeq
  123. + authResp.len_status
  124. + authResp.len_fsc;
  125. //define packet
  126. u_char authRespPacket[packetSize];
  127. //copy all struct fields into packet
  128. int copyOffset = 0;
  129. memcpy(authRespPacket + copyOffset, authResp.radioTapHdr, authResp.len_radioTapHdr);
  130. copyOffset = copyOffset + authResp.len_radioTapHdr;
  131. memcpy(authRespPacket + copyOffset, authResp.type, authResp.len_type);
  132. copyOffset = copyOffset + authResp.len_type;
  133. memcpy(authRespPacket + copyOffset, authResp.flags, authResp.len_flags);
  134. copyOffset = copyOffset + authResp.len_flags;
  135. memcpy(authRespPacket + copyOffset, authResp.duration, authResp.len_duration);
  136. copyOffset = copyOffset + authResp.len_duration;
  137. memcpy(authRespPacket + copyOffset, authResp.destAddr, authResp.len_destAddr);
  138. copyOffset = copyOffset + authResp.len_destAddr;
  139. memcpy(authRespPacket + copyOffset, authResp.sourceAddr, authResp.len_sourceAddr);
  140. copyOffset = copyOffset + authResp.len_sourceAddr;
  141. memcpy(authRespPacket + copyOffset, authResp.bssAddr, authResp.len_bssAddr);
  142. copyOffset = copyOffset + authResp.len_bssAddr;
  143. memcpy(authRespPacket + copyOffset, authResp.seqNr, authResp.len_seqNr);
  144. copyOffset = copyOffset + authResp.len_seqNr;
  145. memcpy(authRespPacket + copyOffset, authResp.authAlg, authResp.len_authAlg);
  146. copyOffset = copyOffset + authResp.len_authAlg;
  147. memcpy(authRespPacket + copyOffset, authResp.authSeq, authResp.len_authSeq);
  148. copyOffset = copyOffset + authResp.len_authSeq;
  149. memcpy(authRespPacket + copyOffset, authResp.status, authResp.len_status);
  150. copyOffset = copyOffset + authResp.len_status;
  151. memcpy(authRespPacket + copyOffset, authResp.fsc, authResp.len_fsc);
  152. copyOffset = copyOffset + authResp.len_fsc;
  153. //send packet
  154. return sendPacket(pcap_h, authRespPacket, packetSize);
  155. }
  156. //Creates Association response frame and sends it
  157. int sendAssResponse(pcap_t *pcap_h, u_char *dstAddress)
  158. {
  159. #define numberOfAssInfoElems (1) //number of information elements
  160. //definition of all information elements
  161. infoElem suppRates = {
  162. 1, //id
  163. 8, //len
  164. 8, //real lenght of data
  165. "\x82\x84\x8b\x96\x0c\x12\x18\x24" //data
  166. };
  167. //create array of information elements
  168. infoElem taggedParams[numberOfAssInfoElems] = {suppRates};
  169. //length of all info elements, including id and len field
  170. int len_taggedParams = 0;
  171. for(int i = 0; i < numberOfAssInfoElems; i++)
  172. {
  173. //+2 to include id and len field size
  174. len_taggedParams = len_taggedParams + taggedParams[i].len_data+2;
  175. }
  176. //fill in struct
  177. assResponse assResp = {
  178. 36, radioTapHeader, //RadioTap hdr (overwritten by firmware)
  179. 1, "\x10", //Type
  180. 1, "\x00", //Flags
  181. 2, "\x40\x01", //Duration
  182. 6, dstAddress, //DST addr
  183. 6, myMAC, //Source addr
  184. 6, myMAC, //BSS addr
  185. 2, "\x00\x00", //Seq nr (overwritten by firmware)
  186. 2, "\x01\x00", //Capab info
  187. 2, "\x00\x00", //Status code
  188. 2, "\x01\xc0", //Association id
  189. len_taggedParams,
  190. taggedParams, //Information elements
  191. 4, "\x00\x00\x00\x00" //FSC (overwritten by firmware)
  192. };
  193. //calculate size of final packet
  194. int packetSize = assResp.len_radioTapHdr
  195. + assResp.len_type
  196. + assResp.len_flags
  197. + assResp.len_duration
  198. + assResp.len_destAddr
  199. + assResp.len_sourceAddr
  200. + assResp.len_bssAddr
  201. + assResp.len_seqNr
  202. + assResp.len_capabInfo
  203. + assResp.len_status
  204. + assResp.len_assId
  205. + assResp.len_taggedParams
  206. + assResp.len_fsc;
  207. //define packet
  208. u_char assRespPacket[packetSize];
  209. //copy all struct fields into packet
  210. int copyOffset = 0;
  211. memcpy(assRespPacket + copyOffset, assResp.radioTapHdr, assResp.len_radioTapHdr);
  212. copyOffset = copyOffset + assResp.len_radioTapHdr;
  213. memcpy(assRespPacket + copyOffset, assResp.type, assResp.len_type);
  214. copyOffset = copyOffset + assResp.len_type;
  215. memcpy(assRespPacket + copyOffset, assResp.flags, assResp.len_flags);
  216. copyOffset = copyOffset + assResp.len_flags;
  217. memcpy(assRespPacket + copyOffset, assResp.duration, assResp.len_duration);
  218. copyOffset = copyOffset + assResp.len_duration;
  219. memcpy(assRespPacket + copyOffset, assResp.destAddr, assResp.len_destAddr);
  220. copyOffset = copyOffset + assResp.len_destAddr;
  221. memcpy(assRespPacket + copyOffset, assResp.sourceAddr, assResp.len_sourceAddr);
  222. copyOffset = copyOffset + assResp.len_sourceAddr;
  223. memcpy(assRespPacket + copyOffset, assResp.bssAddr, assResp.len_bssAddr);
  224. copyOffset = copyOffset + assResp.len_bssAddr;
  225. memcpy(assRespPacket + copyOffset, assResp.seqNr, assResp.len_seqNr);
  226. copyOffset = copyOffset + assResp.len_seqNr;
  227. memcpy(assRespPacket + copyOffset, assResp.capabInfo, assResp.len_capabInfo);
  228. copyOffset = copyOffset + assResp.len_capabInfo;
  229. memcpy(assRespPacket + copyOffset, assResp.status, assResp.len_status);
  230. copyOffset = copyOffset + assResp.len_status;
  231. memcpy(assRespPacket + copyOffset, assResp.assId, assResp.len_assId);
  232. copyOffset = copyOffset + assResp.len_assId;
  233. //copy all information elements
  234. for(int i = 0; i < numberOfAssInfoElems; i++)
  235. {
  236. memcpy(assRespPacket + copyOffset, &taggedParams[i].id, 1);
  237. copyOffset = copyOffset + 1;
  238. memcpy(assRespPacket + copyOffset, &taggedParams[i].len, 1);
  239. copyOffset = copyOffset + 1;
  240. memcpy(assRespPacket + copyOffset, taggedParams[i].data, taggedParams[i].len_data);
  241. copyOffset = copyOffset + taggedParams[i].len_data;
  242. }
  243. memcpy(assRespPacket + copyOffset, assResp.fsc, assResp.len_fsc);
  244. copyOffset = copyOffset + assResp.len_fsc;
  245. //send packet
  246. return sendPacket(pcap_h, assRespPacket, packetSize);
  247. }
  248. //Creates Probe response frame and sends it
  249. int sendProbeResponse(pcap_t *pcap_h, u_char *dstAddress)
  250. {
  251. #define numberOfProbeInfoElems (3) //number of information elements
  252. //definition of all information elements
  253. infoElem ssid = {
  254. 0, //id
  255. 6, //len
  256. 6, //real length of data
  257. "\x46\x75\x7a\x7a\x41\x50" //data
  258. };
  259. infoElem suppRates = {
  260. 1, //id
  261. 7, //len
  262. 7, //real length of data
  263. "\x96\x18\x24\x30\x48\x60\x6c" //data
  264. };
  265. infoElem dsParam = {
  266. 3, //id
  267. 1, //len
  268. 1, //real length of data
  269. "\x01" //data
  270. };
  271. //create array of information elements
  272. infoElem taggedParams[numberOfProbeInfoElems] = {ssid, suppRates, dsParam};
  273. //length of all info elements, including id and len field
  274. int len_taggedParams = 0;
  275. for(int i = 0; i < numberOfProbeInfoElems; i++)
  276. {
  277. //+2 to include id and len field size
  278. len_taggedParams = len_taggedParams + taggedParams[i].len_data+2;
  279. }
  280. //fill in struct
  281. probeResponse probeResp = {
  282. 36, radioTapHeader, //RadioTap hdr (overwritten by firmware)
  283. 1, "\x50", //Type
  284. 1, "\x00", //Flags
  285. 2, "\x3a\x01", //Duration
  286. 6, dstAddress, //DST addr
  287. 6, myMAC, //Source addr
  288. 6, myMAC, //BSS addr
  289. 2, "\x00\x00", //Seq nr (overwritten by firmware)
  290. 8, "\x00\x00\x00\x00\x00\x00\x00\x00", //Timestamp (overwritten by firmware)
  291. 2, "\x64\x00", //Beacon interval
  292. 2, "\x01\x00", //Capab info
  293. len_taggedParams,
  294. taggedParams, //Information elements
  295. 4, "\x00\x00\x00\x00" //FSC (overwritten by firmware)
  296. };
  297. //calculate size of final packet
  298. int packetSize = probeResp.len_radioTapHdr
  299. + probeResp.len_type
  300. + probeResp.len_flags
  301. + probeResp.len_duration
  302. + probeResp.len_destAddr
  303. + probeResp.len_sourceAddr
  304. + probeResp.len_bssAddr
  305. + probeResp.len_seqNr
  306. + probeResp.len_timeStamp
  307. + probeResp.len_beaconInterval
  308. + probeResp.len_capabInfo
  309. + probeResp.len_taggedParams
  310. + probeResp.len_fsc;
  311. //define packet
  312. u_char probeRespPacket[packetSize];
  313. //copy all struct fields into packet
  314. int copyOffset = 0;
  315. memcpy(probeRespPacket + copyOffset, probeResp.radioTapHdr, probeResp.len_radioTapHdr);
  316. copyOffset = copyOffset + probeResp.len_radioTapHdr;
  317. memcpy(probeRespPacket + copyOffset, probeResp.type, probeResp.len_type);
  318. copyOffset = copyOffset + probeResp.len_type;
  319. memcpy(probeRespPacket + copyOffset, probeResp.flags, probeResp.len_flags);
  320. copyOffset = copyOffset + probeResp.len_flags;
  321. memcpy(probeRespPacket + copyOffset, probeResp.duration, probeResp.len_duration);
  322. copyOffset = copyOffset + probeResp.len_duration;
  323. memcpy(probeRespPacket + copyOffset, probeResp.destAddr, probeResp.len_destAddr);
  324. copyOffset = copyOffset + probeResp.len_destAddr;
  325. memcpy(probeRespPacket + copyOffset, probeResp.sourceAddr, probeResp.len_sourceAddr);
  326. copyOffset = copyOffset + probeResp.len_sourceAddr;
  327. memcpy(probeRespPacket + copyOffset, probeResp.bssAddr, probeResp.len_bssAddr);
  328. copyOffset = copyOffset + probeResp.len_bssAddr;
  329. memcpy(probeRespPacket + copyOffset, probeResp.seqNr, probeResp.len_seqNr);
  330. copyOffset = copyOffset + probeResp.len_seqNr;
  331. memcpy(probeRespPacket + copyOffset, probeResp.timeStamp, probeResp.len_timeStamp);
  332. copyOffset = copyOffset + probeResp.len_timeStamp;
  333. memcpy(probeRespPacket + copyOffset, probeResp.beaconInterval, probeResp.len_beaconInterval);
  334. copyOffset = copyOffset + probeResp.len_beaconInterval;
  335. memcpy(probeRespPacket + copyOffset, probeResp.capabInfo, probeResp.len_capabInfo);
  336. copyOffset = copyOffset + probeResp.len_capabInfo;
  337. //copy all information elements
  338. for(int i = 0; i < numberOfProbeInfoElems; i++)
  339. {
  340. memcpy(probeRespPacket + copyOffset, &taggedParams[i].id, 1);
  341. copyOffset = copyOffset + 1;
  342. memcpy(probeRespPacket + copyOffset, &taggedParams[i].len, 1);
  343. copyOffset = copyOffset + 1;
  344. memcpy(probeRespPacket + copyOffset, taggedParams[i].data, taggedParams[i].len_data);
  345. copyOffset = copyOffset + taggedParams[i].len_data;
  346. }
  347. memcpy(probeRespPacket + copyOffset, probeResp.fsc, probeResp.len_fsc);
  348. copyOffset = copyOffset + probeResp.len_fsc;
  349. //send packet
  350. return sendPacket(pcap_h, probeRespPacket, packetSize);
  351. }
  352. int main(int argc, char *argv[])
  353. {
  354. pcap_t *pcap_h;
  355. struct bpf_program fp;
  356. struct pcap_pkthdr header;
  357. char *dev;
  358. char errbuf[PCAP_ERRBUF_SIZE];
  359. //check argument number
  360. if(argc != 2)
  361. {
  362. printf("Usage: %s device\n", argv[0]);
  363. exit(EXIT_FAILURE);
  364. }
  365. dev = argv[1];
  366. //initialize libpcap
  367. if((pcap_h = pcap_create(dev, errbuf)) == NULL)
  368. {
  369. printf("pcap_create() failed: %s\n", errbuf);
  370. exit(EXIT_FAILURE);
  371. }
  372. if(pcap_can_set_rfmon(pcap_h) == 0)
  373. {
  374. printf("Monitor mode can not be set.\n");
  375. exit(EXIT_FAILURE);
  376. }
  377. if(pcap_set_rfmon(pcap_h, 1) != 0)
  378. {
  379. printf("Failed to set monitor mode.\n");
  380. exit(EXIT_FAILURE);
  381. }
  382. if(pcap_activate(pcap_h) != 0)
  383. {
  384. printf("pcap_activate() failed\n");
  385. exit(EXIT_FAILURE);
  386. }
  387. //compile filter for incoming packets
  388. if(pcap_compile(pcap_h, &fp, getFilterString() , 0, PCAP_NETMASK_UNKNOWN) == -1)
  389. {
  390. printf("failed pcap_compile() with error: %s\n", pcap_geterr(pcap_h));
  391. exit(EXIT_FAILURE);
  392. }
  393. //apply filter
  394. if(pcap_setfilter(pcap_h, &fp) == -1)
  395. {
  396. printf("failed pcap_setfilter() with error: %s\n", pcap_geterr(pcap_h));
  397. exit(EXIT_FAILURE);
  398. }
  399. //free memory allocated by pcap_compile()
  400. pcap_freecode(&fp);
  401. //flag to indicate if we have to listen for ACK verification
  402. int waitForACK = 0;
  403. //infinite listen-respond loop
  404. while (1)
  405. {
  406. //receive packet
  407. const u_char *packet = pcap_next(pcap_h, &header);
  408. u_char frameType = getFrameTypeOfPacket(packet);
  409. u_char* sourceAddr;
  410. if (frameType != 0xd4) //ACK frames have no source address
  411. sourceAddr = getSourceAddrOfPacket(packet);
  412. //if we had to wait for an ACK, verify if current frame is an ACK
  413. if (waitForACK != 0)
  414. {
  415. if (frameType == 0xd4)
  416. {
  417. switch (waitForACK)
  418. {
  419. case 1:
  420. {
  421. printf("Association response ACKed\n");
  422. break;
  423. }
  424. case 2:
  425. {
  426. printf("Authentication frame ACKed\n");
  427. break;
  428. }
  429. case 3:
  430. {
  431. printf("Probe response ACKed\n");
  432. break;
  433. }
  434. default:
  435. {
  436. printf("Frame ACKed\n");
  437. break;
  438. }
  439. }
  440. }
  441. else
  442. {
  443. printf("Not sure if frame was ACKed\n");
  444. }
  445. waitForACK = 0;
  446. }
  447. else //Process frame depending on type
  448. {
  449. switch(frameType)
  450. {
  451. case 0x40:
  452. {
  453. sendProbeResponse(pcap_h, sourceAddr);
  454. //do not wait for ACKs of probe response, because we focus on
  455. //the authentication and association process
  456. //waitForACK = 3;
  457. break;
  458. }
  459. case 0xb0:
  460. {
  461. sendAuthResponse(pcap_h, sourceAddr);
  462. waitForACK = 2;
  463. break;
  464. }
  465. case 0x00:
  466. {
  467. sendAssResponse(pcap_h, sourceAddr);
  468. waitForACK = 1;
  469. break;
  470. }
  471. case 0xd4:
  472. {
  473. break;
  474. }
  475. default: break;
  476. }
  477. }
  478. }
  479. return 0;
  480. }