util.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "util.h"
  4. #include "slitheen.h"
  5. static fragment_table *frag_table;
  6. /**
  7. * This function takes as argument a packet fragment. It checks
  8. * to see if there are other pending packets. If so, it
  9. * looks for matching identification numbers and attempts
  10. * to reconstruct a packet. If the packet reconstruction was
  11. * complete, returns a 1 and the input packet will point to
  12. * the completely reassembled ip packet. If the reconstruction
  13. * requires more fragments, it returns a 0. Returns -1 on error
  14. */
  15. int report_fragment(const u_char *data, u_char *packet, u_int length){
  16. int i, ret;
  17. unsigned char *partial_packet;
  18. const struct ip_header *ip_hdr;
  19. ip_hdr = (struct ip_header*) data;
  20. printf("fragment reported.\n");
  21. /* First check to see if this belongs to a partial packet */
  22. for (i=0; i<frag_table->len; i++){
  23. printf("checking fragments.\n");
  24. fragment *candidate = frag_table->table+i;
  25. if (candidate->id == ip_hdr->id){
  26. /*update fragment in table with new data */
  27. printf("Matches existing packet.\n");
  28. ret = update_fragment(i, data, length);
  29. if(ret == 1){
  30. /* Complete, copy into packet ptr */
  31. printf("Successfully reconstructed packet!\n");
  32. for(i=0; i<ip_hdr->len; i++){
  33. packet[i] = candidate->data[i];
  34. }
  35. }
  36. return ret;
  37. }
  38. }
  39. printf("Creating new partial packet.\n");
  40. /* New packet, create a new table entry */
  41. fragment new_fragment;
  42. new_fragment.id = ip_hdr->id;
  43. new_fragment.ip_len = ip_hdr->len;
  44. partial_packet = malloc(65535);
  45. new_fragment.data = partial_packet;
  46. if(add_fragment(new_fragment))
  47. return -1;
  48. /* Now add data into fragment */
  49. printf("New partial packet created.\n");
  50. return update_fragment(frag_table->len -1, data, length);
  51. }
  52. /**
  53. * Initializes the table of all partialy reconstructed
  54. * packets. Sets the maximum length to defined MAX_FRAGMENTS
  55. */
  56. int init_fragment_table(void) {
  57. frag_table = malloc(sizeof(fragment_table));
  58. frag_table->table = (fragment *) malloc(sizeof(fragment)*MAX_FRAGMENTS);
  59. if( frag_table->table == NULL){
  60. fprintf(stderr, "malloc failed.\n");
  61. return 1;
  62. }
  63. frag_table->len = 0;
  64. frag_table->max_len = MAX_FRAGMENTS;
  65. return 0;
  66. }
  67. /**
  68. * Adds a new fragment to the table of partial packets.
  69. */
  70. int add_fragment(fragment new_fragment){
  71. fragment *ptr;
  72. if(frag_table->len == frag_table->max_len){
  73. //grow_table();
  74. return(1);
  75. }
  76. ptr = frag_table->table + frag_table->len;
  77. *ptr = new_fragment;
  78. frag_table->len ++;
  79. return 0;
  80. }
  81. /**
  82. * Updates an existing partial packet by copying data into
  83. * packet. returns a 1 if reconstruction is complete, 0 if not,
  84. * and -1 on error.
  85. */
  86. int update_fragment(int index, const u_char *data, u_int length){
  87. int i, data_length;
  88. unsigned char *src, *dest;
  89. const struct ip_header *ip_hdr;
  90. u_short offset;
  91. fragment *ptr;
  92. u_int size_ip_hdr;
  93. ip_hdr = (struct ip_header*) data;
  94. offset = ip_hdr->flagsoff & 0x1fff;
  95. size_ip_hdr = IP_HEADER_LEN(ip_hdr);
  96. ptr = (fragment *) frag_table->table+index;
  97. dest = ptr->data + offset;
  98. src = (unsigned char *) data + size_ip_hdr;
  99. /* Copy all but the last 4 bytes to partial packet
  100. * these belong to the ethernet footer */
  101. data_length = length - size_ip_hdr - 4;
  102. for(i=0; i< data_length; i++){
  103. dest[i] = src[i];
  104. }
  105. if(i== ip_hdr->len){
  106. /* return a 1! */
  107. printf("Filled fragment %d from %d to %d.\n", ip_hdr->id, offset, offset + data_length);
  108. return 1;
  109. }
  110. printf("Filled fragment %d from %d to %d.\n", ip_hdr->id, offset, offset+data_length);
  111. printf("Still need %d to %d.\n", offset + data_length, ip_hdr->len);
  112. return 0;
  113. }
  114. void remove_fragment(int index){
  115. /* free ptr to data */
  116. /* remove reference in table to fragment */
  117. int i;
  118. fragment *ptr;
  119. ptr = frag_table->table + index;
  120. for(i=0; i< frag_table->len - index-1; i++){
  121. *ptr = *(ptr + 1);
  122. ptr += i;
  123. }
  124. frag_table->len --;
  125. }