/src/ec_connbuf.c
https://github.com/0x0mar/ettercap · C · 184 lines · 71 code · 36 blank · 77 comment · 5 complexity · c65b29909e8116056cd2e867e36c02bc MD5 · raw file
- /*
- ettercap -- connection buffer module
- Copyright (C) ALoR & NaGA
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- #include <ec.h>
- #include <ec_packet.h>
- #include <ec_connbuf.h>
- /* mutexes */
- #define CONNBUF_INIT_LOCK(x) do{ pthread_mutex_init(&x, NULL); }while(0)
- #define CONNBUF_LOCK(x) do{ pthread_mutex_lock(&x); }while(0)
- #define CONNBUF_UNLOCK(x) do{ pthread_mutex_unlock(&x); }while(0)
- /************************************************/
- /*
- * initialize the buffer
- */
- void connbuf_init(struct conn_buf *cb, size_t size)
- {
- DEBUG_MSG("connbuf_init");
-
- /* init the size */
- cb->size = 0;
- cb->max_size = size;
- /* init the tail */
- TAILQ_INIT(&cb->connbuf_tail);
- /* init the mutex */
- CONNBUF_INIT_LOCK(cb->connbuf_mutex);
- }
- /*
- * add the packet to the conn_buf.
- * check if the buffer has reached the max size
- * and in case delete the oldest elements to
- * fit the predefined size.
- *
- * the tail has the newer packet in the head and
- * older in the tail.
- */
- int connbuf_add(struct conn_buf *cb, struct packet_object *po)
- {
- struct conn_pck_list *p;
- struct conn_pck_list *e;
- SAFE_CALLOC(p, 1, sizeof(struct conn_pck_list));
-
- /*
- * we add the sizeof because if the packets have 0 length
- * (ack packets) the real memory occupation will overflow
- * the max_size
- */
- p->size = sizeof(struct conn_pck_list) + po->DATA.disp_len;
-
- memcpy(&p->L3_src, &po->L3.src, sizeof(struct ip_addr));
- /*
- * we cant handle the packet, the buffer
- * is too small
- */
- if (p->size > cb->max_size) {
- DEBUG_MSG("connbuf_add: buffer too small %d %d\n", (int)cb->max_size, (int)p->size);
- SAFE_FREE(p);
- return 0;
- }
-
- /* copy the buffer */
- SAFE_CALLOC(p->buf, po->DATA.disp_len, sizeof(u_char));
-
- memcpy(p->buf, po->DATA.disp_data, po->DATA.disp_len);
- CONNBUF_LOCK(cb->connbuf_mutex);
-
- /*
- * check the total size and make adjustment
- * if we have to free some packets
- */
- if (cb->size + p->size > cb->max_size) {
- struct conn_pck_list *tmp = NULL;
-
- TAILQ_FOREACH_REVERSE_SAFE(e, &cb->connbuf_tail, next, connbuf_head, tmp) {
-
- /* we have freed enough bytes */
- if (cb->size + p->size <= cb->max_size)
- break;
-
- /* calculate the new size */
- cb->size -= e->size;
- /* remove the elemnt */
- SAFE_FREE(e->buf);
- TAILQ_REMOVE(&cb->connbuf_tail, e, next);
- SAFE_FREE(e);
- }
- }
-
- /* insert the packet in the tail */
- TAILQ_INSERT_HEAD(&cb->connbuf_tail, p, next);
-
- /* update the total buffer size */
- cb->size += p->size;
- CONNBUF_UNLOCK(cb->connbuf_mutex);
- return 0;
- }
- /*
- * empty a give buffer.
- * all the elements in the list are deleted
- */
- void connbuf_wipe(struct conn_buf *cb)
- {
- struct conn_pck_list *e;
- DEBUG_MSG("connbuf_wipe");
-
- CONNBUF_LOCK(cb->connbuf_mutex);
-
- /* delete the list */
- while ((e = TAILQ_FIRST(&cb->connbuf_tail)) != TAILQ_END(&cb->connbuf_tail)) {
- TAILQ_REMOVE(&cb->connbuf_tail, e, next);
- SAFE_FREE(e->buf);
- SAFE_FREE(e);
- }
- /* reset the buffer */
- cb->size = 0;
- TAILQ_INIT(&cb->connbuf_tail);
-
- CONNBUF_UNLOCK(cb->connbuf_mutex);
- }
- /*
- * print the content of a buffer
- * you can print only one side of the communication
- * by specifying the L3_src address, or NULL to
- * print all the packet in order (joined view).
- *
- * returns the number of printed chars
- */
- int connbuf_print(struct conn_buf *cb, void (*func)(u_char *, size_t, struct ip_addr *L3_src))
- {
- struct conn_pck_list *e;
- int n = 0;
-
- CONNBUF_LOCK(cb->connbuf_mutex);
-
- /* print the buffer */
- TAILQ_FOREACH_REVERSE(e, &cb->connbuf_tail, next, connbuf_head) {
- /*
- * remember that the size is comprehensive
- * of the struct size
- */
- func(e->buf, e->size - sizeof(struct conn_pck_list), &e->L3_src);
- n += e->size - sizeof(struct conn_pck_list);
- }
-
- CONNBUF_UNLOCK(cb->connbuf_mutex);
-
- return n;
- }
- /* EOF */
- // vim:ts=3:expandtab