flow.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <pthread.h>
  5. #include <errno.h>
  6. #include "flow.h"
  7. #include "crypto.h"
  8. #include "slitheen.h"
  9. #include "relay.h"
  10. static flow_table *table;
  11. static session_cache *sessions;
  12. data_queue *downstream_queue;
  13. /* Initialize the table of tagged flows */
  14. int init_tables(void) {
  15. table = calloc(1, sizeof(flow_table));
  16. table->first_entry = NULL;
  17. table->len = 0;
  18. downstream_queue = calloc(1, sizeof(data_queue));
  19. downstream_queue->first_block = NULL;
  20. printf("initialized downstream queue\n");
  21. return 0;
  22. }
  23. /* Add a new flow to the tagged flow table */
  24. flow *add_flow(flow newFlow) {
  25. flow_entry *entry = calloc(1, sizeof(flow_entry));
  26. flow *ptr = calloc(1, sizeof(flow));
  27. entry->f = ptr;
  28. entry->next = NULL;
  29. printf("there are %d flows in the table\n", table->len);
  30. newFlow.state = TLS_CLNT_HELLO;
  31. newFlow.in_encrypted = 0;
  32. newFlow.out_encrypted = 0;
  33. newFlow.application = 0;
  34. newFlow.resume_session = 0;
  35. newFlow.current_session = NULL;
  36. newFlow.packet_chain = NULL;
  37. newFlow.censored_queue = NULL;
  38. newFlow.outbox_len = 0;
  39. newFlow.remaining_record_len = 0;
  40. newFlow.remaining_response_len = 0;
  41. newFlow.httpstate = PARSE_HEADER;
  42. newFlow.replace_response = 0;
  43. newFlow.finish_md_ctx = EVP_MD_CTX_create();
  44. const EVP_MD *md = EVP_sha384();
  45. EVP_DigestInit_ex(newFlow.finish_md_ctx, md, NULL);
  46. memset(newFlow.read_seq, 0, 8);
  47. memset(newFlow.write_seq, 0, 8);
  48. *ptr = newFlow;
  49. flow_entry *last = table->first_entry;
  50. if(last == NULL){
  51. table->first_entry = entry;
  52. } else {
  53. for(int i=0; i< table->len-1; i++){
  54. last = last->next;
  55. }
  56. last->next = entry;
  57. }
  58. table->len ++;
  59. return ptr;
  60. }
  61. /** Observes TLS handshake messages and updates the state of
  62. * the flow
  63. *
  64. * Inputs:
  65. * f: the tagged flow
  66. *
  67. * Output:
  68. * 0 on success, 1 on failure
  69. */
  70. int update_flow(flow *f) {
  71. uint8_t *record;
  72. const struct record_header *record_hdr;
  73. const struct handshake_header *handshake_hdr;
  74. uint8_t *p = f->packet_chain->data;
  75. record_hdr = (struct record_header*) p;
  76. int record_len;
  77. int data_len;
  78. record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
  79. data_len = f->packet_chain->data_len;
  80. packet *current = f->packet_chain;
  81. int incoming = current->incoming;
  82. record = calloc(1, record_len);
  83. for(int i=0; (i<data_len) && (i<record_len); i++){
  84. record[i] = p[i];
  85. }
  86. while(record_len > data_len) {
  87. if(current->next == NULL){
  88. free(record);
  89. return 0;
  90. }
  91. if(current->next->seq_num != current->seq_num + current->len){
  92. printf("Missing packet: seq_num= %d, datalen= %d, nextseq= %d\n", current->seq_num, current->len, current->next->seq_num);
  93. free(record);
  94. return 0;
  95. }
  96. current = current->next;
  97. p = current->data;
  98. int i;
  99. for(i=0; (i<current->data_len) && (i+data_len < record_len); i++){
  100. record[data_len+i] = p[i];
  101. }
  102. data_len += current->data_len;
  103. }
  104. switch(record_hdr->type){
  105. case HS:
  106. p = record;
  107. p += RECORD_HEADER_LEN;
  108. if((incoming && f->in_encrypted) || (!incoming && f->out_encrypted)){
  109. printf("Decrypting finished (%d bytes) (%x:%d -> %x:%d)\n", record_len - RECORD_HEADER_LEN, f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  110. int32_t n = encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x16, 0);
  111. if(n<=0){
  112. printf("Error decrypting finished (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  113. }
  114. printf("Finished decrypted: (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  115. p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
  116. printf("record:\n");
  117. for(int i=0; i< n; i++){
  118. printf("%02x ", p[i]);
  119. }
  120. printf("\n");
  121. update_context(f, p, n, incoming, 0x16, 0);
  122. if(incoming) f->in_encrypted = 2;
  123. else f->out_encrypted = 2;
  124. }
  125. handshake_hdr = (struct handshake_header*) p;
  126. f->state = handshake_hdr->type;
  127. switch(f->state){
  128. case TLS_CLNT_HELLO:
  129. printf("Received tagged client hello (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  130. update_finish_hash(f, p);
  131. check_session(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr));
  132. break;
  133. case TLS_SERV_HELLO:
  134. printf("Received server hello (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  135. if(f->resume_session){
  136. verify_session_id(f,p);
  137. } else {
  138. save_session_id(f,p);
  139. }
  140. extract_server_random(f, p);
  141. update_finish_hash(f, p);
  142. break;
  143. case TLS_NEW_SESS:
  144. printf("Received new session\n");
  145. save_session_ticket(f, p, HANDSHAKE_MESSAGE_LEN(handshake_hdr));
  146. update_finish_hash(f, p);
  147. break;
  148. case TLS_CERT:
  149. printf("Received cert\n");
  150. update_finish_hash(f, p);
  151. break;
  152. case TLS_SRVR_KEYEX:
  153. printf("Received server keyex\n");
  154. update_finish_hash(f, p);
  155. if(extract_parameters(f, p)){
  156. printf("Error extracting params\n");
  157. }
  158. if(compute_master_secret(f)){
  159. printf("Error computing master secret\n");
  160. }
  161. break;
  162. case TLS_CERT_REQ:
  163. update_finish_hash(f, p);
  164. break;
  165. case TLS_SRVR_HELLO_DONE:
  166. printf("Received server hello done\n");
  167. update_finish_hash(f, p);
  168. break;
  169. case TLS_CERT_VERIFY:
  170. printf("received cert verify\n");
  171. update_finish_hash(f, p);
  172. break;
  173. case TLS_CLNT_KEYEX:
  174. printf("Received client key exchange\n");
  175. update_finish_hash(f, p);
  176. break;
  177. case TLS_FINISHED:
  178. printf("Received finished (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  179. verify_finish_hash(f,p, incoming);
  180. update_finish_hash(f, p);
  181. if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
  182. printf("Handshake complete!\n");
  183. f->application = 1;
  184. if(current->incoming)
  185. f->seq_num = current->seq_num + current->len;
  186. while(current->next != NULL){
  187. current = current->next;
  188. if(current->incoming)
  189. f->seq_num = current->seq_num+ current->len;
  190. }
  191. }
  192. break;
  193. default:
  194. printf("Error? (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  195. break;
  196. }
  197. break;
  198. case APP:
  199. printf("Application Data\n");
  200. break;
  201. case CCS:
  202. printf("CCS (%x:%d -> %x:%d) \n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  203. if(incoming){
  204. f->in_encrypted = 1;
  205. } else {
  206. f->out_encrypted = 1;
  207. }
  208. /*Initialize ciphers */
  209. init_ciphers(f);
  210. break;
  211. case ALERT:
  212. p = record;
  213. p += RECORD_HEADER_LEN;
  214. if(((incoming) && (f->in_encrypted > 0)) || ((!incoming) && (f->out_encrypted > 0))){
  215. encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x16, 0);
  216. p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
  217. }
  218. printf("Alert (%x:%d -> %x:%d) %02x %02x \n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port, p[0], p[1]);
  219. fflush(stdout);
  220. break;
  221. case HB:
  222. printf("Heartbeat\n");
  223. break;
  224. default:
  225. printf("Error: Not a Record (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  226. fflush(stdout);
  227. //TODO: later figure this out, for now delete
  228. f->packet_chain = f->packet_chain->next;
  229. if( f->packet_chain != NULL){
  230. update_flow(f);
  231. }
  232. return 0;
  233. }
  234. if(!f->application){
  235. f->seq_num = current->seq_num;
  236. if(record_len == data_len){
  237. /* record ended on packet boundary */
  238. f->packet_chain = current->next;
  239. } else {
  240. /* need to update data */
  241. f->packet_chain = current;
  242. current->data = current->data + (current->data_len - (data_len - record_len));
  243. current->data_len = data_len - record_len;
  244. update_flow(f);
  245. }
  246. }
  247. free(record);
  248. return 0;
  249. }
  250. /** Removes the tagged flow from the flow table: happens when
  251. * the station receives a TCP RST or FIN packet
  252. *
  253. * Input:
  254. * index: the index into the flow table of the tagged flow
  255. *
  256. * Output:
  257. * 0 on success, 1 on failure
  258. */
  259. int remove_flow(flow *f) {
  260. flow_entry *entry = table->first_entry;
  261. if(entry->f == f){
  262. table->first_entry = entry->next;
  263. free(entry->f);
  264. free(entry);
  265. printf("flow removed!\n");
  266. fflush(stdout);
  267. table->len --;
  268. return 0;
  269. }
  270. flow_entry *next;
  271. for(int i=0; i< table->len; i++){
  272. if(entry->next != NULL){
  273. next = entry->next;
  274. } else {
  275. printf("Flow not in table\n");
  276. return 1;
  277. }
  278. if(next->f == f){
  279. entry->next = next->next;
  280. free(next->f);
  281. free(next);
  282. printf("flow removed!\n");
  283. table->len --;
  284. return 0;
  285. }
  286. entry = next;
  287. }
  288. printf("Should not get here!\n");
  289. return 1;
  290. }
  291. /** Expands the flow table when we run out of space
  292. * TODO: implement and test
  293. */
  294. int grow_table() {
  295. return 0;
  296. }
  297. /** Returns the index of a flow in the flow table if
  298. * it exists, returns 0 if it is not present.
  299. *
  300. * Inputs:
  301. * observed: details for the observed flow
  302. *
  303. * Output:
  304. * index of flow in table or -1 if it doesn't exist
  305. */
  306. flow *check_flow(flow observed){
  307. /* Loop through flows in table and see if it exists */
  308. int i;
  309. flow_entry *entry = table->first_entry;
  310. flow *candidate;
  311. if(entry == NULL)
  312. return NULL;
  313. /* Check first in this direction */
  314. for(i=0; i<table->len; i++){
  315. if(entry == NULL){
  316. printf("Error: entry is null\n");
  317. break;
  318. }
  319. candidate = entry->f;
  320. if(candidate->src_ip.s_addr == observed.src_ip.s_addr){
  321. if(candidate->dst_ip.s_addr == observed.dst_ip.s_addr){
  322. if(candidate->src_port == observed.src_port){
  323. if(candidate->dst_port == observed.dst_port){
  324. return candidate;
  325. }
  326. }
  327. }
  328. }
  329. entry = entry->next;
  330. }
  331. entry = table->first_entry;
  332. /* Then in the other direction */
  333. for(i=0; i<table->len; i++){
  334. if(entry == NULL){
  335. printf("Error: entry is null\n");
  336. break;
  337. }
  338. candidate = entry->f;
  339. if(candidate->src_ip.s_addr == observed.dst_ip.s_addr){
  340. if(candidate->dst_ip.s_addr == observed.src_ip.s_addr){
  341. if(candidate->src_port == observed.dst_port){
  342. if(candidate->dst_port == observed.src_port){
  343. return candidate;
  344. }
  345. }
  346. }
  347. }
  348. entry = entry->next;
  349. }
  350. return NULL;
  351. }
  352. /** Returns the flow in the flow table at a specified index
  353. *
  354. * Input:
  355. * index: the desired index of the flow table
  356. *
  357. * Output:
  358. * the flow at the specified index
  359. flow *get_flow(int index){
  360. if(index < table->len){
  361. return table->table+index;
  362. } else {
  363. return NULL;
  364. }
  365. }
  366. */
  367. int init_session_cache(void){
  368. sessions = malloc(sizeof(session_cache));
  369. sessions->length = 0;
  370. sessions->first_session = NULL;
  371. return 0;
  372. }
  373. /** Called from ServerHello, verifies that the session id returned matches
  374. * the session id requested from the client hello
  375. *
  376. * Input:
  377. * f: the tagged flow
  378. * hs: a pointer to the ServerHello message
  379. *
  380. * Output:
  381. * 0 if success, 1 if failed
  382. */
  383. int verify_session_id(flow *f, uint8_t *hs){
  384. //increment pointer to point to sessionid
  385. uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
  386. p += 2; //skip version
  387. p += SSL3_RANDOM_SIZE; //skip random
  388. uint8_t id_len = (uint8_t) p[0];
  389. p ++;
  390. //check to see if it matches flow's session id set by ClientHello
  391. if(f->current_session != NULL && f->current_session->session_id_len > 0 && !memcmp(f->current_session->session_id, p, id_len)){
  392. //if it matched, update flow with master secret :D
  393. session *last = sessions->first_session;
  394. int found = 0;
  395. for(int i=0; ((i<sessions->length) && (!found)); i++){
  396. if(!memcmp(last->session_id, f->current_session->session_id, id_len)){
  397. memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
  398. found = 1;
  399. }
  400. last = last->next;
  401. }
  402. if((!found) && (f->current_session->session_ticket_len > 0)){
  403. last = sessions->first_session;
  404. for(int i=0; ((i<sessions->length) && (!found)); i++){
  405. if(!memcmp(last->session_ticket, f->current_session->session_ticket, f->current_session->session_ticket_len)){
  406. memcpy(f->master_secret, last->master_secret, SSL3_MASTER_SECRET_SIZE);
  407. found = 1;
  408. printf("Found new session ticket (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  409. for(int i=0; i< last->session_ticket_len; i++){
  410. printf("%02x ", last->session_ticket[i]);
  411. }
  412. printf("\n");
  413. }
  414. last = last->next;
  415. }
  416. }
  417. } else if (f->current_session != NULL && f->current_session->session_id_len > 0){
  418. //check to see if server's hello extension matches the ticket
  419. save_session_id(f, p);
  420. }
  421. //now check
  422. return 0;
  423. }
  424. /* Called from ClientHello. Checks to see if the session id len is > 0. If so,
  425. * saves sessionid for later verification. Also checks to see if a session
  426. * ticket is included as an extension.
  427. *
  428. * Input:
  429. * f: the tagged flow
  430. * hs: a pointer to the ServerHello message
  431. *
  432. * Output:
  433. * 0 if success, 1 if failed
  434. */
  435. int check_session(flow *f, uint8_t *hs, uint32_t len){
  436. uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
  437. p += 2; //skip version
  438. p += SSL3_RANDOM_SIZE; //skip random
  439. session *new_session = calloc(1, sizeof(session));
  440. new_session->session_id_len = (uint8_t) p[0];
  441. new_session->session_ticket_len = 0;
  442. p ++;
  443. if(new_session->session_id_len > 0){
  444. f->resume_session = 1;
  445. memcpy(new_session->session_id, p, new_session->session_id_len);
  446. new_session->next = NULL;
  447. printf("Requested new session (%x:%d -> %x:%d)\n", f->src_ip.s_addr, f->src_port, f->dst_ip.s_addr, f->dst_port);
  448. f->current_session = new_session;
  449. }
  450. p += new_session->session_id_len;
  451. //check to see if there is a session ticket included
  452. //skip to extensions
  453. uint16_t ciphersuite_len = (p[0] << 8) + p[1];
  454. p += 2 + ciphersuite_len;
  455. uint8_t compress_meth_len = p[0];
  456. p += 1 + compress_meth_len;
  457. //search for SessionTicket TLS extension
  458. if(2 + SSL3_RANDOM_SIZE + new_session->session_id_len + 1 + 2 + ciphersuite_len + 1 + compress_meth_len > len){
  459. //no extension
  460. if(f->current_session == NULL)
  461. free(new_session);
  462. return 0;
  463. }
  464. uint16_t extensions_len = (p[0] << 8) + p[1];
  465. p += 2;
  466. while(extensions_len > 0){
  467. uint16_t type = (p[0] << 8) + p[1];
  468. p += 2;
  469. uint16_t ext_len = (p[0] << 8) + p[1];
  470. p += 2;
  471. if(type == 0x23){
  472. if(ext_len > 0){
  473. f->resume_session = 1;
  474. new_session->session_ticket_len = ext_len;
  475. new_session->session_ticket = calloc(1, ext_len);
  476. memcpy(new_session->session_ticket, p, ext_len);
  477. f->current_session = new_session;
  478. }
  479. }
  480. p += ext_len;
  481. extensions_len -= (4 + ext_len);
  482. }
  483. if(!f->resume_session){
  484. //see if a ticket is incuded
  485. free(new_session);
  486. }
  487. return 0;
  488. }
  489. /* Called from ServerHello during full handshake. Adds the session id to the
  490. * cache for later resumptions
  491. *
  492. * Input:
  493. * f: the tagged flow
  494. * hs: a pointer to the ServerHello message
  495. *
  496. * Output:
  497. * 0 if success, 1 if failed
  498. */
  499. int save_session_id(flow *f, uint8_t *hs){
  500. printf("saving session id\n");
  501. //increment pointer to point to sessionid
  502. uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
  503. p += 2; //skip version
  504. p += SSL3_RANDOM_SIZE; //skip random
  505. session *new_session = calloc(1, sizeof(session));
  506. new_session->session_id_len = (uint8_t) p[0];
  507. if(new_session->session_id_len <= 0){
  508. //if this value is zero, the session is non-resumable or the
  509. //server will issue a NewSessionTicket handshake message
  510. free(new_session);
  511. return 0;
  512. }
  513. p++;
  514. memcpy(new_session->session_id, p, new_session->session_id_len);
  515. new_session->next = NULL;
  516. f->current_session = new_session;
  517. if(sessions->first_session == NULL){
  518. sessions->first_session = new_session;
  519. } else {
  520. session *last = sessions->first_session;
  521. for(int i=0; i< sessions->length; i++){
  522. if(last == NULL)
  523. printf("UH OH: last is null?\n");
  524. last = last->next;
  525. }
  526. last->next = new_session;
  527. }
  528. sessions->length ++;
  529. printf("Saved session id:");
  530. for(int i=0; i< new_session->session_id_len; i++){
  531. printf(" %02x", p[i]);
  532. }
  533. printf("\n");
  534. printf("THERE ARE NOW %d saved sessions\n", sessions->length);
  535. return 0;
  536. }
  537. /* Called from NewSessionTicket. Adds the session ticket to the
  538. * cache for later resumptions
  539. *
  540. * Input:
  541. * f: the tagged flow
  542. * hs: a pointer to the ServerHello message
  543. *
  544. * Output:
  545. * 0 if success, 1 if failed
  546. */
  547. int save_session_ticket(flow *f, uint8_t *hs, uint32_t len){
  548. uint8_t *p = hs + HANDSHAKE_HEADER_LEN;
  549. p += 4; //skip lifetime TODO: add to session struct
  550. session *new_session = calloc(1,sizeof(session));
  551. new_session->session_id_len = 0;
  552. new_session->session_ticket_len = (p[0] << 8) + p[1];
  553. printf("saving ticket of size %d\n", new_session->session_ticket_len);
  554. fflush(stdout);
  555. p += 2;
  556. uint8_t *ticket = calloc(1, new_session->session_ticket_len);
  557. memcpy(ticket, p, new_session->session_ticket_len);
  558. new_session->session_ticket = ticket;
  559. memcpy(new_session->master_secret, f->master_secret, SSL3_MASTER_SECRET_SIZE);
  560. if(sessions->first_session == NULL){
  561. sessions->first_session = new_session;
  562. } else {
  563. session *last = sessions->first_session;
  564. for(int i=0; i< (sessions->length-1); i++){
  565. if(last == NULL){
  566. printf("UH OH: last is null?\n");
  567. fflush(stdout);
  568. }
  569. last = last->next;
  570. }
  571. last->next = new_session;
  572. }
  573. sessions->length ++;
  574. printf("Saved session ticket:");
  575. for(int i=0; i< new_session->session_ticket_len; i++){
  576. printf(" %02x", p[i]);
  577. }
  578. printf("\n");
  579. fflush(stdout);
  580. printf("Saved session master secret:");
  581. for(int i=0; i< SSL3_MASTER_SECRET_SIZE; i++){
  582. printf(" %02x", new_session->master_secret[i]);
  583. }
  584. printf("\n");
  585. fflush(stdout);
  586. printf("THERE ARE NOW %d saved sessions\n", sessions->length);
  587. fflush(stdout);
  588. return 0;
  589. }
  590. /* Adds a packet the flow's packet chain */
  591. int add_packet(flow *f, struct packet_info *info){
  592. packet *new_packet = malloc(sizeof(packet));
  593. if (info->tcp_hdr == NULL){
  594. return 0;
  595. }
  596. new_packet->seq_num = htonl(info->tcp_hdr->sequence_num);
  597. new_packet->len = info->app_data_len;
  598. new_packet->data = info->app_data;
  599. new_packet->data_len = new_packet->len;
  600. new_packet->next = NULL;
  601. new_packet->incoming =
  602. (info->ip_hdr->src.s_addr == f->src_ip.s_addr) ? 0 : 1;
  603. /* Find appropriate place in chain */
  604. if(new_packet->data_len > 0){
  605. packet *previous = NULL;
  606. packet *next = f->packet_chain;
  607. while(next != NULL && (next->seq_num <= new_packet->seq_num)){
  608. previous = next;
  609. next = next->next;
  610. }
  611. //place packet after current
  612. if(previous == NULL){
  613. //goes at the beginning of chain
  614. new_packet->next = f->packet_chain;
  615. f->packet_chain = new_packet;
  616. } else {
  617. new_packet->next = next;
  618. previous->next = new_packet;
  619. }
  620. }
  621. return 0;
  622. }