/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe 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.                                       *
*                                                                             *
*   Nprobe 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 Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/


#ifndef _WREAD_UTIL_H_
#define _WREAD_UTIL_H_


extern char *prog;
extern char errbuf[100];

#if 0
/*
 * Holds info on current rep file record 
 */
struct rec_info 
{
  long indx;			/* file index of recored */
  unsigned short len;
  unsigned char type;		/* record type */
};
#endif


#define GET_INT(file, addr, type)      \
MACRO_BEGIN                          \
  if (fread((addr), sizeof(type), 1, (file)) != 1) \
    ERROR("fread - GET_INT");        \
MACRO_END

#define GET_STRUCT(file, addr, type)      \
MACRO_BEGIN                          \
  if (fread((addr), sizeof(type), 1, (file)) != 1) \
    {                                             \
       if (feof(file))     \
         ERROR("fread - GET_STRUCT " #type " EOF reached"); \
       else if (ferror(file))                 \
         ERROR("fread - GET_STRUCT " #type " file error"); \
       else                               \
         ERROR("fread - GET_STRUCT " #type);        \
    }                                    \
MACRO_END

#define GET_STRUCT_SZ(file, addr, size, type)      \
MACRO_BEGIN                          \
  if (fread((addr), size, 1, (file)) != 1) \
    {                                             \
       if (feof(file))     \
         ERROR("fread - GET_STRUCT " #type " EOF reached"); \
       else if (ferror(file))                 \
         ERROR("fread - GET_STRUCT " #type " file error"); \
       else                               \
         ERROR("fread - GET_STRUCT " #type);        \
    }                                    \
MACRO_END

#define GET_STRING(file, addr)      \
MACRO_BEGIN                          \
  char *cp = (addr);                \
  do                               \
    {                         \
      *cp = fgetc(file);   \
    } while (*cp++ != '\0');               \
MACRO_END

#define GET_STRING_ADVANCE(file, addr, cp)      \
MACRO_BEGIN                          \
  (cp) = (addr);                \
  do                               \
    {                         \
      *(cp) = fgetc(file);   \
    } while (*(cp)++ != '\0');               \
MACRO_END

#define GET_MEM(file, addr, len)      \
MACRO_BEGIN                          \
  if (fread((addr), (len), 1, (file)) != 1) \
    ERROR("fread - GET_MEM");        \
MACRO_END


/*
 * Control allocation of HTTP transaction chain etc.
 */

#define NO_TRANS 0		/* get TCP connection data only */
#define GET_TRANS 1		/* get transaction chain too */

#define TRANS_ALLOC_ON_FLY 0	/* one set per tcp_conn */
#define TRANS_PREALLOC 1	/* one set does for all */

#define NO_IMGBUFS 0
#define PROVIDE_IMGBUFS 1

/*
 * Control allocation of UDP service data  etc.
 */
#undef NO_DATA
#define NO_DATA 0		/* get UDP connection data only */
#define GET_DATA 1		/* get service data too */

#define DATA_ALLOC_ON_FLY 0	/* allocate memory as needed */
#define DATA_PREALLOC 1	        /* memory pre-allocated */

/*
 * Key types for report filtering
 */
#define KEY_REC 0x1
#define KEY_CONN_ID 0x2
#define KEY_SERV_ADDR 0x4
#define KEY_CLI_ADDR 0x8

void wr_error(char *msg);
void read_conn(struct np_file *file, tcp_conn_t *tconnp, int allocflag, int get_trans);


static int total_for_this_file = 0; 

#if 0
#define malloc(x)    \
({  total_for_this_file += x; printf("malloc %d at %s %d total for this file %d\n", (x), __FILE__, __LINE__, total_for_this_file); \
    malloc(x);  \
  }) 
#endif



extern void wr_error(char *msg);

extern long long start_us;

int _file_open(struct np_file *file);
int _file_reset(struct np_file *file);
int _printfile(struct np_file *file, int allocflag, unsigned char type, 
	       int keytype, unsigned int key, int quietflag);
int filter_file(int type, char *ofile);

int _indx(struct np_file *file);
long _indx_rec(struct np_file *file);
int _rewind(struct np_file *file);
int _seek_rec(struct np_file *file, unsigned int recno);
long _offset(struct np_file *file);
int _seek(struct np_file *file, long off);
int _next_rec(struct np_file *file, unsigned char rec_type);
int _advance(struct np_file *file);
int _is_rectype(int type, int wanted);
int _read_rec(struct np_file *file, unsigned char type, void *data, int allocflag, int get_arg);
int _report_rec(void *data, unsigned char type, int indx);

int _dealloc_tcp_conn(tcp_conn_t *tconnp);
int _tcp_alloc_hdrbuffs(tcp_hdrs_t *hdrs, int nbufs);
int _tcp_dealloc_hdrbuffs(tcp_hdrs_t *hdrs);
int _read_tcp_conn(struct np_file *file, tcp_conn_t *tconnp, int allocflag, int get_trans);
int _read_tcp_open(struct np_file *file, tcp_open_t *flow);
int _read_tcp_hdrs(struct np_file *file, struct tcp_hdrs *drec, int allocflag);
int _dealloc_udp_conn(udp_conn_t *uconnp);
int _read_udp_conn(struct np_file *file, udp_conn_t *uconnp, int allocflag, int get_data);
int _read_ns_rec(struct np_file *file, ns_fullrec_t *np, int allocflag);
int _dealloc_ns_rec(ns_fullrec_t *np);
int _read_icmp(struct np_file *file, struct icmp_rec *ipp);

char *_links_buf_alloc(unsigned int len);

int _http_alloc_trans(tcp_conn_t *tconnp, int ntrans, int alloc_imgbuf);
int _http_get_transchain(struct np_file *file, tcp_conn_t *tconnp);
int _http_dealloc_trans(tcp_conn_t *tconnp);
char *_http_img_chars_buf_alloc(unsigned int len);
int _http_read_trans(http_trans_t *tp, struct np_file *file, int client_seen, int server_seen, unsigned int addit_trans_fields, int allocflag);
int _http_get_nurls(char *chars, int len);
int _http_get_ndist_urls(char *chars, int len);
int _http_print_like_squidlog(http_trans_t *trans, tcp_conn_t *tconn, int code);
int _read_buf_alloc_fail(struct np_file *file, sk_buff_alloc_fail_rec_t *fail_rec);
int _read_period_report(struct np_file *file, period_report_t *prep, 
		    np_rusage_t *rup);
int _read_rusage(struct np_file *file, np_rusage_t *ru);
int _read_interesting(struct np_file *file, flow_inner_t *flowp, int *wayp, char *s);
int _read_wrapper(struct np_file *file, wrapper_record_t *wrapper);
int _read_procstats(struct np_file *file, procstat_rec_t *prp);

unsigned char _parse_type(char *ts);
int _http_get_nurls(char *chars, int len);
int _http_get_ndist_urls(char *chars, int buflen);
int _copy_rec(struct np_file *file, long int off, int fd, int n);
void _write_pseudocounters(int fd, int reci, counters_t *counters);


#endif /* _WREAD_UTIL_H_ */





/*
 * end wread.h 
 */
