session_partition_declaration.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * ESG parser
  3. *
  4. * Copyright (C) 2006 Stephane Este-Gracias (sestegra@free.fr)
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <libesg/transport/session_partition_declaration.h>
  23. struct esg_session_partition_declaration *esg_session_partition_declaration_decode(uint8_t *buffer, uint32_t size) {
  24. uint32_t pos;
  25. struct esg_session_partition_declaration *partition;
  26. struct esg_session_field *field;
  27. struct esg_session_field *last_field;
  28. uint8_t field_index;
  29. struct esg_session_ip_stream *ip_stream;
  30. struct esg_session_ip_stream *last_ip_stream;
  31. uint8_t ip_stream_index;
  32. uint8_t ip_index;
  33. struct esg_session_ip_stream_field *ip_stream_field;
  34. struct esg_session_ip_stream_field *last_ip_stream_field;
  35. uint8_t *field_buffer;
  36. uint32_t field_length;
  37. union esg_session_ip_stream_field_value *field_value;
  38. if ((buffer == NULL) || (size <= 2)) {
  39. return NULL;
  40. }
  41. pos = 0;
  42. partition = (struct esg_session_partition_declaration *) malloc(sizeof(struct esg_session_partition_declaration));
  43. memset(partition, 0, sizeof(struct esg_session_partition_declaration));
  44. partition->field_list = NULL;
  45. partition->ip_stream_list = NULL;
  46. partition->num_fields = buffer[pos];
  47. pos += 1;
  48. partition->overlapping = (buffer[pos] & 0x80) ? 1 : 0;
  49. pos += 1;
  50. if (size < (pos + 5*(partition->num_fields))) {
  51. esg_session_partition_declaration_free(partition);
  52. return NULL;
  53. }
  54. last_field = NULL;
  55. for (field_index = 0; field_index < partition->num_fields; field_index++) {
  56. field = (struct esg_session_field *) malloc(sizeof(struct esg_session_field));
  57. memset(field, 0, sizeof(struct esg_session_field));
  58. field->_next = NULL;
  59. if (last_field == NULL) {
  60. partition->field_list = field;
  61. } else {
  62. last_field->_next = field;
  63. }
  64. last_field = field;
  65. field->identifier = (buffer[pos] << 8) | buffer[pos+1];
  66. pos += 2;
  67. field->encoding = (buffer[pos] << 8) | buffer[pos+1];
  68. pos += 2;
  69. field->length = buffer[pos];
  70. pos += 1;
  71. }
  72. partition->n_o_ip_streams = buffer[pos];
  73. pos += 1;
  74. partition->ip_version_6 = (buffer[pos] & 0x80) ? 1 : 0;
  75. pos += 1;
  76. last_ip_stream = NULL;
  77. for (ip_stream_index = 0; ip_stream_index < partition->n_o_ip_streams; ip_stream_index++) {
  78. ip_stream = (struct esg_session_ip_stream *) malloc(sizeof(struct esg_session_ip_stream));
  79. memset(ip_stream, 0, sizeof(struct esg_session_ip_stream));
  80. ip_stream->_next = NULL;
  81. if (last_ip_stream == NULL) {
  82. partition->ip_stream_list = ip_stream;
  83. } else {
  84. last_ip_stream->_next = ip_stream;
  85. }
  86. last_ip_stream = ip_stream;
  87. ip_stream->id = buffer[pos];
  88. pos += 1;
  89. if (partition->ip_version_6) {
  90. for (ip_index = 0; ip_index < 16; ip_index++) {
  91. ip_stream->source_ip.ipv6[ip_index] = buffer[pos+ip_index];
  92. ip_stream->destination_ip.ipv6[ip_index] = buffer[pos+16+ip_index];
  93. }
  94. pos += 32;
  95. } else {
  96. for (ip_index = 0; ip_index < 4; ip_index++) {
  97. ip_stream->source_ip.ipv4[ip_index] = buffer[pos+ip_index];
  98. ip_stream->destination_ip.ipv4[ip_index] = buffer[pos+4+ip_index];
  99. }
  100. pos += 8;
  101. }
  102. ip_stream->port = (buffer[pos] << 8) | buffer[pos+1];
  103. pos += 2;
  104. ip_stream->session_id = (buffer[pos] << 8) | buffer[pos+1];
  105. pos += 2;
  106. last_ip_stream_field = NULL;
  107. esg_session_partition_declaration_field_list_for_each(partition, field) {
  108. ip_stream_field = (struct esg_session_ip_stream_field *) malloc(sizeof(struct esg_session_ip_stream_field));
  109. memset(ip_stream_field, 0, sizeof(struct esg_session_ip_stream_field));
  110. ip_stream_field->_next = NULL;
  111. ip_stream_field->start_field_value = NULL;
  112. ip_stream_field->end_field_value = NULL;
  113. if (last_ip_stream_field == NULL) {
  114. ip_stream->field_list = ip_stream_field;
  115. } else {
  116. last_ip_stream_field->_next = ip_stream_field;
  117. }
  118. last_ip_stream_field = ip_stream_field;
  119. field_length = field->length;
  120. if (field->length != 0) {
  121. field_length = field->length;
  122. } else {
  123. pos += vluimsbf8(buffer + pos, size - pos, &field_length);
  124. }
  125. switch (field->encoding) {
  126. case 0x0000: {
  127. if (partition->overlapping == 1) {
  128. field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
  129. memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
  130. ip_stream_field->start_field_value = field_value;
  131. field_buffer = (uint8_t *) malloc(field_length);
  132. memset(field_buffer, 0, field_length);
  133. memcpy(field_buffer, buffer + pos, field_length);
  134. ip_stream_field->start_field_value->string = field_buffer;
  135. pos += field_length;
  136. }
  137. field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
  138. memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
  139. ip_stream_field->end_field_value = field_value;
  140. field_buffer = (uint8_t *) malloc(field_length);
  141. memset(field_buffer, 0, field_length);
  142. memcpy(field_buffer, buffer + pos, field_length);
  143. ip_stream_field->end_field_value->string = field_buffer;
  144. pos += field_length;
  145. break;
  146. }
  147. case 0x0101: {
  148. if (partition->overlapping == 1) {
  149. field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
  150. memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
  151. ip_stream_field->start_field_value = field_value;
  152. ip_stream_field->start_field_value->unsigned_short = (buffer[pos] << 8) | buffer[pos+1];
  153. pos += field_length;
  154. }
  155. field_value = (union esg_session_ip_stream_field_value *) malloc(sizeof(union esg_session_ip_stream_field_value));
  156. memset(field_value, 0, sizeof(union esg_session_ip_stream_field_value));
  157. ip_stream_field->end_field_value = field_value;
  158. ip_stream_field->end_field_value->unsigned_short = (buffer[pos] << 8) | buffer[pos+1];
  159. pos += field_length;
  160. break;
  161. }
  162. default: {
  163. esg_session_partition_declaration_free(partition);
  164. return NULL;
  165. }
  166. }
  167. }
  168. }
  169. return partition;
  170. }
  171. void esg_session_partition_declaration_free(struct esg_session_partition_declaration *partition) {
  172. struct esg_session_field *field;
  173. struct esg_session_field *next_field;
  174. struct esg_session_ip_stream *ip_stream;
  175. struct esg_session_ip_stream *next_ip_stream;
  176. struct esg_session_ip_stream_field *ip_stream_field;
  177. struct esg_session_ip_stream_field *next_ip_stream_field;
  178. if (partition == NULL) {
  179. return;
  180. }
  181. for(ip_stream = partition->ip_stream_list; ip_stream; ip_stream = next_ip_stream) {
  182. next_ip_stream = ip_stream->_next;
  183. field = partition->field_list;
  184. for(ip_stream_field = next_ip_stream->field_list; ip_stream_field; ip_stream_field = next_ip_stream_field) {
  185. next_ip_stream_field = ip_stream_field->_next;
  186. switch (field->encoding) {
  187. case 0x0000: {
  188. if (ip_stream_field->start_field_value != NULL) {
  189. free(ip_stream_field->start_field_value->string);
  190. }
  191. free(ip_stream_field->end_field_value->string);
  192. break;
  193. }
  194. case 0x0101: {
  195. // Nothing to free
  196. break;
  197. }
  198. }
  199. free(ip_stream_field);
  200. field = field->_next;
  201. }
  202. free(ip_stream);
  203. }
  204. for(field = partition->field_list; field; field = next_field) {
  205. next_field = field->_next;
  206. free(field);
  207. }
  208. free(partition);
  209. }