mirror of
https://github.com/adulau/ssldump.git
synced 2024-12-12 11:17:19 +00:00
163 lines
4.6 KiB
C
163 lines
4.6 KiB
C
|
|
#include <pcap.h>
|
|
#include <unistd.h>
|
|
#ifndef __OpenBSD__
|
|
#include <pcap-bpf.h>
|
|
#endif
|
|
#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 sockaddr_storage *i_addr,
|
|
u_short i_port,
|
|
struct sockaddr_storage *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(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(void) {
|
|
#if defined(_POSIX_SYNCHRONIZED_IO) && (_POSIX_SYNCHRONIZED_IO > 0)
|
|
fdatasync(pcap_fd);
|
|
#else
|
|
fsync(pcap_fd);
|
|
#endif
|
|
close(pcap_fd);
|
|
return 0;
|
|
}
|
|
|
|
static int create_pcap_logger(proto_obj **objp,
|
|
struct sockaddr_storage *i_addr,
|
|
u_short i_port,
|
|
struct sockaddr_storage *r_addr,
|
|
u_short r_port,
|
|
struct timeval *base_time) {
|
|
int _status;
|
|
logpkt_ctx_t *pcap_obj = 0;
|
|
struct sockaddr_in src_addr, dst_addr;
|
|
uint32_t timestamp_sec, timestamp_usec;
|
|
|
|
timestamp_sec = base_time->tv_sec;
|
|
timestamp_usec = base_time->tv_usec;
|
|
|
|
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_addr = *i_addr;
|
|
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
|
src_addr.sin_port = htons(i_port);
|
|
|
|
// dst_addr.sin_family = AF_INET;
|
|
// dst_addr.sin_addr = *r_addr;
|
|
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
|
dst_addr.sin_port = htons(r_port);
|
|
|
|
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),
|
|
×tamp_sec,
|
|
×tamp_usec);
|
|
*objp = (proto_obj *)pcap_obj;
|
|
_status = 0;
|
|
abort:
|
|
if(_status) {
|
|
destroy_pcap_logger((proto_obj **)&pcap_obj);
|
|
}
|
|
return _status;
|
|
}
|
|
|
|
static int destroy_pcap_logger(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(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(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};
|