/src/ec_connbuf.c

https://github.com/0x0mar/ettercap · C · 184 lines · 71 code · 36 blank · 77 comment · 5 complexity · c65b29909e8116056cd2e867e36c02bc MD5 · raw file

  1. /*
  2. ettercap -- connection buffer module
  3. Copyright (C) ALoR & NaGA
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include <ec.h>
  17. #include <ec_packet.h>
  18. #include <ec_connbuf.h>
  19. /* mutexes */
  20. #define CONNBUF_INIT_LOCK(x) do{ pthread_mutex_init(&x, NULL); }while(0)
  21. #define CONNBUF_LOCK(x) do{ pthread_mutex_lock(&x); }while(0)
  22. #define CONNBUF_UNLOCK(x) do{ pthread_mutex_unlock(&x); }while(0)
  23. /************************************************/
  24. /*
  25. * initialize the buffer
  26. */
  27. void connbuf_init(struct conn_buf *cb, size_t size)
  28. {
  29. DEBUG_MSG("connbuf_init");
  30. /* init the size */
  31. cb->size = 0;
  32. cb->max_size = size;
  33. /* init the tail */
  34. TAILQ_INIT(&cb->connbuf_tail);
  35. /* init the mutex */
  36. CONNBUF_INIT_LOCK(cb->connbuf_mutex);
  37. }
  38. /*
  39. * add the packet to the conn_buf.
  40. * check if the buffer has reached the max size
  41. * and in case delete the oldest elements to
  42. * fit the predefined size.
  43. *
  44. * the tail has the newer packet in the head and
  45. * older in the tail.
  46. */
  47. int connbuf_add(struct conn_buf *cb, struct packet_object *po)
  48. {
  49. struct conn_pck_list *p;
  50. struct conn_pck_list *e;
  51. SAFE_CALLOC(p, 1, sizeof(struct conn_pck_list));
  52. /*
  53. * we add the sizeof because if the packets have 0 length
  54. * (ack packets) the real memory occupation will overflow
  55. * the max_size
  56. */
  57. p->size = sizeof(struct conn_pck_list) + po->DATA.disp_len;
  58. memcpy(&p->L3_src, &po->L3.src, sizeof(struct ip_addr));
  59. /*
  60. * we cant handle the packet, the buffer
  61. * is too small
  62. */
  63. if (p->size > cb->max_size) {
  64. DEBUG_MSG("connbuf_add: buffer too small %d %d\n", (int)cb->max_size, (int)p->size);
  65. SAFE_FREE(p);
  66. return 0;
  67. }
  68. /* copy the buffer */
  69. SAFE_CALLOC(p->buf, po->DATA.disp_len, sizeof(u_char));
  70. memcpy(p->buf, po->DATA.disp_data, po->DATA.disp_len);
  71. CONNBUF_LOCK(cb->connbuf_mutex);
  72. /*
  73. * check the total size and make adjustment
  74. * if we have to free some packets
  75. */
  76. if (cb->size + p->size > cb->max_size) {
  77. struct conn_pck_list *tmp = NULL;
  78. TAILQ_FOREACH_REVERSE_SAFE(e, &cb->connbuf_tail, next, connbuf_head, tmp) {
  79. /* we have freed enough bytes */
  80. if (cb->size + p->size <= cb->max_size)
  81. break;
  82. /* calculate the new size */
  83. cb->size -= e->size;
  84. /* remove the elemnt */
  85. SAFE_FREE(e->buf);
  86. TAILQ_REMOVE(&cb->connbuf_tail, e, next);
  87. SAFE_FREE(e);
  88. }
  89. }
  90. /* insert the packet in the tail */
  91. TAILQ_INSERT_HEAD(&cb->connbuf_tail, p, next);
  92. /* update the total buffer size */
  93. cb->size += p->size;
  94. CONNBUF_UNLOCK(cb->connbuf_mutex);
  95. return 0;
  96. }
  97. /*
  98. * empty a give buffer.
  99. * all the elements in the list are deleted
  100. */
  101. void connbuf_wipe(struct conn_buf *cb)
  102. {
  103. struct conn_pck_list *e;
  104. DEBUG_MSG("connbuf_wipe");
  105. CONNBUF_LOCK(cb->connbuf_mutex);
  106. /* delete the list */
  107. while ((e = TAILQ_FIRST(&cb->connbuf_tail)) != TAILQ_END(&cb->connbuf_tail)) {
  108. TAILQ_REMOVE(&cb->connbuf_tail, e, next);
  109. SAFE_FREE(e->buf);
  110. SAFE_FREE(e);
  111. }
  112. /* reset the buffer */
  113. cb->size = 0;
  114. TAILQ_INIT(&cb->connbuf_tail);
  115. CONNBUF_UNLOCK(cb->connbuf_mutex);
  116. }
  117. /*
  118. * print the content of a buffer
  119. * you can print only one side of the communication
  120. * by specifying the L3_src address, or NULL to
  121. * print all the packet in order (joined view).
  122. *
  123. * returns the number of printed chars
  124. */
  125. int connbuf_print(struct conn_buf *cb, void (*func)(u_char *, size_t, struct ip_addr *L3_src))
  126. {
  127. struct conn_pck_list *e;
  128. int n = 0;
  129. CONNBUF_LOCK(cb->connbuf_mutex);
  130. /* print the buffer */
  131. TAILQ_FOREACH_REVERSE(e, &cb->connbuf_tail, next, connbuf_head) {
  132. /*
  133. * remember that the size is comprehensive
  134. * of the struct size
  135. */
  136. func(e->buf, e->size - sizeof(struct conn_pck_list), &e->L3_src);
  137. n += e->size - sizeof(struct conn_pck_list);
  138. }
  139. CONNBUF_UNLOCK(cb->connbuf_mutex);
  140. return n;
  141. }
  142. /* EOF */
  143. // vim:ts=3:expandtab