mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-24 02:17:05 +00:00
Merge pull request #86 from wllm-rbnt/sigs
Connection tracker live list & purge
This commit is contained in:
commit
6c1aa99da8
7 changed files with 110 additions and 21 deletions
|
@ -75,6 +75,7 @@
|
||||||
#include "record_analyze.h"
|
#include "record_analyze.h"
|
||||||
#endif
|
#endif
|
||||||
#include "pcap_logger.h"
|
#include "pcap_logger.h"
|
||||||
|
#include "tcpconn.h"
|
||||||
|
|
||||||
#ifndef ETHERTYPE_8021Q
|
#ifndef ETHERTYPE_8021Q
|
||||||
#define ETHERTYPE_8021Q 0x8100
|
#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 err_exit PROTO_LIST((char *str, int num));
|
||||||
int usage PROTO_LIST((void));
|
int usage PROTO_LIST((void));
|
||||||
int print_version 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,
|
void pcap_cb PROTO_LIST((u_char * ptr,
|
||||||
const struct pcap_pkthdr *hdr,
|
const struct pcap_pkthdr *hdr,
|
||||||
const u_char *data));
|
const u_char *data));
|
||||||
|
@ -102,7 +104,7 @@ logger_mod *logger = NULL;
|
||||||
|
|
||||||
int err_exit(char *str, int num) {
|
int err_exit(char *str, int num) {
|
||||||
fprintf(stderr, "ERROR: %s\n", str);
|
fprintf(stderr, "ERROR: %s\n", str);
|
||||||
sig_handler(SIGQUIT);
|
sig_handler_quit(SIGQUIT);
|
||||||
exit(num);
|
exit(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +138,7 @@ n_handler *n;
|
||||||
char *interface_name = 0;
|
char *interface_name = 0;
|
||||||
char *file = 0;
|
char *file = 0;
|
||||||
char *filter = 0;
|
char *filter = 0;
|
||||||
void sig_handler(int sig) {
|
void sig_handler_quit(int sig) {
|
||||||
int freed_conn = 0;
|
int freed_conn = 0;
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if(logger)
|
if(logger)
|
||||||
|
@ -144,8 +146,8 @@ void sig_handler(int sig) {
|
||||||
|
|
||||||
freed_conn = destroy_all_conn();
|
freed_conn = destroy_all_conn();
|
||||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n",
|
||||||
freed_conn);
|
freed_conn);
|
||||||
|
|
||||||
network_handler_destroy(mod, &n);
|
network_handler_destroy(mod, &n);
|
||||||
|
|
||||||
|
@ -161,6 +163,33 @@ void sig_handler(int sig) {
|
||||||
exit(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) {
|
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||||
n_handler *n;
|
n_handler *n;
|
||||||
int len;
|
int len;
|
||||||
|
@ -186,9 +215,9 @@ void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||||
case DLT_EN10MB:
|
case DLT_EN10MB:
|
||||||
if(len < sizeof(struct ether_header)) {
|
if(len < sizeof(struct ether_header)) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf(
|
fprintf(stderr,
|
||||||
"Frame size too small to contain Ethernet header, skipping "
|
"Frame size too small to contain Ethernet header, skipping "
|
||||||
"...\n");
|
"...\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,8 +320,9 @@ void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||||
packet_cnt = 0;
|
packet_cnt = 0;
|
||||||
memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval));
|
memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval));
|
||||||
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("%d inactive connection(s) cleaned from connection pool\n",
|
fprintf(stderr,
|
||||||
cleaned_conn);
|
"%d inactive connection(s) cleaned from connection pool\n",
|
||||||
|
cleaned_conn);
|
||||||
} else {
|
} else {
|
||||||
packet_cnt++;
|
packet_cnt++;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +360,9 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
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")) !=
|
while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) !=
|
||||||
EOF) {
|
EOF) {
|
||||||
|
@ -442,6 +474,7 @@ int main(int argc, char **argv) {
|
||||||
err_exit("Aborting", -1);
|
err_exit("Aborting", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "ssldump: listening on %s\n", interface_name);
|
||||||
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
|
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
|
||||||
errbuf))) {
|
errbuf))) {
|
||||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
|
@ -514,8 +547,8 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
freed_conn = destroy_all_conn();
|
freed_conn = destroy_all_conn();
|
||||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
fprintf(stderr, "Cleaned %d remaining connection(s) from connection pool\n",
|
||||||
freed_conn);
|
freed_conn);
|
||||||
|
|
||||||
network_handler_destroy(mod, &n);
|
network_handler_destroy(mod, &n);
|
||||||
pcap_close(p);
|
pcap_close(p);
|
||||||
|
|
|
@ -47,15 +47,13 @@
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "tcpconn.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;
|
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 struct timeval last_packet_seen_time;
|
||||||
extern int conn_ttl;
|
extern int conn_ttl;
|
||||||
|
@ -179,6 +177,30 @@ int clean_old_conn(void) {
|
||||||
return i;
|
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 destroy_all_conn(void) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(first_conn) {
|
while(first_conn) {
|
||||||
|
|
|
@ -62,6 +62,8 @@ typedef struct stream_data_ {
|
||||||
segment *oo_queue;
|
segment *oo_queue;
|
||||||
} stream_data;
|
} stream_data;
|
||||||
|
|
||||||
|
extern char *state_map[];
|
||||||
|
|
||||||
typedef struct tcp_conn_ {
|
typedef struct tcp_conn_ {
|
||||||
int conn_number;
|
int conn_number;
|
||||||
int state;
|
int state;
|
||||||
|
@ -92,6 +94,12 @@ typedef struct tcp_conn_ {
|
||||||
struct conn_struct_ *backptr;
|
struct conn_struct_ *backptr;
|
||||||
} tcp_conn;
|
} 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 tcp_find_conn PROTO_LIST((tcp_conn * *connp,
|
||||||
int *directionp,
|
int *directionp,
|
||||||
struct sockaddr_storage *src_addr,
|
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 copy_tcp_segment_queue PROTO_LIST((segment * *out, segment *in));
|
||||||
|
|
||||||
int clean_old_conn(void);
|
int clean_old_conn(void);
|
||||||
|
void list_all_conn(void);
|
||||||
int destroy_all_conn(void);
|
int destroy_all_conn(void);
|
||||||
|
|
||||||
|
extern conn_struct *first_conn;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
3
build.sh
Executable file
3
build.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
rm -Rf build && cmake -B build -G Ninja && ninja -C build
|
|
@ -125,7 +125,7 @@ static int decode_ContentType_application_data(ssl_obj *ssl,
|
||||||
|
|
||||||
if(NET_print_flags & NET_PRINT_JSON) {
|
if(NET_print_flags & NET_PRINT_JSON) {
|
||||||
json_object_object_add(jobj, "msg_data",
|
json_object_object_add(jobj, "msg_data",
|
||||||
json_object_new_string_len((char *) d.data, d.len));
|
json_object_new_string_len((char *)d.data, d.len));
|
||||||
} else
|
} else
|
||||||
P_(P_AD) { print_data(ssl, &d); }
|
P_(P_AD) { print_data(ssl, &d); }
|
||||||
else {
|
else {
|
||||||
|
|
10
ssldump.1
10
ssldump.1
|
@ -534,6 +534,16 @@ and
|
||||||
.B \-p
|
.B \-p
|
||||||
flags.
|
flags.
|
||||||
.LP
|
.LP
|
||||||
|
.SH SIGNALS
|
||||||
|
.LP
|
||||||
|
When it receives SIGUSR1,
|
||||||
|
.B ssldump
|
||||||
|
prints the list of currently tracked connection on stderr.
|
||||||
|
.LP
|
||||||
|
With SIGUSR2,
|
||||||
|
.B ssldump
|
||||||
|
purges its internal connection tracking data structures.
|
||||||
|
.LP
|
||||||
.SH DECRYPTION
|
.SH DECRYPTION
|
||||||
.LP
|
.LP
|
||||||
\fIssldump\fP can decrypt traffic between two hosts if the following two
|
\fIssldump\fP can decrypt traffic between two hosts if the following two
|
||||||
|
|
10
ssldump.md
10
ssldump.md
|
@ -371,6 +371,16 @@ and
|
||||||
**-p**
|
**-p**
|
||||||
flags.
|
flags.
|
||||||
|
|
||||||
|
<a name="signals"></a>
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
|
||||||
|
When it receives SIGUSR1, _ssldump_ prints the list of currently tracked
|
||||||
|
connection on stderr.
|
||||||
|
|
||||||
|
With SIGUSR2, _ssldump_ purges its internal connection tracking data
|
||||||
|
structures.
|
||||||
|
|
||||||
|
|
||||||
<a name="decryption"></a>
|
<a name="decryption"></a>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue