diff --git a/base/pcap-snoop.c.in b/base/pcap-snoop.c.in index 06ea0d8..6f2d75e 100644 --- a/base/pcap-snoop.c.in +++ b/base/pcap-snoop.c.in @@ -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); diff --git a/base/tcpconn.c b/base/tcpconn.c index 408d980..36b532c 100644 --- a/base/tcpconn.c +++ b/base/tcpconn.c @@ -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, + " -> " + "\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) { diff --git a/base/tcpconn.h b/base/tcpconn.h index fc5ae22..c9eda10 100644 --- a/base/tcpconn.h +++ b/base/tcpconn.h @@ -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