ssldump/pcap/pcap_logger.c

150 lines
3.8 KiB
C
Raw Permalink Normal View History

#include <pcap.h>
#include <unistd.h>
#include <pcap-bpf.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "network.h"
#include "proto_mod.h"
#include "debug.h"
#include "pcap_logger.h"
#include "logpkt.h"
#define DFLT_FILEMODE 0666
static int init_pcap_logger PROTO_LIST((void * data));
static int deinit_pcap_logger PROTO_LIST(());
static int create_pcap_logger PROTO_LIST((proto_obj **objp, struct in_addr *i_addr,
u_short i_port,struct in_addr *r_addr, u_short r_port, struct timeval *base_time));
static int destroy_pcap_logger PROTO_LIST((proto_obj **objp));
static int data_pcap_logger PROTO_LIST((proto_obj *_obj, unsigned char *data,unsigned int len, int dir));
static int close_pcap_logger PROTO_LIST((proto_obj *_obj, unsigned char *data,unsigned int len, int dir));
int pcap_fd = -1;
static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x11, 0x11, 0x11};
static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x22, 0x22, 0x22};
static int init_pcap_logger(data)
void *data;
{
char *pcap_outfile = (char *) data;
pcap_fd = open(pcap_outfile, O_RDWR|O_CREAT, DFLT_FILEMODE);
if (pcap_fd == -1) {
//printf("Failed to open pcap '%s' for writing\n", pcap_outfile);
return -1;
}
if (logpkt_pcap_open_fd(pcap_fd) == -1) {
//printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile);
close(pcap_fd);
pcap_fd = -1;
return -1;
}
return 0;
}
static int deinit_pcap_logger()
{
fdatasync(pcap_fd);
close(pcap_fd);
return 0;
}
static int create_pcap_logger(proto_obj **objp, struct in_addr *i_addr, u_short i_port, struct in_addr *r_addr, u_short r_port, struct timeval *base_time)
{
int r,_status;
logpkt_ctx_t *pcap_obj=0;
struct sockaddr_in src_addr, dst_addr;
if(!(pcap_obj=(logpkt_ctx_t *)calloc(1,sizeof(logpkt_ctx_t))))
ABORT(R_NO_MEMORY);
src_addr.sin_family = AF_INET;
src_addr.sin_port = htons(i_port);
src_addr.sin_addr = *i_addr;
dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(r_port);
dst_addr.sin_addr = *r_addr;
logpkt_ctx_init(pcap_obj,NULL,0,content_pcap_src_ether, content_pcap_dst_ether,
(const struct sockaddr*)&src_addr, sizeof(src_addr),
(const struct sockaddr*)&dst_addr, sizeof(dst_addr));
*objp=(proto_obj *)pcap_obj;
_status=0;
abort:
if(_status){
destroy_pcap_logger((proto_obj **)&pcap_obj);
}
return(_status);
}
static int destroy_pcap_logger(objp)
proto_obj **objp;
{
logpkt_ctx_t *pcap_obj;
if(!objp || !*objp)
return(0);
pcap_obj=(logpkt_ctx_t *)*objp;
free(pcap_obj);
*objp=0;
return(0);
}
static int data_pcap_logger(_obj,data,len,dir)
proto_obj *_obj;
unsigned char *data;
unsigned int len;
int dir;
{
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
int direction;
int status;
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
else direction = LOGPKT_RESPONSE;
status = logpkt_write_payload(pcap_obj,pcap_fd,direction,data,len);
return status;
}
int close_pcap_logger(_obj,data,len,dir)
proto_obj *_obj;
unsigned char *data;
unsigned int len;
int dir;
{
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
int direction;
int status;
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
else direction = LOGPKT_RESPONSE;
status = logpkt_write_close(pcap_obj, pcap_fd, direction);
return status;
}
static struct logger_mod_vtbl_ pcap_vtbl ={
init_pcap_logger,
deinit_pcap_logger,
create_pcap_logger,
destroy_pcap_logger,
data_pcap_logger,
close_pcap_logger,
};
struct logger_mod_ pcap_mod = {
"PCAP",
&pcap_vtbl
};