mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-24 18:37:05 +00:00
Add support for IPv6 traffic dump
This commit is contained in:
parent
04deb915a3
commit
6686cedfdd
10 changed files with 192 additions and 105 deletions
137
base/network.c
137
base/network.c
|
@ -107,16 +107,18 @@ int network_handler_destroy(mod,handlerp)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int network_process_packet(handler,timestamp,data,length)
|
int network_process_packet(handler,timestamp,data,length,af)
|
||||||
n_handler *handler;
|
n_handler *handler;
|
||||||
struct timeval *timestamp;
|
struct timeval *timestamp;
|
||||||
UCHAR *data;
|
UCHAR *data;
|
||||||
int length;
|
int length;
|
||||||
|
int af;
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int hlen;
|
int hlen;
|
||||||
packet p;
|
packet p;
|
||||||
u_short off;
|
u_short off;
|
||||||
|
int proto;
|
||||||
|
|
||||||
/*We can pretty much ignore all the options*/
|
/*We can pretty much ignore all the options*/
|
||||||
memcpy(&p.ts,timestamp,sizeof(struct timeval));
|
memcpy(&p.ts,timestamp,sizeof(struct timeval));
|
||||||
|
@ -124,7 +126,7 @@ int network_process_packet(handler,timestamp,data,length)
|
||||||
p._len=length;
|
p._len=length;
|
||||||
p.data=data;
|
p.data=data;
|
||||||
p.len=length;
|
p.len=length;
|
||||||
p.ip=(struct ip *)data;
|
p.af=af;
|
||||||
|
|
||||||
if(p.len < 20) {
|
if(p.len < 20) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
|
@ -132,37 +134,77 @@ int network_process_packet(handler,timestamp,data,length)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Handle, or rather mishandle, fragmentation*/
|
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||||
off=ntohs(p.ip->ip_off);
|
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
if((off & 0x1fff) || /*Later fragment*/
|
if(af == AF_INET) {
|
||||||
(off & 0x2000)){ /*More fragments*/
|
p.l3_hdr.ip=(struct ip *)data;
|
||||||
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src, sizeof(struct in_addr));
|
||||||
return(0);
|
p.i_addr.so_in.sin_family = AF_INET;
|
||||||
|
memcpy(&p.r_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_dst, sizeof(struct in_addr));
|
||||||
|
p.r_addr.so_in.sin_family = AF_INET;
|
||||||
|
|
||||||
|
/*Handle, or rather mishandle, fragmentation*/
|
||||||
|
off=ntohs(p.l3_hdr.ip->ip_off);
|
||||||
|
|
||||||
|
if((off & 0x1fff) || /*Later fragment*/
|
||||||
|
(off & 0x2000)){ /*More fragments*/
|
||||||
|
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
hlen=p.l3_hdr.ip->ip_hl * 4;
|
||||||
|
p.data += hlen;
|
||||||
|
p.len = ntohs(p.l3_hdr.ip->ip_len);
|
||||||
|
|
||||||
|
if(p.len > length) {
|
||||||
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
|
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.len == 0) {
|
||||||
|
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
||||||
|
p.len = p._len;
|
||||||
|
}
|
||||||
|
p.len -= hlen;
|
||||||
|
|
||||||
|
proto = p.l3_hdr.ip->ip_p;
|
||||||
|
} else {
|
||||||
|
p.l3_hdr.ip6=(struct ip6_hdr *)data;
|
||||||
|
memcpy(&p.i_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_src, sizeof(struct in6_addr));
|
||||||
|
p.i_addr.so_in6.sin6_family = AF_INET6;
|
||||||
|
memcpy(&p.r_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_dst, sizeof(struct in6_addr));
|
||||||
|
p.r_addr.so_in6.sin6_family = AF_INET6;
|
||||||
|
// Skip packets with header extensions
|
||||||
|
if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hlen=40; // Fixed header size with no extension
|
||||||
|
p.data += hlen;
|
||||||
|
p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
||||||
|
if(p.len > length) {
|
||||||
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
|
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.len == 0) {
|
||||||
|
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
||||||
|
p.len = p._len;
|
||||||
|
}
|
||||||
|
|
||||||
|
proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlen=p.ip->ip_hl * 4;
|
switch(proto){
|
||||||
p.data += hlen;
|
|
||||||
p.len = ntohs(p.ip->ip_len);
|
|
||||||
|
|
||||||
if(p.len > length) {
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
|
||||||
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.len == 0) {
|
|
||||||
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
|
||||||
p.len = p._len;
|
|
||||||
}
|
|
||||||
p.len -= hlen;
|
|
||||||
|
|
||||||
switch(p.ip->ip_p){
|
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
if((r=process_tcp_packet(handler->mod,handler->ctx,&p)))
|
if((r=process_tcp_packet(handler->mod,handler->ctx,&p)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,26 +280,43 @@ int timestamp_diff(t1,t0,diff)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int lookuphostname(addr,namep)
|
int lookuphostname(so_st,namep)
|
||||||
struct in_addr *addr;
|
struct sockaddr_storage *so_st;
|
||||||
char **namep;
|
char **namep;
|
||||||
{
|
{
|
||||||
struct hostent *ne=0;
|
int r = 1;
|
||||||
|
*namep = calloc(1, NI_MAXHOST);
|
||||||
|
void *addr = NULL;
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)){
|
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||||
ne=gethostbyaddr((char *)addr,4,AF_INET);
|
r = getnameinfo((struct sockaddr *) so_st, sizeof(struct sockaddr_storage), *namep, NI_MAXHOST, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ne){
|
if(r) {
|
||||||
*namep=strdup((char *)inet_ntoa(*addr));
|
if(so_st->ss_family == AF_INET) {
|
||||||
}
|
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
||||||
else{
|
} else {
|
||||||
*namep=strdup(ne->h_name);
|
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
||||||
|
}
|
||||||
|
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int addrtotext(so_st,namep)
|
||||||
|
struct sockaddr_storage *so_st;
|
||||||
|
char **namep;
|
||||||
|
{
|
||||||
|
*namep = calloc(1, NI_MAXHOST);
|
||||||
|
void *addr = NULL;
|
||||||
|
|
||||||
|
if(so_st->ss_family == AF_INET) {
|
||||||
|
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
||||||
|
} else {
|
||||||
|
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
||||||
|
}
|
||||||
|
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <netinet/in_systm.h>
|
#include <netinet/in_systm.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <r_time.h>
|
#include <r_time.h>
|
||||||
#include <r_data.h>
|
#include <r_data.h>
|
||||||
|
@ -77,12 +78,13 @@ int network_handler_create PROTO_LIST((proto_mod *mod,
|
||||||
n_handler **handlerp));
|
n_handler **handlerp));
|
||||||
int network_handler_destroy PROTO_LIST((proto_mod *mod,n_handler **handlerp));
|
int network_handler_destroy PROTO_LIST((proto_mod *mod,n_handler **handlerp));
|
||||||
int network_process_packet PROTO_LIST((n_handler *handler,
|
int network_process_packet PROTO_LIST((n_handler *handler,
|
||||||
struct timeval *timestamp,UCHAR *data,int length));
|
struct timeval *timestamp,UCHAR *data,int length,int af));
|
||||||
int packet_copy PROTO_LIST((packet *in,packet **out));
|
int packet_copy PROTO_LIST((packet *in,packet **out));
|
||||||
int packet_destroy PROTO_LIST((packet *p));
|
int packet_destroy PROTO_LIST((packet *p));
|
||||||
int timestamp_diff PROTO_LIST(( struct timeval *t1,struct timeval *t0,
|
int timestamp_diff PROTO_LIST(( struct timeval *t1,struct timeval *t0,
|
||||||
struct timeval *diff));
|
struct timeval *diff));
|
||||||
int lookuphostname PROTO_LIST((struct in_addr *addr,char **name));
|
int lookuphostname PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||||
|
int addrtotext PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||||
|
|
||||||
struct packet_ {
|
struct packet_ {
|
||||||
struct timeval ts;
|
struct timeval ts;
|
||||||
|
@ -94,7 +96,22 @@ struct packet_ {
|
||||||
/*These just save us the effort of doing casts to the data
|
/*These just save us the effort of doing casts to the data
|
||||||
segments*/
|
segments*/
|
||||||
struct ip *ip; /*The IP header*/
|
struct ip *ip; /*The IP header*/
|
||||||
|
int af;
|
||||||
|
union {
|
||||||
|
struct ip *ip; /*The IP header*/
|
||||||
|
struct ip6_hdr *ip6; /*The IP header*/
|
||||||
|
} l3_hdr;
|
||||||
struct tcphdr *tcp; /*The TCP header*/
|
struct tcphdr *tcp; /*The TCP header*/
|
||||||
|
union {
|
||||||
|
struct sockaddr_storage so_st;
|
||||||
|
struct sockaddr_in so_in;
|
||||||
|
struct sockaddr_in6 so_in6;
|
||||||
|
} i_addr;
|
||||||
|
union {
|
||||||
|
struct sockaddr_storage so_st;
|
||||||
|
struct sockaddr_in so_in;
|
||||||
|
struct sockaddr_in6 so_in6;
|
||||||
|
} r_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "tcpconn.h"
|
#include "tcpconn.h"
|
||||||
|
|
|
@ -204,7 +204,7 @@ void pcap_cb(ptr,hdr,data)
|
||||||
len+=4;
|
len+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type!=ETHERTYPE_IP)
|
if(type!=ETHERTYPE_IP && type!=ETHERTYPE_IPV6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -276,7 +276,11 @@ void pcap_cb(ptr,hdr,data)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len);
|
|
||||||
|
if(type == ETHERTYPE_IPV6)
|
||||||
|
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET6);
|
||||||
|
else
|
||||||
|
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET);
|
||||||
|
|
||||||
if(packet_cnt == conn_freq) {
|
if(packet_cnt == conn_freq) {
|
||||||
packet_cnt = 0;
|
packet_cnt = 0;
|
||||||
|
|
|
@ -60,8 +60,8 @@ struct proto_mod_vtbl_ {
|
||||||
int (*create) PROTO_LIST((void *handle,proto_ctx *ctx,
|
int (*create) PROTO_LIST((void *handle,proto_ctx *ctx,
|
||||||
tcp_conn *conn,
|
tcp_conn *conn,
|
||||||
proto_obj **objp,
|
proto_obj **objp,
|
||||||
struct in_addr *i_addr,u_short i_port,
|
struct sockaddr_storage *i_addr,u_short i_port,
|
||||||
struct in_addr *r_addr,u_short r_port,struct timeval *time_base));
|
struct sockaddr_storage *r_addr,u_short r_port,struct timeval *time_base));
|
||||||
int (*destroy_ctx) PROTO_LIST((void *handle,proto_ctx **ctxp));
|
int (*destroy_ctx) PROTO_LIST((void *handle,proto_ctx **ctxp));
|
||||||
int (*destroy) PROTO_LIST((proto_obj **objp));
|
int (*destroy) PROTO_LIST((proto_obj **objp));
|
||||||
int (*data) PROTO_LIST((proto_obj *obj,segment *data,int direction));
|
int (*data) PROTO_LIST((proto_obj *obj,segment *data,int direction));
|
||||||
|
@ -89,8 +89,8 @@ struct logger_mod_vtbl_ {
|
||||||
int (*init) PROTO_LIST((void *data));
|
int (*init) PROTO_LIST((void *data));
|
||||||
//deinit must be async signal safe(!!!)
|
//deinit must be async signal safe(!!!)
|
||||||
int (*deinit) PROTO_LIST(());
|
int (*deinit) PROTO_LIST(());
|
||||||
int (*create) PROTO_LIST((proto_obj **objp, struct in_addr *i_addr,u_short i_port,
|
int (*create) PROTO_LIST((proto_obj **objp, struct sockaddr_storage *i_addr,u_short i_port,
|
||||||
struct in_addr *r_addr,u_short r_port,struct timeval *time_base));
|
struct sockaddr_storage *r_addr,u_short r_port,struct timeval *time_base));
|
||||||
int (*destroy) PROTO_LIST((proto_obj **objp));
|
int (*destroy) PROTO_LIST((proto_obj **objp));
|
||||||
int (*data) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
int (*data) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
||||||
int (*close) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
int (*close) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
||||||
|
|
|
@ -70,16 +70,16 @@ static int zero_conn(conn)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_find_conn(tcp_conn **connp, int *directionp,struct in_addr *saddr,
|
int tcp_find_conn(tcp_conn **connp, int *directionp,struct sockaddr_storage *saddr,
|
||||||
u_short sport, struct in_addr *daddr, u_short dport)
|
u_short sport, struct sockaddr_storage *daddr, u_short dport)
|
||||||
{
|
{
|
||||||
conn_struct *conn;
|
conn_struct *conn;
|
||||||
|
|
||||||
for(conn=first_conn;conn;conn=conn->next){
|
for(conn=first_conn;conn;conn=conn->next){
|
||||||
|
|
||||||
if(sport == conn->conn.i_port && dport==conn->conn.r_port){
|
if(sport == conn->conn.i_port && dport==conn->conn.r_port){
|
||||||
if(!memcmp(saddr,&conn->conn.i_addr,sizeof(struct in_addr))
|
if(!memcmp(saddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage))
|
||||||
&& !memcmp(daddr,&conn->conn.r_addr,sizeof(struct in_addr)))
|
&& !memcmp(daddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage)))
|
||||||
{
|
{
|
||||||
*directionp=DIR_I2R;
|
*directionp=DIR_I2R;
|
||||||
*connp=&(conn->conn);
|
*connp=&(conn->conn);
|
||||||
|
@ -88,8 +88,8 @@ int tcp_find_conn(tcp_conn **connp, int *directionp,struct in_addr *saddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dport == conn->conn.i_port && sport==conn->conn.r_port){
|
if(dport == conn->conn.i_port && sport==conn->conn.r_port){
|
||||||
if(!memcmp(saddr,&conn->conn.r_addr,sizeof(struct in_addr))
|
if(!memcmp(saddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage))
|
||||||
&& !memcmp(daddr,&conn->conn.i_addr,sizeof(struct in_addr)))
|
&& !memcmp(daddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage)))
|
||||||
{
|
{
|
||||||
*directionp=DIR_R2I;
|
*directionp=DIR_R2I;
|
||||||
*connp=&(conn->conn);
|
*connp=&(conn->conn);
|
||||||
|
@ -101,8 +101,8 @@ int tcp_find_conn(tcp_conn **connp, int *directionp,struct in_addr *saddr,
|
||||||
return(R_NOT_FOUND);
|
return(R_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_create_conn(tcp_conn **connp,struct in_addr *i_addr,
|
int tcp_create_conn(tcp_conn **connp,struct sockaddr_storage *i_addr,
|
||||||
u_short i_port, struct in_addr *r_addr, u_short r_port)
|
u_short i_port, struct sockaddr_storage *r_addr, u_short r_port)
|
||||||
{
|
{
|
||||||
conn_struct *conn=0;
|
conn_struct *conn=0;
|
||||||
|
|
||||||
|
@ -115,9 +115,9 @@ int tcp_create_conn(tcp_conn **connp,struct in_addr *i_addr,
|
||||||
conn->conn.backptr=conn;
|
conn->conn.backptr=conn;
|
||||||
conn->conn.conn_number=conn_number++;
|
conn->conn.conn_number=conn_number++;
|
||||||
|
|
||||||
memcpy(&conn->conn.i_addr,i_addr,sizeof(struct in_addr));
|
memcpy(&conn->conn.i_addr,i_addr,sizeof(struct sockaddr_storage));
|
||||||
conn->conn.i_port=i_port;
|
conn->conn.i_port=i_port;
|
||||||
memcpy(&conn->conn.r_addr,r_addr,sizeof(struct in_addr));
|
memcpy(&conn->conn.r_addr,r_addr,sizeof(struct sockaddr_storage));
|
||||||
conn->conn.r_port=r_port;
|
conn->conn.r_port=r_port;
|
||||||
*connp=&(conn->conn);
|
*connp=&(conn->conn);
|
||||||
|
|
||||||
|
@ -150,6 +150,10 @@ int tcp_destroy_conn(conn)
|
||||||
destroy_proto_handler(&conn->analyzer);
|
destroy_proto_handler(&conn->analyzer);
|
||||||
free_tcp_segment_queue(conn->i2r.oo_queue);
|
free_tcp_segment_queue(conn->i2r.oo_queue);
|
||||||
free_tcp_segment_queue(conn->r2i.oo_queue);
|
free_tcp_segment_queue(conn->r2i.oo_queue);
|
||||||
|
free(conn->i_name);
|
||||||
|
free(conn->r_name);
|
||||||
|
free(conn->i_num);
|
||||||
|
free(conn->r_num);
|
||||||
zero_conn(conn);
|
zero_conn(conn);
|
||||||
free(conn->backptr);
|
free(conn->backptr);
|
||||||
free(conn);
|
free(conn);
|
||||||
|
|
|
@ -72,12 +72,16 @@ typedef struct tcp_conn_ {
|
||||||
#define TCP_STATE_FIN1 5
|
#define TCP_STATE_FIN1 5
|
||||||
#define TCP_STATE_CLOSED 6
|
#define TCP_STATE_CLOSED 6
|
||||||
/*The address which sent the first SYN*/
|
/*The address which sent the first SYN*/
|
||||||
struct in_addr i_addr;
|
struct sockaddr_storage i_addr;
|
||||||
u_short i_port;
|
u_short i_port;
|
||||||
|
char *i_name;
|
||||||
|
char *i_num;
|
||||||
|
|
||||||
/*The address which sent the second SYN*/
|
/*The address which sent the second SYN*/
|
||||||
struct in_addr r_addr;
|
struct sockaddr_storage r_addr;
|
||||||
u_short r_port;
|
u_short r_port;
|
||||||
|
char *r_name;
|
||||||
|
char *r_num;
|
||||||
|
|
||||||
stream_data i2r; /*The stream from initiator to responder*/
|
stream_data i2r; /*The stream from initiator to responder*/
|
||||||
stream_data r2i; /*The stream from responder to initiator*/
|
stream_data r2i; /*The stream from responder to initiator*/
|
||||||
|
@ -90,12 +94,12 @@ typedef struct tcp_conn_ {
|
||||||
|
|
||||||
int tcp_find_conn PROTO_LIST((tcp_conn **connp,
|
int tcp_find_conn PROTO_LIST((tcp_conn **connp,
|
||||||
int *directionp,
|
int *directionp,
|
||||||
struct in_addr *src_addr, u_short src_port,
|
struct sockaddr_storage *src_addr, u_short src_port,
|
||||||
struct in_addr *dst_addr, u_short dst_port));
|
struct sockaddr_storage *dst_addr, u_short dst_port));
|
||||||
|
|
||||||
int tcp_create_conn PROTO_LIST((tcp_conn **connp,
|
int tcp_create_conn PROTO_LIST((tcp_conn **connp,
|
||||||
struct in_addr *initiator_addr, u_short initiator_port,
|
struct sockaddr_storage *initiator_addr, u_short initiator_port,
|
||||||
struct in_addr *responder_addr, u_short responder_port));
|
struct sockaddr_storage *responder_addr, u_short responder_port));
|
||||||
|
|
||||||
int tcp_destroy_conn PROTO_LIST((tcp_conn *conn));
|
int tcp_destroy_conn PROTO_LIST((tcp_conn *conn));
|
||||||
int free_tcp_segment_queue PROTO_LIST((segment *seg));
|
int free_tcp_segment_queue PROTO_LIST((segment *seg));
|
||||||
|
|
|
@ -88,8 +88,8 @@ int process_tcp_packet(handler,ctx,p)
|
||||||
|
|
||||||
print_tcp_packet(p);
|
print_tcp_packet(p);
|
||||||
|
|
||||||
if((r=tcp_find_conn(&conn,&direction,&p->ip->ip_src,
|
if((r=tcp_find_conn(&conn,&direction,&p->i_addr.so_st,
|
||||||
ntohs(p->tcp->th_sport),&p->ip->ip_dst,ntohs(p->tcp->th_dport)))){
|
ntohs(p->tcp->th_sport),&p->r_addr.so_st,ntohs(p->tcp->th_dport)))){
|
||||||
if(r!=R_NOT_FOUND)
|
if(r!=R_NOT_FOUND)
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
|
@ -126,26 +126,21 @@ int process_tcp_packet(handler,ctx,p)
|
||||||
break;
|
break;
|
||||||
case TCP_STATE_ACK:
|
case TCP_STATE_ACK:
|
||||||
{
|
{
|
||||||
char *sn=0,*dn=0;
|
|
||||||
if(direction != DIR_I2R)
|
if(direction != DIR_I2R)
|
||||||
break;
|
break;
|
||||||
DBG((0,"ACK seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0,"ACK seq: %u",ntohl(p->tcp->th_seq)));
|
||||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
||||||
lookuphostname(&conn->i_addr,&sn);
|
|
||||||
lookuphostname(&conn->r_addr,&dn);
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
printf("\\fC");
|
printf("\\fC");
|
||||||
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n",
|
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n",
|
||||||
conn->conn_number,
|
conn->conn_number,
|
||||||
sn,conn->i_port,
|
conn->i_name,conn->i_port,
|
||||||
dn,conn->r_port);
|
conn->r_name,conn->r_port);
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
printf("\\fR");
|
printf("\\fR");
|
||||||
}
|
}
|
||||||
conn->state=TCP_STATE_ESTABLISHED;
|
conn->state=TCP_STATE_ESTABLISHED;
|
||||||
free(sn);
|
|
||||||
free(dn);
|
|
||||||
}
|
}
|
||||||
case TCP_STATE_ESTABLISHED:
|
case TCP_STATE_ESTABLISHED:
|
||||||
case TCP_STATE_FIN1:
|
case TCP_STATE_FIN1:
|
||||||
|
@ -180,16 +175,16 @@ static int new_connection(handler,ctx,p,connp)
|
||||||
tcp_conn *conn=0;
|
tcp_conn *conn=0;
|
||||||
|
|
||||||
if ((p->tcp->th_flags & (TH_SYN|TH_ACK))==TH_SYN) {
|
if ((p->tcp->th_flags & (TH_SYN|TH_ACK))==TH_SYN) {
|
||||||
if((r=tcp_create_conn(&conn,&p->ip->ip_src,ntohs(p->tcp->th_sport),
|
if((r=tcp_create_conn(&conn,&p->i_addr.so_st,ntohs(p->tcp->th_sport),
|
||||||
&p->ip->ip_dst,ntohs(p->tcp->th_dport))))
|
&p->r_addr.so_st,ntohs(p->tcp->th_dport))))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
||||||
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
||||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
||||||
conn->state=TCP_STATE_SYN1;
|
conn->state=TCP_STATE_SYN1;
|
||||||
} else { // SYN&ACK comes first somehow
|
} else { // SYN&ACK comes first somehow
|
||||||
if((r=tcp_create_conn(&conn,&p->ip->ip_dst,ntohs(p->tcp->th_dport),
|
if((r=tcp_create_conn(&conn,&p->r_addr.so_st,ntohs(p->tcp->th_dport),
|
||||||
&p->ip->ip_src,ntohs(p->tcp->th_sport))))
|
&p->i_addr.so_st,ntohs(p->tcp->th_sport))))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
||||||
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
||||||
|
@ -198,6 +193,10 @@ static int new_connection(handler,ctx,p,connp)
|
||||||
}
|
}
|
||||||
memcpy(&conn->start_time,&p->ts,sizeof(struct timeval));
|
memcpy(&conn->start_time,&p->ts,sizeof(struct timeval));
|
||||||
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
|
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
|
||||||
|
lookuphostname(&conn->i_addr,&conn->i_name);
|
||||||
|
lookuphostname(&conn->r_addr,&conn->r_name);
|
||||||
|
addrtotext(&conn->i_addr,&conn->i_num);
|
||||||
|
addrtotext(&conn->r_addr,&conn->r_num);
|
||||||
if((r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)))
|
if((r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
|
@ -402,8 +401,8 @@ static int print_tcp_packet(p)
|
||||||
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
lookuphostname(&p->ip->ip_src,&src);
|
lookuphostname(&p->i_addr.so_st,&src);
|
||||||
lookuphostname(&p->ip->ip_dst,&dst);
|
lookuphostname(&p->r_addr.so_st,&dst);
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||||
printf("TCP: %s(%d) -> %s(%d) ",
|
printf("TCP: %s(%d) -> %s(%d) ",
|
||||||
|
|
|
@ -56,11 +56,11 @@ typedef struct null_analyzer_ {
|
||||||
|
|
||||||
static int create_null_analyzer PROTO_LIST((void *handle,
|
static int create_null_analyzer PROTO_LIST((void *handle,
|
||||||
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
||||||
struct in_addr *i_addr,u_short i_port,
|
struct sockaddr_storage *i_addr,u_short i_port,
|
||||||
struct in_addr *r_addr,u_short r_port, struct timeval *base_time));
|
struct sockaddr_storage *r_addr,u_short r_port, struct timeval *base_time));
|
||||||
|
|
||||||
static int create_null_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
static int create_null_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
||||||
proto_obj **objp, struct in_addr *i_addr, u_short i_port, struct in_addr *r_addr,
|
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)
|
u_short r_port, struct timeval *base_time)
|
||||||
{
|
{
|
||||||
null_analyzer *obj=0;
|
null_analyzer *obj=0;
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
static int init_pcap_logger PROTO_LIST((void * data));
|
static int init_pcap_logger PROTO_LIST((void * data));
|
||||||
static int deinit_pcap_logger PROTO_LIST(());
|
static int deinit_pcap_logger PROTO_LIST(());
|
||||||
static int create_pcap_logger PROTO_LIST((proto_obj **objp, struct in_addr *i_addr,
|
static int create_pcap_logger PROTO_LIST((proto_obj **objp, struct sockaddr_storage *i_addr,
|
||||||
u_short i_port,struct in_addr *r_addr, u_short r_port, struct timeval *base_time));
|
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 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 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));
|
static int close_pcap_logger PROTO_LIST((proto_obj *_obj, unsigned char *data,unsigned int len, int dir));
|
||||||
|
@ -52,7 +52,7 @@ static int deinit_pcap_logger()
|
||||||
return 0;
|
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)
|
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 r,_status;
|
int r,_status;
|
||||||
logpkt_ctx_t *pcap_obj=0;
|
logpkt_ctx_t *pcap_obj=0;
|
||||||
|
@ -61,13 +61,15 @@ static int create_pcap_logger(proto_obj **objp, struct in_addr *i_addr, u_short
|
||||||
if(!(pcap_obj=(logpkt_ctx_t *)calloc(1,sizeof(logpkt_ctx_t))))
|
if(!(pcap_obj=(logpkt_ctx_t *)calloc(1,sizeof(logpkt_ctx_t))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
src_addr.sin_family = AF_INET;
|
//src_addr.sin_family = AF_INET;
|
||||||
src_addr.sin_port = htons(i_port);
|
//src_addr.sin_port = htons(i_port);
|
||||||
src_addr.sin_addr = *i_addr;
|
//src_addr.sin_addr = *i_addr;
|
||||||
|
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
dst_addr.sin_family = AF_INET;
|
//dst_addr.sin_family = AF_INET;
|
||||||
dst_addr.sin_port = htons(r_port);
|
//dst_addr.sin_port = htons(r_port);
|
||||||
dst_addr.sin_addr = *r_addr;
|
//dst_addr.sin_addr = *r_addr;
|
||||||
|
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
logpkt_ctx_init(pcap_obj,NULL,0,content_pcap_src_ether, content_pcap_dst_ether,
|
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*)&src_addr, sizeof(src_addr),
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#include <json-c/json.h>
|
#include <json-c/json.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "sslprint.h"
|
#include "sslprint.h"
|
||||||
|
@ -59,8 +60,8 @@ static int parse_ssl_flags PROTO_LIST((char *str));
|
||||||
static int create_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
static int create_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
||||||
static int create_ssl_analyzer PROTO_LIST((void *handle,
|
static int create_ssl_analyzer PROTO_LIST((void *handle,
|
||||||
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
||||||
struct in_addr *i_addr,u_short i_port,
|
struct sockaddr_storage *i_addr,u_short i_port,
|
||||||
struct in_addr *r_addr,u_short r_port, struct timeval *base_time));
|
struct sockaddr_storage *r_addr,u_short r_port, struct timeval *base_time));
|
||||||
static int destroy_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
static int destroy_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
||||||
static int destroy_ssl_analyzer PROTO_LIST((proto_obj **objp));
|
static int destroy_ssl_analyzer PROTO_LIST((proto_obj **objp));
|
||||||
static int read_ssl_record PROTO_LIST((ssl_obj *obj,r_queue *q,segment *seg,
|
static int read_ssl_record PROTO_LIST((ssl_obj *obj,r_queue *q,segment *seg,
|
||||||
|
@ -240,7 +241,7 @@ static int destroy_ssl_ctx(handle,ctxp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
||||||
proto_obj **objp, struct in_addr *i_addr, u_short i_port, struct in_addr *r_addr,
|
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)
|
u_short r_port, struct timeval *base_time)
|
||||||
{
|
{
|
||||||
int r,_status;
|
int r,_status;
|
||||||
|
@ -257,15 +258,12 @@ static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
||||||
if((r=create_r_queue(&obj->i2r_queue)))
|
if((r=create_r_queue(&obj->i2r_queue)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
lookuphostname(i_addr,&obj->client_name);
|
obj->client_name = strndup(conn->i_name, NI_MAXHOST);
|
||||||
if(!(obj->client_ip=(char *)calloc(1,INET_ADDRSTRLEN)))
|
obj->client_ip = strndup(conn->i_num, INET6_ADDRSTRLEN);
|
||||||
ABORT(R_NO_MEMORY);
|
|
||||||
inet_ntop(AF_INET, i_addr, obj->client_ip, INET_ADDRSTRLEN);
|
|
||||||
obj->client_port=i_port;
|
obj->client_port=i_port;
|
||||||
lookuphostname(r_addr,&obj->server_name);
|
|
||||||
if(!(obj->server_ip=(char *)calloc(1,INET_ADDRSTRLEN)))
|
obj->server_name = strndup(conn->r_name, NI_MAXHOST);
|
||||||
ABORT(R_NO_MEMORY);
|
obj->server_ip = strndup(conn->r_num, INET6_ADDRSTRLEN);
|
||||||
inet_ntop(AF_INET, r_addr, obj->server_ip, INET_ADDRSTRLEN);
|
|
||||||
obj->server_port=r_port;
|
obj->server_port=r_port;
|
||||||
|
|
||||||
obj->i_state=SSL_ST_SENT_NOTHING;
|
obj->i_state=SSL_ST_SENT_NOTHING;
|
||||||
|
|
Loading…
Reference in a new issue