/*
    ettercap -- data comunication buffer between illithid and ettercap

    Copyright (C) 2003  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>

    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 "include/ec_main.h"

typedef struct {
    u_int32 len;    
    u_int32 r_off;
    u_int32 w_off;
    u_int32 wrap_f;
} CBuff_header;

// protos...

int ConnBuffer_Get(char *buf, void *data, int size);
int ConnBuffer_Put(char *buf, void *data, int size);
char *ConnBuffer_Create(int len);
void ConnBuffer_Destroy(char *buf);
void ConnBuffer_Flush(char *buf);

// ----------------------------

char *ConnBuffer_Create(int len)
{
   char *buf;
   CBuff_header *header;
   
   buf = (char *) calloc(len + sizeof(CBuff_header), sizeof(char));
   header = (CBuff_header *)buf;
   header->len = len;

   DEBUG_MSG("ConnBuffer_Create -- len %d", len);

   return buf;
}


void ConnBuffer_Flush(char *buf)
{
   CBuff_header *header;
      
   if (!buf) return;
   header = (CBuff_header *)buf;
   
   if (header->wrap_f)
       header->r_off = (header->w_off + sizeof(SNIFFED_DATA))%header->len;
   else
       header->r_off = 0;
}


void ConnBuffer_Destroy(char *buf)
{
    if (buf) free(buf);
}


int ConnBuffer_Get(char *buf, void *to_read, int size)
{
   unsigned long R_Offset, W_Offset;
   char *data;
   CBuff_header *header;

   if (!buf) return -1;

   header = (CBuff_header *) buf;
   R_Offset = header->r_off;
   
   W_Offset = header->w_off;
   
   data     = buf + sizeof(CBuff_header);
   
   if (R_Offset==W_Offset) return 0;

       memcpy((char *)to_read, data+R_Offset, size);

   header->r_off=(R_Offset+size)%header->len;

   return size;
}


int ConnBuffer_Put(char *buf, void *to_write, int size)
{
   unsigned long R_Offset, W_Offset;
   char *data;
   CBuff_header *header;

   if (!buf) return -1;

   header = (CBuff_header *) buf;
   R_Offset = header->r_off;
   W_Offset = header->w_off;
   data     = buf + sizeof(CBuff_header);

   if ( -header->len + W_Offset + size == 0 ) header->wrap_f = 1;

   memcpy(data+W_Offset, (char *)to_write, size);
   
   header->w_off = (W_Offset+size)%header->len;

   return 0;

}


/* EOF */


// vim:ts=3:expandtab

