slitheen-proxy.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /* Name: slitheen-proxy.c
  2. *
  3. * Slitheen - a decoy routing system for censorship resistance
  4. * Copyright (C) 2017 Cecylia Bocovich (cbocovic@uwaterloo.ca)
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, version 3.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * Additional permission under GNU GPL version 3 section 7
  19. *
  20. * If you modify this Program, or any covered work, by linking or combining
  21. * it with the OpenSSL library (or a modified version of that library),
  22. * containing parts covered by the terms of [name of library's license],
  23. * the licensors of this Program grant you additional permission to convey
  24. * the resulting work. {Corresponding Source for a non-source form of such
  25. * a combination shall include the source code for the parts of the OpenSSL
  26. * library used as well as that of the covered work.}
  27. */
  28. #include <pcap.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <unistd.h>
  32. #include <string.h>
  33. #include <pthread.h>
  34. #include <sys/ioctl.h>
  35. #include <net/if.h>
  36. #include <openssl/ssl.h>
  37. #include "util.h"
  38. #include "flow.h"
  39. #include "slitheen.h"
  40. #include "relay.h"
  41. #include "crypto.h"
  42. #include "cryptothread.h"
  43. void save_packet(flow *f, struct packet_info *info);
  44. void update_window_expiration(flow *f, struct packet_info *info);
  45. void retransmit(flow *f, struct packet_info *info, uint32_t data_to_fill);
  46. void usage(void){
  47. printf("Usage: slitheen-proxy [internal network interface] [NAT interface]\n");
  48. }
  49. int main(int argc, char *argv[]){
  50. pthread_t t1, t2;
  51. char *dev1 = NULL; /* Device that leads to the internal network */
  52. char *dev2 = NULL; /* Device that leads out to the world */
  53. struct sniff_args outbound;
  54. struct sniff_args inbound;
  55. if (argc != 3) {
  56. usage();
  57. return(2);
  58. }
  59. dev1 = argv[1];
  60. dev2 = argv[2];
  61. if(init_tables()){
  62. exit(1);
  63. }
  64. if(init_session_cache()){
  65. exit(1);
  66. }
  67. init_crypto_locks();
  68. /* Create threads */
  69. outbound.readdev = dev1;
  70. outbound.writedev = dev2;
  71. inbound.readdev = dev2;
  72. inbound.writedev = dev1;
  73. pthread_create(&t1, NULL, sniff_packets, (void *) &outbound);
  74. pthread_create(&t2, NULL, sniff_packets, (void *) &inbound);
  75. pthread_join(t1, NULL);
  76. pthread_join(t2, NULL);
  77. pthread_exit(NULL);
  78. crypto_locks_cleanup();
  79. return(0);
  80. }
  81. void *sniff_packets(void *args){
  82. pcap_t *rd_handle;
  83. pcap_t *wr_handle;
  84. char rd_errbuf[BUFSIZ];
  85. char wr_errbuf[BUFSIZ];
  86. uint8_t MAC[ETHER_ADDR_LEN];
  87. bpf_u_int32 mask;
  88. bpf_u_int32 net;
  89. char *readdev, *writedev;
  90. struct sniff_args *arg_st = (struct sniff_args *) args;
  91. readdev = arg_st->readdev;
  92. writedev = arg_st->writedev;
  93. //Find MAC address of each interface
  94. struct ifreq ifr;
  95. int s = socket(AF_INET, SOCK_DGRAM, 0);
  96. strcpy(ifr.ifr_name, writedev);
  97. ioctl(s, SIOCGIFHWADDR, &ifr);
  98. memcpy(MAC, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
  99. close(s);
  100. if (pcap_lookupnet(readdev, &net, &mask, rd_errbuf) == -1){
  101. fprintf(stderr, "Can't get netmask for device %s\n", readdev);
  102. exit(2);
  103. }
  104. rd_handle = pcap_open_live(readdev, BUFSIZ, 0, 0, rd_errbuf);
  105. if (rd_handle == NULL){
  106. fprintf(stderr, "Couldn't open device %s: %s\n", readdev, rd_errbuf);
  107. }
  108. if(pcap_datalink(rd_handle) != DLT_EN10MB) {
  109. fprintf(stderr, "Device %s does not provide Ethernet headers - not supported\n", readdev);
  110. exit(2);
  111. }
  112. if(pcap_setdirection(rd_handle, PCAP_D_IN)){
  113. fprintf(stderr, "Platform does not support write direction. Update filters with MAC address\n");
  114. exit(2);
  115. }
  116. wr_handle = pcap_open_live(writedev, BUFSIZ, 0, 0, wr_errbuf);
  117. if (wr_handle == NULL){
  118. fprintf(stderr, "Couldn't open device %s: %s\n", writedev, wr_errbuf);
  119. }
  120. struct inject_args iargs;
  121. iargs.mac_addr = MAC;
  122. iargs.write_dev = wr_handle;
  123. /*callback function*/
  124. pcap_loop(rd_handle, -1, got_packet, (unsigned char *) &iargs);
  125. /*Sniff a packet*/
  126. pcap_close(rd_handle);
  127. return NULL;
  128. }
  129. /*
  130. * Injects a packet back out the opposite interface
  131. */
  132. void inject_packet(struct inject_args *iargs, const struct pcap_pkthdr *header, uint8_t *packet){
  133. pcap_t *handle = iargs->write_dev;
  134. //write back out to the MAC ADDR it came in on
  135. memmove(packet, packet+ETHER_ADDR_LEN, ETHER_ADDR_LEN);
  136. memcpy(packet+ETHER_ADDR_LEN, iargs->mac_addr, ETHER_ADDR_LEN);
  137. if((pcap_inject(handle, packet, header->len)) < 0 ){
  138. fprintf(stderr, "Error: %s\n", pcap_geterr(handle));
  139. printf("Length: %d\n", header->len);
  140. }
  141. #ifdef DEBUG
  142. fprintf(stderr, "injected the following packet:\n");
  143. for(int i=0; i< header->len; i++){
  144. fprintf(stderr, "%02x ", packet[i]);
  145. }
  146. fprintf(stderr, "\n");
  147. #endif
  148. free(packet);
  149. }
  150. /**
  151. * Runs when pcap_loop receives a packet from the specified interface
  152. * If the received packet is a tcp packet, processes it and then writes it back out
  153. * to the interface
  154. *
  155. */
  156. void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const uint8_t *packet){
  157. struct inject_args *iargs = (struct inject_args *) args;
  158. uint8_t *tmp_packet = emalloc(header->len);
  159. memcpy(tmp_packet, packet, header->len);
  160. process_packet(iargs, header, tmp_packet);
  161. }
  162. /* This function receives a full ip packet and then:
  163. * 1) identifies the flow
  164. * 2) adds the packet to the flow's data chain
  165. * 3) updates the flow's state
  166. */
  167. void process_packet(struct inject_args *iargs, const struct pcap_pkthdr *header, uint8_t *packet){
  168. struct packet_info *info = emalloc(sizeof(struct packet_info));
  169. extract_packet_headers(packet, info);
  170. //Ignore non-TCP packets (shouldn't actually get any)
  171. if((info->ip_hdr == NULL) || (info->tcp_hdr == NULL)){
  172. free(info);
  173. free(packet);
  174. return;
  175. }
  176. /* Checks to see if this is a possibly tagged hello msg */
  177. if ((info->record_hdr != NULL) && (info->record_hdr->type == HS)){ /* This is a TLS handshake */
  178. check_handshake(info);
  179. }
  180. /* Now if flow is in table, update state */
  181. flow *observed;
  182. if((observed = check_flow(info)) != NULL){
  183. #ifdef DEBUG
  184. /*Check sequence number and replay application data if necessary*/
  185. fprintf(stdout,"Flow: %x:%d > %x:%d (%s)\n", info->ip_hdr->src.s_addr, ntohs(info->tcp_hdr->src_port), info->ip_hdr->dst.s_addr, ntohs(info->tcp_hdr->dst_port), (info->ip_hdr->src.s_addr != observed->src_ip.s_addr)? "incoming":"outgoing");
  186. fprintf(stdout,"ID number: %u\n", htonl(info->ip_hdr->id));
  187. fprintf(stdout,"Sequence number: %u\n", htonl(info->tcp_hdr->sequence_num));
  188. fprintf(stdout,"Acknowledgement number: %u\n", htonl(info->tcp_hdr->ack_num));
  189. #endif
  190. uint8_t incoming = (info->ip_hdr->src.s_addr != observed->src_ip.s_addr)? 1 : 0;
  191. uint32_t seq_num = htonl(info->tcp_hdr->sequence_num);
  192. uint32_t expected_seq = (incoming)? observed->downstream_seq_num : observed->upstream_seq_num;
  193. #ifdef DEBUG
  194. fprintf(stdout,"Expected sequence number: %u\n", expected_seq);
  195. #endif
  196. /* Remove acknowledged data from queue after TCP window is exceeded */
  197. update_window_expiration(observed, info);
  198. /* fill with retransmit data, process new data */
  199. uint32_t data_to_fill;
  200. uint32_t data_to_process;
  201. if(seq_num > expected_seq){
  202. data_to_process = info->app_data_len;
  203. data_to_fill = 0;
  204. } else if (seq_num + info->app_data_len > expected_seq){
  205. data_to_fill = expected_seq - seq_num;
  206. data_to_process = seq_num + info->app_data_len - expected_seq;
  207. } else {
  208. data_to_fill = info->app_data_len;
  209. data_to_process = 0;
  210. }
  211. uint8_t *p = info->app_data;
  212. if(data_to_fill){ //retransmit
  213. printf("Retransmiting data (%u:%u)\n", seq_num, seq_num + info->app_data_len);
  214. retransmit(observed, info, data_to_fill);
  215. }
  216. p += data_to_fill;
  217. if(data_to_process){
  218. if(p != info->app_data){
  219. printf("UH OH something weird might happen\n");
  220. }
  221. if(observed->application){
  222. if(seq_num > expected_seq){
  223. //For now, enters into FORFEIT state
  224. //TODO: change upstream behaviour to try to mask slitheen hdr
  225. //printf("ERROR: future packet in app data, forfeiting flow\n");
  226. remove_flow(observed);
  227. goto err;
  228. }
  229. replace_packet(observed, info);
  230. } else {
  231. //We're still in the TLS handshake; hold packets misordered packets
  232. if(seq_num > expected_seq){
  233. //Delay and process later
  234. frame *new_frame = ecalloc(1, sizeof(frame));
  235. new_frame->iargs = iargs;
  236. new_frame->packet = packet;
  237. new_frame->header = header;
  238. new_frame->seq_num = seq_num;
  239. new_frame->next = NULL;
  240. frame_queue *queue = (incoming) ? observed->ds_frame_queue : observed->us_frame_queue;
  241. printf("Delay processing of frame (seq = %u )\n", seq_num);
  242. //add to end of list
  243. if(queue->first_frame == NULL){
  244. queue->first_frame = new_frame;
  245. } else {
  246. frame *last = queue->first_frame;
  247. while(last->next != NULL){
  248. last = last->next;
  249. }
  250. last->next = new_frame;
  251. }
  252. free(info);
  253. observed->ref_ctr--;
  254. printf("Misordered packet. %p ref_ctr %d\n", observed, observed->ref_ctr);
  255. return; //TODO: fix terrible spaghetti returns
  256. }
  257. /* Pass data to packet chain */
  258. if(observed->stall){
  259. }
  260. if(add_packet(observed, info)){//removed_flow
  261. goto err;
  262. }
  263. }
  264. /* Update TCP state */
  265. if(info->tcp_hdr->flags & (FIN | RST) ){
  266. /* Remove flow from table, connection ended */
  267. remove_flow(observed);
  268. goto err;
  269. }
  270. /* add packet to application data queue */
  271. save_packet(observed, info);
  272. }
  273. /*process and release held frames with current sequence numbers*/
  274. frame_queue *queue = (incoming) ? observed->ds_frame_queue : observed->us_frame_queue;
  275. frame *first = queue->first_frame;
  276. frame *prev = queue->first_frame;
  277. expected_seq = (incoming)? observed->downstream_seq_num : observed->upstream_seq_num;
  278. while (first != NULL){
  279. if(first->seq_num <= expected_seq){
  280. //remove from queue and process
  281. if(first == queue->first_frame) {
  282. queue->first_frame = first->next;
  283. } else {
  284. prev->next = first->next;
  285. }
  286. printf("Now processing frame (seq = %u )\n", first->seq_num);
  287. process_packet(iargs, first->header, first->packet);
  288. free(first);
  289. first = queue->first_frame;
  290. prev = queue->first_frame;
  291. } else {
  292. prev = first;
  293. first = first->next;
  294. }
  295. }
  296. observed->ref_ctr--;
  297. printf("Finished processing packet. %p ref_ctr %d\n", observed, observed->ref_ctr);
  298. }
  299. err:
  300. free(info);//Note: don't free this while a thread is using it
  301. inject_packet(iargs, header, packet);
  302. return;
  303. }
  304. //TODO: rewrite this function to remove bloat
  305. void save_packet(flow *f, struct packet_info *info){
  306. uint8_t incoming = (info->ip_hdr->src.s_addr != f->src_ip.s_addr)? 1 : 0;
  307. uint32_t seq_num = htonl(info->tcp_hdr->sequence_num);
  308. //add new app block
  309. packet *new_block = ecalloc(1, sizeof(packet));
  310. new_block->seq_num = htonl(info->tcp_hdr->sequence_num);
  311. new_block->data = ecalloc(1, info->app_data_len);
  312. memcpy(new_block->data, info->app_data, info->app_data_len);
  313. new_block->len = info->app_data_len;
  314. new_block->next = NULL;
  315. new_block->expiration = 0;
  316. packet *saved_data = (incoming)? f->downstream_app_data->first_packet :
  317. f->upstream_app_data->first_packet;
  318. //put app data block in queue
  319. if(saved_data == NULL){
  320. if(incoming){
  321. f->downstream_app_data->first_packet = new_block;
  322. if(new_block->seq_num ==
  323. f->downstream_seq_num){
  324. f->downstream_seq_num += new_block->len;
  325. #ifdef DEBUG
  326. printf("Updated downstream expected seqnum to %u\n",
  327. f->downstream_seq_num );
  328. #endif
  329. }
  330. } else {
  331. f->upstream_app_data->first_packet = new_block;
  332. if(new_block->seq_num ==
  333. f->upstream_seq_num){
  334. f->upstream_seq_num += new_block->len;
  335. #ifdef DEBUG
  336. printf("Updated upstream expected seqnum to %u\n",
  337. f->upstream_seq_num );
  338. #endif
  339. }
  340. }
  341. } else {
  342. uint8_t saved = 0;
  343. while(saved_data->next != NULL){
  344. if(!saved && (saved_data->next->seq_num > seq_num)){
  345. new_block->next = saved_data->next;
  346. saved_data->next = new_block;
  347. saved = 1;
  348. }
  349. //update expected sequence number
  350. if(incoming){
  351. if(saved_data->next->seq_num ==
  352. f->downstream_seq_num){
  353. f->downstream_seq_num += saved_data->next->len;
  354. #ifdef DEBUG
  355. printf("Updated downstream expected seqnum to %u\n",
  356. f->downstream_seq_num );
  357. #endif
  358. }
  359. } else {//outgoing
  360. if(saved_data->next->seq_num ==
  361. f->upstream_seq_num){
  362. f->upstream_seq_num += saved_data->next->len;
  363. #ifdef DEBUG
  364. printf("Updated upstream expected seqnum to %u\n",
  365. f->upstream_seq_num );
  366. #endif
  367. }
  368. }
  369. saved_data = saved_data->next;
  370. }
  371. if(!saved){
  372. saved_data->next = new_block;
  373. //update expected sequence number
  374. if(incoming){
  375. if(saved_data->next->seq_num ==
  376. f->downstream_seq_num){
  377. f->downstream_seq_num += saved_data->next->len;
  378. #ifdef DEBUG
  379. printf("Updated downstream expected seqnum to %u\n",
  380. f->downstream_seq_num );
  381. #endif
  382. }
  383. } else {//outgoing
  384. if(saved_data->next->seq_num ==
  385. f->upstream_seq_num){
  386. f->upstream_seq_num += saved_data->next->len;
  387. #ifdef DEBUG
  388. printf("Updated upstream expected seqnum to %u\n",
  389. f->upstream_seq_num );
  390. #endif
  391. }
  392. }
  393. }
  394. }
  395. }
  396. /**
  397. * This function cleans up data that has been acked, after the TCP window of the recipient has been
  398. * exceeded. This ensures that a retransmisson of the data will no longer occur.
  399. *
  400. * Sets the expiration for recent data base on the TCP window
  401. */
  402. void update_window_expiration(flow *f, struct packet_info *info){
  403. uint8_t incoming = (info->ip_hdr->src.s_addr != f->src_ip.s_addr)? 1 : 0;
  404. uint32_t ack_num = htonl(info->tcp_hdr->ack_num);
  405. uint32_t end_seq = htonl(info->tcp_hdr->sequence_num) + info->app_data_len - 1;
  406. uint32_t window = ack_num + htons(info->tcp_hdr->win_size);
  407. #ifdef DEBUG
  408. printf("Received sequence number %u\n", htonl(info->tcp_hdr->sequence_num));
  409. printf("Acknowledged up to %u with window expiring at %u\n", ack_num, window);
  410. printf("Removing all packets up to %u\n", end_seq);
  411. #endif
  412. packet *saved_data = (incoming)? f->downstream_app_data->first_packet :
  413. f->upstream_app_data->first_packet;
  414. while((saved_data != NULL) && (saved_data->expiration != 0) && (end_seq > saved_data->expiration)){
  415. //remove entire block
  416. if(incoming){
  417. f->downstream_app_data->first_packet = saved_data->next;
  418. } else {
  419. f->upstream_app_data->first_packet = saved_data->next;
  420. }
  421. free(saved_data->data);
  422. free(saved_data);
  423. saved_data = (incoming)? f->downstream_app_data->first_packet :
  424. f->upstream_app_data->first_packet;
  425. #ifdef DEBUG
  426. if(saved_data != NULL){
  427. printf("Currently saved seq_num is now %u\n", saved_data->seq_num);
  428. } else {
  429. printf("Acked all data, queue is empty\n");
  430. }
  431. #endif
  432. }
  433. /* Update expiration for packets based on TCP window size */
  434. saved_data = (incoming)? f->upstream_app_data->first_packet :
  435. f->downstream_app_data->first_packet;
  436. while((saved_data != NULL) && (ack_num > saved_data->seq_num)){
  437. //update window
  438. if(ack_num >= saved_data->seq_num + saved_data->len){
  439. //remove entire block
  440. saved_data->expiration = window;
  441. }
  442. saved_data = saved_data->next;
  443. }
  444. }
  445. /**
  446. * This function retransmits previously sent (and possibly modified) data
  447. *
  448. */
  449. void retransmit(flow *f, struct packet_info *info, uint32_t data_to_fill){
  450. uint8_t *p = info->app_data;
  451. uint32_t seq_num = htonl(info->tcp_hdr->sequence_num);
  452. uint8_t incoming = (info->ip_hdr->src.s_addr != f->src_ip.s_addr)? 1 : 0;
  453. packet *saved_data = (incoming)? f->downstream_app_data->first_packet :
  454. f->upstream_app_data->first_packet;
  455. while(data_to_fill > 0){
  456. if(saved_data == NULL){
  457. //have already acked all data
  458. p += data_to_fill;
  459. seq_num += data_to_fill;
  460. data_to_fill -= data_to_fill;
  461. continue;
  462. }
  463. if(seq_num < saved_data->seq_num){
  464. //we are missing a block. Use what was given
  465. if(saved_data->seq_num - seq_num > data_to_fill){
  466. //skip the rest
  467. p += data_to_fill;
  468. seq_num += data_to_fill;
  469. data_to_fill -= data_to_fill;
  470. } else {
  471. p += saved_data->seq_num - seq_num;
  472. data_to_fill -= saved_data->seq_num - seq_num;
  473. seq_num += saved_data->seq_num - seq_num;
  474. }
  475. } else if ( seq_num == saved_data->seq_num) {
  476. if(data_to_fill >= saved_data->len){
  477. //exhaust this block and move onto next one
  478. memcpy(p, saved_data->data, saved_data->len);
  479. p += saved_data->len;
  480. seq_num += saved_data->len;
  481. data_to_fill -= saved_data->len;
  482. saved_data = saved_data->next;
  483. } else {
  484. //fill with partial block
  485. memcpy(p, saved_data->data, data_to_fill);
  486. p += data_to_fill;
  487. seq_num += data_to_fill;
  488. data_to_fill -= data_to_fill;
  489. }
  490. } else { //seq_num > saved_data->seq_num
  491. uint32_t offset = seq_num - saved_data->seq_num;
  492. if(offset > saved_data->len){
  493. saved_data = saved_data->next;
  494. offset -= saved_data->len;
  495. } else {
  496. if(data_to_fill > saved_data->len - offset){
  497. memcpy(p, saved_data->data + offset, saved_data->len - offset);
  498. p += saved_data->len - offset;
  499. seq_num += saved_data->len - offset;
  500. data_to_fill -= saved_data->len - offset;
  501. saved_data = saved_data->next;
  502. } else {
  503. memcpy(p, saved_data->data + offset, data_to_fill);
  504. p += data_to_fill;
  505. seq_num += data_to_fill;
  506. data_to_fill -= data_to_fill;
  507. }
  508. }
  509. }
  510. }
  511. tcp_checksum(info);//update checksum
  512. }
  513. /** This function extracts the ip, tcp, and tls record headers
  514. * from a received packet (if they exist), and put them in
  515. * a packet_info struct
  516. *
  517. */
  518. void extract_packet_headers(uint8_t *packet, struct packet_info *info){
  519. /* First fill in IP header */
  520. uint8_t *p = packet;
  521. p += ETHER_HEADER_LEN; //skip ethernet header
  522. info->ip_hdr = (struct ip_header*) p;
  523. info->size_ip_hdr = IP_HEADER_LEN(info->ip_hdr);
  524. /* Verify this is an IP packet */
  525. if( (info->ip_hdr->versionihl >>4) != 4){
  526. info->ip_hdr = NULL;
  527. info->size_ip_hdr = 0;
  528. info->tcp_hdr = NULL;
  529. info->size_tcp_hdr = 0;
  530. info->record_hdr = NULL;
  531. return;
  532. }
  533. /* If this is a TCP segment, fill in TCP header */
  534. if (info->ip_hdr->proto == IPPROTO_TCP){
  535. p += info->size_ip_hdr; //skip IP header
  536. info->tcp_hdr = (struct tcp_header*) p;
  537. info->size_tcp_hdr = TCP_HEADER_LEN(info->tcp_hdr);
  538. p += info->size_tcp_hdr;
  539. } else {
  540. info->tcp_hdr = NULL;
  541. info->size_tcp_hdr = 0;
  542. info->record_hdr = NULL;
  543. return;
  544. }
  545. /* If the application data contains a TLS record, fill in hdr */
  546. info->app_data_len = htons(info->ip_hdr->len) - (info->size_ip_hdr + info->size_tcp_hdr);
  547. if(info->app_data_len > 0){
  548. info->app_data = p;
  549. info->record_hdr = (struct tls_header*) p;
  550. //check to see if this is a valid record
  551. if((info->record_hdr->type < 0x14) || (info->record_hdr->type > 0x18)){
  552. info->record_hdr = NULL;
  553. }
  554. } else {
  555. info->record_hdr = NULL;
  556. info->app_data = NULL;
  557. }
  558. return;
  559. }
  560. /** Copies a packet_info structure and returns a pointer to the duplicate.
  561. */
  562. struct packet_info *copy_packet_info(struct packet_info *src_info){
  563. struct packet_info *dst_info = emalloc(sizeof(struct packet_info));
  564. dst_info->ip_hdr = src_info->ip_hdr;
  565. dst_info->tcp_hdr = src_info->tcp_hdr;
  566. dst_info->size_tcp_hdr = src_info->size_tcp_hdr;
  567. dst_info->size_ip_hdr = src_info->size_ip_hdr;
  568. dst_info->app_data = src_info->app_data;
  569. dst_info->app_data_len = src_info->app_data_len;
  570. return dst_info;
  571. }