flow.c 18 KB

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