Add handlers for signals USR1 & 2

This commit is contained in:
William Robinet 2023-08-20 12:20:41 +02:00
parent 4f948aaeff
commit 86574eff12
No known key found for this signature in database
GPG key ID: 003FA3DF74C7A949
3 changed files with 86 additions and 20 deletions

View file

@ -75,6 +75,7 @@
#include "record_analyze.h"
#endif
#include "pcap_logger.h"
#include "tcpconn.h"
#ifndef ETHERTYPE_8021Q
#define ETHERTYPE_8021Q 0x8100
@ -85,7 +86,8 @@ static int pcap_if_type = DLT_NULL;
int err_exit PROTO_LIST((char *str, int num));
int usage PROTO_LIST((void));
int print_version PROTO_LIST((void));
void sig_handler PROTO_LIST((int sig));
void sig_handler_quit PROTO_LIST((int sig));
void sig_handler_usr PROTO_LIST((int sig));
void pcap_cb PROTO_LIST((u_char * ptr,
const struct pcap_pkthdr *hdr,
const u_char *data));
@ -102,7 +104,7 @@ logger_mod *logger = NULL;
int err_exit(char *str, int num) {
fprintf(stderr, "ERROR: %s\n", str);
sig_handler(SIGQUIT);
sig_handler_quit(SIGQUIT);
exit(num);
}
@ -136,7 +138,7 @@ n_handler *n;
char *interface_name = 0;
char *file = 0;
char *filter = 0;
void sig_handler(int sig) {
void sig_handler_quit(int sig) {
int freed_conn = 0;
fflush(stdout);
if(logger)
@ -144,8 +146,8 @@ void sig_handler(int sig) {
freed_conn = destroy_all_conn();
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
printf("Cleaned %d remaining connection(s) from connection pool\n",
freed_conn);
fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n",
freed_conn);
network_handler_destroy(mod, &n);
@ -161,6 +163,33 @@ void sig_handler(int sig) {
exit(sig);
}
void sig_handler_usr(int sig) {
int freed_conn = 0;
if(sig == SIGUSR1) {
if(!first_conn) {
fprintf(stderr,
"Received SIGUSR1, connection pool empty, nothing to list.\n");
} else {
fprintf(
stderr,
"Received SIGUSR1, listing currently tracked connection(s) ...\n");
list_all_conn();
}
} else if(sig == SIGUSR2) {
if(!first_conn) {
fprintf(stderr,
"Received SIGUSR2, connection pool empty, nothing to purge.\n");
} else {
fprintf(stderr, "Received SIGUSR2, purging connection pool ...\n");
freed_conn = destroy_all_conn();
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
fprintf(stderr, "Purged %d connection(s) from connection pool\n",
freed_conn);
}
}
}
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
n_handler *n;
int len;
@ -186,9 +215,9 @@ void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
case DLT_EN10MB:
if(len < sizeof(struct ether_header)) {
if(!(NET_print_flags & NET_PRINT_JSON))
printf(
"Frame size too small to contain Ethernet header, skipping "
"...\n");
fprintf(stderr,
"Frame size too small to contain Ethernet header, skipping "
"...\n");
return;
}
@ -291,8 +320,9 @@ void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
packet_cnt = 0;
memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval));
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
printf("%d inactive connection(s) cleaned from connection pool\n",
cleaned_conn);
fprintf(stderr,
"%d inactive connection(s) cleaned from connection pool\n",
cleaned_conn);
} else {
packet_cnt++;
}
@ -330,7 +360,9 @@ int main(int argc, char **argv) {
char errbuf[PCAP_ERRBUF_SIZE];
signal(SIGINT, sig_handler);
signal(SIGINT, sig_handler_quit);
signal(SIGUSR1, sig_handler_usr);
signal(SIGUSR2, sig_handler_usr);
while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) !=
EOF) {
@ -442,6 +474,7 @@ int main(int argc, char **argv) {
err_exit("Aborting", -1);
}
}
fprintf(stderr, "ssldump: listening on %s\n", interface_name);
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
errbuf))) {
fprintf(stderr, "PCAP: %s\n", errbuf);
@ -514,8 +547,8 @@ int main(int argc, char **argv) {
freed_conn = destroy_all_conn();
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
printf("Cleaned %d remaining connection(s) from connection pool\n",
freed_conn);
fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n",
freed_conn);
network_handler_destroy(mod, &n);
pcap_close(p);

View file

@ -47,15 +47,13 @@
#include "network.h"
#include "tcpconn.h"
typedef struct conn_struct_ {
tcp_conn conn;
struct conn_struct_ *next;
struct conn_struct_ *prev;
} conn_struct;
int conn_number = 1;
static conn_struct *first_conn = 0;
conn_struct *first_conn = 0;
char *state_map[] = {
"UNKNOWN", "TCP_STATE_SYN1", "TCP_STATE_SYN2",
"TCP_STATE_ACK", "TCP_STATE_ESTABLISHED", "TCP_STATE_FIN1",
"TCP_STATE_CLOSED"};
extern struct timeval last_packet_seen_time;
extern int conn_ttl;
@ -179,6 +177,30 @@ int clean_old_conn(void) {
return i;
}
void list_all_conn(void) {
conn_struct *conn;
tcp_conn *tcpconn;
struct timeval dt;
long freshness;
fprintf(stderr,
"<connection #> <initiator:port> -> <responder:port> <state> "
"<freshness (in s)>\n");
conn = first_conn;
while(conn) {
tcpconn = &conn->conn;
conn = conn->next;
freshness =
(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt))
? 0
: dt.tv_sec;
fprintf(stderr, "Connection #%d %s:%d -> %s:%d %s %ld\n",
tcpconn->conn_number, tcpconn->i_name, tcpconn->i_port,
tcpconn->r_name, tcpconn->r_port, state_map[tcpconn->state],
freshness);
}
}
int destroy_all_conn(void) {
int i = 0;
while(first_conn) {

View file

@ -62,6 +62,8 @@ typedef struct stream_data_ {
segment *oo_queue;
} stream_data;
extern char *state_map[];
typedef struct tcp_conn_ {
int conn_number;
int state;
@ -92,6 +94,12 @@ typedef struct tcp_conn_ {
struct conn_struct_ *backptr;
} tcp_conn;
typedef struct conn_struct_ {
tcp_conn conn;
struct conn_struct_ *next;
struct conn_struct_ *prev;
} conn_struct;
int tcp_find_conn PROTO_LIST((tcp_conn * *connp,
int *directionp,
struct sockaddr_storage *src_addr,
@ -110,6 +118,9 @@ int free_tcp_segment_queue PROTO_LIST((segment * seg));
int copy_tcp_segment_queue PROTO_LIST((segment * *out, segment *in));
int clean_old_conn(void);
void list_all_conn(void);
int destroy_all_conn(void);
extern conn_struct *first_conn;
#endif