mirror of
https://github.com/adulau/ssldump.git
synced 2024-12-10 18:27:23 +00:00
Lint ALL the things !
This commit is contained in:
parent
26a3816051
commit
ecacee7c36
58 changed files with 8234 additions and 9935 deletions
424
base/network.c
424
base/network.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||
DAMAGE.
|
||||
|
||||
$Id: network.c,v 1.10 2002/09/09 21:02:58 ekr Exp $
|
||||
|
||||
|
@ -43,8 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 09:52:54 1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <r_common.h>
|
||||
#include "network.h"
|
||||
|
@ -64,248 +63,251 @@
|
|||
UINT4 NET_print_flags;
|
||||
|
||||
struct network_handler_ {
|
||||
proto_mod *mod;
|
||||
proto_ctx *ctx;
|
||||
proto_mod *mod;
|
||||
proto_ctx *ctx;
|
||||
};
|
||||
|
||||
int
|
||||
network_handler_create (proto_mod *mod, n_handler **handlerp)
|
||||
{
|
||||
int r,_status;
|
||||
n_handler *handler=0;
|
||||
|
||||
if(!(handler=(n_handler *)malloc(sizeof(n_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(mod->vtbl->create_ctx){
|
||||
if((r=mod->vtbl->create_ctx(mod->handle,&handler->ctx)))
|
||||
ABORT(r);
|
||||
}
|
||||
handler->mod=mod;
|
||||
*handlerp=handler;
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
network_handler_destroy(mod, &handler);
|
||||
}
|
||||
return(_status);
|
||||
int network_handler_create(proto_mod *mod, n_handler **handlerp) {
|
||||
int r, _status;
|
||||
n_handler *handler = 0;
|
||||
|
||||
if(!(handler = (n_handler *)malloc(sizeof(n_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(mod->vtbl->create_ctx) {
|
||||
if((r = mod->vtbl->create_ctx(mod->handle, &handler->ctx)))
|
||||
ABORT(r);
|
||||
}
|
||||
handler->mod = mod;
|
||||
*handlerp = handler;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
network_handler_destroy(mod, &handler);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int network_handler_destroy(proto_mod *mod, n_handler **handlerp) {
|
||||
n_handler *handler = 0;
|
||||
if(!handlerp || !*handlerp)
|
||||
return (0);
|
||||
|
||||
handler = *handlerp;
|
||||
|
||||
mod->vtbl->destroy_ctx(mod->handle, &handler->ctx);
|
||||
free(*handlerp);
|
||||
*handlerp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int network_process_packet(n_handler *handler,
|
||||
struct timeval *timestamp,
|
||||
UCHAR *data,
|
||||
int length,
|
||||
int af) {
|
||||
int r;
|
||||
int hlen;
|
||||
packet p;
|
||||
u_short off;
|
||||
int proto;
|
||||
|
||||
/*We can pretty much ignore all the options*/
|
||||
memcpy(&p.ts, timestamp, sizeof(struct timeval));
|
||||
p.base = data;
|
||||
p._len = length;
|
||||
p.data = data;
|
||||
p.len = length;
|
||||
p.af = af;
|
||||
|
||||
if(p.len < 20) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf(
|
||||
"Malformed packet, packet too small to contain IP header, skipping "
|
||||
"...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
network_handler_destroy (proto_mod *mod, n_handler **handlerp)
|
||||
{
|
||||
n_handler *handler=0;
|
||||
if(!handlerp || !*handlerp)
|
||||
return(0);
|
||||
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
|
||||
handler = *handlerp;
|
||||
if(af == AF_INET) {
|
||||
p.l3_hdr.ip = (struct ip *)data;
|
||||
memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src,
|
||||
sizeof(struct in_addr));
|
||||
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;
|
||||
|
||||
mod->vtbl->destroy_ctx(mod->handle,&handler->ctx);
|
||||
free(*handlerp);
|
||||
*handlerp=0;
|
||||
return(0);
|
||||
}
|
||||
/*Handle, or rather mishandle, fragmentation*/
|
||||
off = ntohs(p.l3_hdr.ip->ip_off);
|
||||
|
||||
int
|
||||
network_process_packet (n_handler *handler, struct timeval *timestamp, UCHAR *data, int length, int af)
|
||||
{
|
||||
int r;
|
||||
int hlen;
|
||||
packet p;
|
||||
u_short off;
|
||||
int proto;
|
||||
|
||||
/*We can pretty much ignore all the options*/
|
||||
memcpy(&p.ts,timestamp,sizeof(struct timeval));
|
||||
p.base=data;
|
||||
p._len=length;
|
||||
p.data=data;
|
||||
p.len=length;
|
||||
p.af=af;
|
||||
if((off & 0x1fff) || /*Later fragment*/
|
||||
(off & 0x2000)) { /*More fragments*/
|
||||
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(p.len < 20) {
|
||||
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, packet too small to contain IP header, skipping ...\n");
|
||||
return(0);
|
||||
printf(
|
||||
"Malformed packet, size from IP header is larger than size "
|
||||
"reported by libpcap, skipping ...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
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;
|
||||
|
||||
if(af == AF_INET) {
|
||||
p.l3_hdr.ip=(struct ip *)data;
|
||||
memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src, sizeof(struct in_addr));
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
switch(proto){
|
||||
case IPPROTO_TCP:
|
||||
if((r=process_tcp_packet(handler->mod,handler->ctx,&p)))
|
||||
ERETURN(r);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
packet_copy (packet *in, packet **out)
|
||||
{
|
||||
int _status;
|
||||
|
||||
packet *p=0;
|
||||
|
||||
if(!(p=(packet *)calloc(1,sizeof(packet))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(&p->ts,&in->ts,sizeof(struct timeval));
|
||||
if(!(p->base=(UCHAR *)malloc(in->_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(p->base,in->base,p->_len=in->_len);
|
||||
|
||||
p->data=p->base + (in->data - in->base);
|
||||
p->len=in->len;
|
||||
|
||||
p->ip=(struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
||||
p->tcp=(struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
||||
|
||||
*out=p;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
packet_destroy(p);
|
||||
}
|
||||
return(_status);
|
||||
switch(proto) {
|
||||
case IPPROTO_TCP:
|
||||
if((r = process_tcp_packet(handler->mod, handler->ctx, &p)))
|
||||
ERETURN(r);
|
||||
break;
|
||||
}
|
||||
|
||||
int
|
||||
packet_destroy (packet *p)
|
||||
{
|
||||
if(!p)
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
FREE(p->base);
|
||||
FREE(p);
|
||||
return(0);
|
||||
int packet_copy(packet *in, packet **out) {
|
||||
int _status;
|
||||
|
||||
packet *p = 0;
|
||||
|
||||
if(!(p = (packet *)calloc(1, sizeof(packet))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(&p->ts, &in->ts, sizeof(struct timeval));
|
||||
if(!(p->base = (UCHAR *)malloc(in->_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(p->base, in->base, p->_len = in->_len);
|
||||
|
||||
p->data = p->base + (in->data - in->base);
|
||||
p->len = in->len;
|
||||
|
||||
p->ip = (struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
||||
p->tcp = (struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
||||
|
||||
*out = p;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
packet_destroy(p);
|
||||
}
|
||||
|
||||
int
|
||||
timestamp_diff (struct timeval *t1, struct timeval *t0, struct timeval *diff)
|
||||
{
|
||||
long d;
|
||||
return (_status);
|
||||
}
|
||||
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
int packet_destroy(packet *p) {
|
||||
if(!p)
|
||||
return (0);
|
||||
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec){
|
||||
diff->tv_sec=t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec=t1->tv_usec - t0->tv_usec;
|
||||
return(0);
|
||||
}
|
||||
FREE(p->base);
|
||||
FREE(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*Hard case*/
|
||||
d=t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec=t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec=1000000 - d;
|
||||
int timestamp_diff(struct timeval *t1,
|
||||
struct timeval *t0,
|
||||
struct timeval *diff) {
|
||||
long d;
|
||||
|
||||
return(0);
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec) {
|
||||
diff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*Hard case*/
|
||||
d = t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec = 1000000 - d;
|
||||
|
||||
int
|
||||
lookuphostname (struct sockaddr_storage *so_st, char **namep)
|
||||
{
|
||||
int r = 1;
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||
r = getnameinfo((struct sockaddr *) so_st, sizeof(struct sockaddr_storage), *namep, NI_MAXHOST, NULL, 0, 0);
|
||||
}
|
||||
int lookuphostname(struct sockaddr_storage *so_st, char **namep) {
|
||||
int r = 1;
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
|
||||
if(r) {
|
||||
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);
|
||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||
r = getnameinfo((struct sockaddr *)so_st, sizeof(struct sockaddr_storage),
|
||||
*namep, NI_MAXHOST, NULL, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
addrtotext (struct sockaddr_storage *so_st, char **namep)
|
||||
{
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
|
||||
if(r) {
|
||||
if(so_st->ss_family == AF_INET) {
|
||||
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
||||
addr = &((struct sockaddr_in *)so_st)->sin_addr;
|
||||
} else {
|
||||
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
||||
addr = &((struct sockaddr_in6 *)so_st)->sin6_addr;
|
||||
}
|
||||
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int addrtotext(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);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||
DAMAGE.
|
||||
|
||||
$Id: network.h,v 1.3 2001/09/14 22:29:14 ekr Exp $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 09:53:50 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _network_h
|
||||
#define _network_h
|
||||
|
||||
|
@ -74,44 +74,47 @@ typedef struct proto_mod_ proto_mod;
|
|||
typedef struct proto_handler_ proto_handler;
|
||||
typedef struct packet_ packet;
|
||||
|
||||
int network_handler_create 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,
|
||||
struct timeval *timestamp,UCHAR *data,int length,int af));
|
||||
int packet_copy PROTO_LIST((packet *in,packet **out));
|
||||
int packet_destroy PROTO_LIST((packet *p));
|
||||
int timestamp_diff PROTO_LIST(( struct timeval *t1,struct timeval *t0,
|
||||
struct timeval *diff));
|
||||
int lookuphostname PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||
int addrtotext PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||
int network_handler_create 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,
|
||||
struct timeval *timestamp,
|
||||
UCHAR *data,
|
||||
int length,
|
||||
int af));
|
||||
int packet_copy PROTO_LIST((packet * in, packet **out));
|
||||
int packet_destroy PROTO_LIST((packet * p));
|
||||
int timestamp_diff PROTO_LIST((struct timeval * t1,
|
||||
struct timeval *t0,
|
||||
struct timeval *diff));
|
||||
int lookuphostname PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||
int addrtotext PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||
|
||||
struct packet_ {
|
||||
struct timeval ts;
|
||||
UCHAR *base; /*The base of the packet*/
|
||||
int _len;
|
||||
UCHAR *data; /*The data ptr appropriate to this layer*/
|
||||
int len; /*The length of the data segment*/
|
||||
|
||||
/*These just save us the effort of doing casts to the data
|
||||
segments*/
|
||||
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*/
|
||||
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;
|
||||
struct timeval ts;
|
||||
UCHAR *base; /*The base of the packet*/
|
||||
int _len;
|
||||
UCHAR *data; /*The data ptr appropriate to this layer*/
|
||||
int len; /*The length of the data segment*/
|
||||
|
||||
/*These just save us the effort of doing casts to the data
|
||||
segments*/
|
||||
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*/
|
||||
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"
|
||||
|
@ -119,11 +122,10 @@ struct packet_ {
|
|||
|
||||
extern UINT4 NET_print_flags;
|
||||
|
||||
#define NET_PRINT_TCP_HDR 1
|
||||
#define NET_PRINT_TYPESET 2
|
||||
#define NET_PRINT_ACKS 4
|
||||
#define NET_PRINT_NO_RESOLVE 8
|
||||
#define NET_PRINT_JSON 16
|
||||
#define NET_PRINT_TS 32
|
||||
#define NET_PRINT_TCP_HDR 1
|
||||
#define NET_PRINT_TYPESET 2
|
||||
#define NET_PRINT_ACKS 4
|
||||
#define NET_PRINT_NO_RESOLVE 8
|
||||
#define NET_PRINT_JSON 16
|
||||
#define NET_PRINT_TS 32
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
with the distribution.
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -46,9 +46,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <pcap.h>
|
||||
#include <unistd.h>
|
||||
#ifndef __OpenBSD__
|
||||
|
@ -80,493 +77,491 @@
|
|||
#include "pcap_logger.h"
|
||||
|
||||
#ifndef ETHERTYPE_8021Q
|
||||
# define ETHERTYPE_8021Q 0x8100
|
||||
#define ETHERTYPE_8021Q 0x8100
|
||||
#endif
|
||||
|
||||
char *collapse_args PROTO_LIST((int argc,char **argv));
|
||||
static int pcap_if_type=DLT_NULL;
|
||||
int err_exit PROTO_LIST((char *str,int num));
|
||||
char *collapse_args PROTO_LIST((int argc, char **argv));
|
||||
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 pcap_cb PROTO_LIST((u_char *ptr,const struct pcap_pkthdr *hdr,const u_char *data));
|
||||
int main PROTO_LIST((int argc,char **argv));
|
||||
void pcap_cb PROTO_LIST((u_char * ptr,
|
||||
const struct pcap_pkthdr *hdr,
|
||||
const u_char *data));
|
||||
int main PROTO_LIST((int argc, char **argv));
|
||||
|
||||
int packet_cnt = 0; // Packet counter used for connection pool cleaning
|
||||
int conn_freq = 100; // Number of packets after which a connection pool
|
||||
// cleaning is performed
|
||||
int conn_ttl = 100; // TTL of inactive connections in connection pool
|
||||
struct timeval last_packet_seen_time = // Timestamp of the last packet of the
|
||||
(struct timeval) {0}; // last block of conn_freq packets seen
|
||||
int packet_cnt = 0; // Packet counter used for connection pool cleaning
|
||||
int conn_freq = 100; // Number of packets after which a connection pool
|
||||
// cleaning is performed
|
||||
int conn_ttl = 100; // TTL of inactive connections in connection pool
|
||||
struct timeval last_packet_seen_time = // Timestamp of the last packet of the
|
||||
(struct timeval){0}; // last block of conn_freq packets seen
|
||||
|
||||
logger_mod *logger=NULL;
|
||||
logger_mod *logger = NULL;
|
||||
|
||||
int
|
||||
err_exit (char *str, int num)
|
||||
{
|
||||
fprintf(stderr,"ERROR: %s\n",str);
|
||||
sig_handler(SIGQUIT);
|
||||
exit(num);
|
||||
}
|
||||
int err_exit(char *str, int num) {
|
||||
fprintf(stderr, "ERROR: %s\n", str);
|
||||
sig_handler(SIGQUIT);
|
||||
exit(num);
|
||||
}
|
||||
|
||||
int
|
||||
usage (void)
|
||||
{
|
||||
fprintf(stderr,"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w outpcapfile]\n");
|
||||
fprintf(stderr," [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
||||
fprintf(stderr," [filter]\n");
|
||||
exit(0);
|
||||
}
|
||||
int usage(void) {
|
||||
fprintf(stderr,
|
||||
"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w "
|
||||
"outpcapfile]\n");
|
||||
fprintf(stderr,
|
||||
" [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
||||
fprintf(stderr, " [filter]\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
print_version (void)
|
||||
{
|
||||
printf("Version: @ssldump_VERSION@ (@ssldump_DESCRIPTION@)\n");
|
||||
printf("Maintained by a bunch of volunteers, see https://github.com/adulau/ssldump/blob/master/CREDITS\n");
|
||||
printf("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
||||
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
||||
printf("All rights reserved.\n");
|
||||
#ifdef OPENSSL
|
||||
printf("Compiled with OpenSSL: decryption enabled\n");
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
int print_version(void) {
|
||||
printf("Version: @ssldump_VERSION@ (@ssldump_DESCRIPTION@)\n");
|
||||
printf(
|
||||
"Maintained by a bunch of volunteers, see "
|
||||
"https://github.com/adulau/ssldump/blob/master/CREDITS\n");
|
||||
printf("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
||||
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
||||
printf("All rights reserved.\n");
|
||||
#ifdef OPENSSL
|
||||
printf("Compiled with OpenSSL: decryption enabled\n");
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pcap_t *p;
|
||||
proto_mod *mod=&ssl_mod;
|
||||
proto_mod *mod = &ssl_mod;
|
||||
n_handler *n;
|
||||
char *interface_name=0;
|
||||
char *file=0;
|
||||
char *filter=0;
|
||||
void sig_handler(int sig)
|
||||
{
|
||||
int freed_conn = 0;
|
||||
fflush(stdout);
|
||||
if (logger)
|
||||
logger->vtbl->deinit();
|
||||
char *interface_name = 0;
|
||||
char *file = 0;
|
||||
char *filter = 0;
|
||||
void sig_handler(int sig) {
|
||||
int freed_conn = 0;
|
||||
fflush(stdout);
|
||||
if(logger)
|
||||
logger->vtbl->deinit();
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
network_handler_destroy(mod, &n);
|
||||
network_handler_destroy(mod, &n);
|
||||
|
||||
if(p)
|
||||
pcap_close(p);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
if(p)
|
||||
pcap_close(p);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
|
||||
exit(sig);
|
||||
}
|
||||
|
||||
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data)
|
||||
{
|
||||
n_handler *n;
|
||||
int len;
|
||||
struct ether_header *e_hdr=(struct ether_header *)data;
|
||||
int type, cleaned_conn;
|
||||
|
||||
n=(n_handler *)ptr;
|
||||
if(hdr->caplen!=hdr->len) err_exit("Length mismatch",-1);
|
||||
exit(sig);
|
||||
}
|
||||
|
||||
len=hdr->len;
|
||||
|
||||
switch(pcap_if_type){
|
||||
case DLT_RAW:
|
||||
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||
n_handler *n;
|
||||
int len;
|
||||
struct ether_header *e_hdr = (struct ether_header *)data;
|
||||
int type, cleaned_conn;
|
||||
|
||||
n = (n_handler *)ptr;
|
||||
if(hdr->caplen != hdr->len)
|
||||
err_exit("Length mismatch", -1);
|
||||
|
||||
len = hdr->len;
|
||||
|
||||
switch(pcap_if_type) {
|
||||
case DLT_RAW:
|
||||
#ifdef DLT_LOOP
|
||||
case DLT_LOOP:
|
||||
case DLT_LOOP:
|
||||
#endif
|
||||
case DLT_NULL:
|
||||
data+=4;
|
||||
len-=4;
|
||||
break;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
case DLT_NULL:
|
||||
data += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
type=ntohs(e_hdr->ether_type);
|
||||
type = ntohs(e_hdr->ether_type);
|
||||
|
||||
data+=sizeof(struct ether_header);
|
||||
len-=sizeof(struct ether_header);
|
||||
data += sizeof(struct ether_header);
|
||||
len -= sizeof(struct ether_header);
|
||||
|
||||
/* if vlans, push past VLAN header (4 bytes) */
|
||||
if(type==ETHERTYPE_8021Q) {
|
||||
type=ntohs(*(u_int16_t *)(data + 2));
|
||||
/* if vlans, push past VLAN header (4 bytes) */
|
||||
if(type == ETHERTYPE_8021Q) {
|
||||
type = ntohs(*(u_int16_t *)(data + 2));
|
||||
|
||||
data+=4;
|
||||
len+=4;
|
||||
}
|
||||
data += 4;
|
||||
len += 4;
|
||||
}
|
||||
|
||||
if(type!=ETHERTYPE_IP && type!=ETHERTYPE_IPV6)
|
||||
return;
|
||||
if(type != ETHERTYPE_IP && type != ETHERTYPE_IPV6)
|
||||
return;
|
||||
|
||||
break;
|
||||
case DLT_IEEE802:
|
||||
data+=22;
|
||||
len-=22;
|
||||
break;
|
||||
case DLT_FDDI:
|
||||
data+=21;
|
||||
len-=21;
|
||||
break;
|
||||
break;
|
||||
case DLT_IEEE802:
|
||||
data += 22;
|
||||
len -= 22;
|
||||
break;
|
||||
case DLT_FDDI:
|
||||
data += 21;
|
||||
len -= 21;
|
||||
break;
|
||||
#ifdef __amigaos__
|
||||
case DLT_MIAMI:
|
||||
data+=16;
|
||||
len-=16;
|
||||
break;
|
||||
case DLT_MIAMI:
|
||||
data += 16;
|
||||
len -= 16;
|
||||
break;
|
||||
#endif
|
||||
case DLT_SLIP:
|
||||
case DLT_SLIP:
|
||||
#ifdef DLT_SLIP_BSDOS
|
||||
case DLT_SLIP_BSDOS:
|
||||
case DLT_SLIP_BSDOS:
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
||||
data+=16;
|
||||
len-=16;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||
defined(__bsdi__) || defined(__APPLE__)
|
||||
data += 16;
|
||||
len -= 16;
|
||||
#else
|
||||
data+=24;
|
||||
len-=24;
|
||||
data += 24;
|
||||
len -= 24;
|
||||
#endif
|
||||
break;
|
||||
case DLT_PPP:
|
||||
break;
|
||||
case DLT_PPP:
|
||||
#ifdef DLT_PPP_BSDOS
|
||||
case DLT_PPP_BSDOS:
|
||||
case DLT_PPP_BSDOS:
|
||||
#endif
|
||||
#ifdef DLT_PPP_SERIAL
|
||||
case DLT_PPP_SERIAL:
|
||||
case DLT_PPP_SERIAL:
|
||||
#endif
|
||||
#ifdef DLT_PPP_ETHER
|
||||
case DLT_PPP_ETHER:
|
||||
case DLT_PPP_ETHER:
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
||||
data+=4;
|
||||
len-=4;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||
defined(__bsdi__) || defined(__APPLE__)
|
||||
data += 4;
|
||||
len -= 4;
|
||||
#else
|
||||
#if defined(sun) || defined(__sun)
|
||||
data+=8;
|
||||
len-=8;
|
||||
data += 8;
|
||||
len -= 8;
|
||||
#else
|
||||
data+=24;
|
||||
len-=24;
|
||||
data += 24;
|
||||
len -= 24;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
#ifdef DLT_ENC
|
||||
case DLT_ENC:
|
||||
data+=12;
|
||||
len-=12;
|
||||
break;
|
||||
case DLT_ENC:
|
||||
data += 12;
|
||||
len -= 12;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DLT_LINUX_SLL
|
||||
case DLT_LINUX_SLL:
|
||||
data+=16;
|
||||
len-=16;
|
||||
break;
|
||||
case DLT_LINUX_SLL:
|
||||
data += 16;
|
||||
len -= 16;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DLT_IPNET
|
||||
case DLT_IPNET:
|
||||
data+=24;
|
||||
len-=24;
|
||||
break;
|
||||
case DLT_IPNET:
|
||||
data += 24;
|
||||
len -= 24;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
} else {
|
||||
packet_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
} else {
|
||||
packet_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct module_def_ {
|
||||
char *name;
|
||||
proto_mod *mod;
|
||||
char *name;
|
||||
proto_mod *mod;
|
||||
} module_def;
|
||||
|
||||
static module_def modules[]={
|
||||
{"SSL",&ssl_mod},
|
||||
{"NULL",&null_mod},
|
||||
static module_def modules[] = {{"SSL", &ssl_mod},
|
||||
{"NULL", &null_mod},
|
||||
#ifdef ENABLE_RECORD
|
||||
{"RECORD",&record_mod},
|
||||
{"RECORD", &record_mod},
|
||||
#endif
|
||||
{0,0}
|
||||
};
|
||||
|
||||
{0, 0}};
|
||||
|
||||
int parse_ssl_flag PROTO_LIST((int c));
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
int main(int argc, char **argv) {
|
||||
int r;
|
||||
#ifdef _WIN32
|
||||
__declspec(dllimport) char *optarg;
|
||||
__declspec(dllimport) int optind;
|
||||
__declspec(dllimport) char *optarg;
|
||||
__declspec(dllimport) int optind;
|
||||
#else
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
#endif
|
||||
pcap_if_t *interfaces;
|
||||
bpf_u_int32 localnet,netmask;
|
||||
int c;
|
||||
module_def *m=0;
|
||||
int no_promiscuous=0;
|
||||
int freed_conn=0;
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_if_t *interfaces;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
int c;
|
||||
module_def *m = 0;
|
||||
int no_promiscuous = 0;
|
||||
int freed_conn = 0;
|
||||
|
||||
signal(SIGINT,sig_handler);
|
||||
|
||||
while((c=getopt(argc,argv,"vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P"))!=EOF){
|
||||
switch(c){
|
||||
case 'v':
|
||||
print_version();
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr,"-f option replaced by -r. Use that in the future\n");
|
||||
case 'r':
|
||||
file=strdup(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
ssl_mod.vtbl->parse_flags(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
NET_print_flags|=NET_PRINT_TYPESET;
|
||||
/*Kludge*/
|
||||
SSL_print_flags |= SSL_PRINT_NROFF;
|
||||
break;
|
||||
case 'j':
|
||||
NET_print_flags |= NET_PRINT_JSON;
|
||||
SSL_print_flags |= SSL_PRINT_JSON;
|
||||
break;
|
||||
case 'z':
|
||||
NET_print_flags |= NET_PRINT_TS;
|
||||
break;
|
||||
case 'a':
|
||||
NET_print_flags |= NET_PRINT_ACKS;
|
||||
break;
|
||||
case 'A':
|
||||
SSL_print_flags |= SSL_PRINT_ALL_FIELDS;
|
||||
break;
|
||||
case 'T':
|
||||
NET_print_flags |= NET_PRINT_TCP_HDR;
|
||||
break;
|
||||
case 'i':
|
||||
interface_name=strdup(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
SSL_keyfile=strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
SSL_keylogfile=strdup(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
logger=&pcap_mod;
|
||||
if(logger->vtbl->init(optarg)!=0){
|
||||
fprintf(stderr,"Can not open/create out pcap %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
SSL_password=strdup(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
++no_promiscuous;
|
||||
break;
|
||||
case 'n':
|
||||
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
||||
break;
|
||||
case 't':
|
||||
conn_ttl=atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
conn_freq=atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
for(m=modules;m->name!=0;m++){
|
||||
if(!strcmp(m->name,optarg)){
|
||||
mod=m->mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!m->name){
|
||||
fprintf(stderr,"Request analysis module %s not found\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
printf("Do 'man ssldump' for documentation\n");
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) !=
|
||||
EOF) {
|
||||
switch(c) {
|
||||
case 'v':
|
||||
print_version();
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr, "-f option replaced by -r. Use that in the future\n");
|
||||
case 'r':
|
||||
file = strdup(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
ssl_mod.vtbl->parse_flags(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
NET_print_flags |= NET_PRINT_TYPESET;
|
||||
/*Kludge*/
|
||||
SSL_print_flags |= SSL_PRINT_NROFF;
|
||||
break;
|
||||
case 'j':
|
||||
NET_print_flags |= NET_PRINT_JSON;
|
||||
SSL_print_flags |= SSL_PRINT_JSON;
|
||||
break;
|
||||
case 'z':
|
||||
NET_print_flags |= NET_PRINT_TS;
|
||||
break;
|
||||
case 'a':
|
||||
NET_print_flags |= NET_PRINT_ACKS;
|
||||
break;
|
||||
case 'A':
|
||||
SSL_print_flags |= SSL_PRINT_ALL_FIELDS;
|
||||
break;
|
||||
case 'T':
|
||||
NET_print_flags |= NET_PRINT_TCP_HDR;
|
||||
break;
|
||||
case 'i':
|
||||
interface_name = strdup(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
SSL_keyfile = strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
SSL_keylogfile = strdup(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
logger = &pcap_mod;
|
||||
if(logger->vtbl->init(optarg) != 0) {
|
||||
fprintf(stderr, "Can not open/create out pcap %s\n", optarg);
|
||||
exit(1);
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
|
||||
/* must be an SSL flag. This is kind of a gross
|
||||
special case */
|
||||
default:
|
||||
parse_ssl_flag(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argv+=optind;
|
||||
argc-=optind;
|
||||
|
||||
if(!file){
|
||||
if(!interface_name){
|
||||
if(pcap_findalldevs(&interfaces,errbuf)==-1) {
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
interface_name=interfaces->name;
|
||||
if(!interface_name){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
}
|
||||
if(!(p=pcap_open_live(interface_name,65535,!no_promiscuous,1000,errbuf))){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
|
||||
if (pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
||||
fprintf(stderr,"PCAP: %s\n", errbuf);
|
||||
}
|
||||
else{
|
||||
if(!(p=pcap_open_offline(file,errbuf))){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
|
||||
netmask=0;
|
||||
localnet=0;
|
||||
}
|
||||
|
||||
if(argc!=0)
|
||||
filter=collapse_args(argc,argv);
|
||||
|
||||
if(filter){
|
||||
struct bpf_program fp;
|
||||
|
||||
/* (F5 patch)
|
||||
* reformat filter to include traffic with or without the 802.1q
|
||||
* vlan header. for example, "port 80" becomes:
|
||||
* "( port 80 ) or ( vlan and port 80 )".
|
||||
* note that if the filter includes the literals vlan, tagged, or
|
||||
* untagged, then it is assumed that the user knows what she is
|
||||
* doing, and the filter is not reformatted.
|
||||
*/
|
||||
if ((pcap_datalink(p) == DLT_EN10MB) &&
|
||||
(filter != NULL) &&
|
||||
(strstr(filter,"vlan") == NULL)) {
|
||||
char *tmp_filter;
|
||||
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
||||
|
||||
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
||||
if (tmp_filter == NULL) {
|
||||
fprintf(stderr,"PCAP: malloc failed\n");
|
||||
err_exit("Aborting",-1);
|
||||
break;
|
||||
case 'p':
|
||||
SSL_password = strdup(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
++no_promiscuous;
|
||||
break;
|
||||
case 'n':
|
||||
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
||||
break;
|
||||
case 't':
|
||||
conn_ttl = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
conn_freq = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
for(m = modules; m->name != 0; m++) {
|
||||
if(!strcmp(m->name, optarg)) {
|
||||
mod = m->mod;
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(tmp_filter,fmt,filter,filter);
|
||||
free(filter);
|
||||
filter = tmp_filter;
|
||||
}
|
||||
if(!m->name) {
|
||||
fprintf(stderr, "Request analysis module %s not found\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
printf("Do 'man ssldump' for documentation\n");
|
||||
exit(1);
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
|
||||
/* must be an SSL flag. This is kind of a gross
|
||||
special case */
|
||||
default:
|
||||
parse_ssl_flag(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if(!file) {
|
||||
if(!interface_name) {
|
||||
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
interface_name = interfaces->name;
|
||||
if(!interface_name) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
}
|
||||
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
|
||||
errbuf))) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
if(pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
} else {
|
||||
if(!(p = pcap_open_offline(file, errbuf))) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
netmask = 0;
|
||||
localnet = 0;
|
||||
}
|
||||
|
||||
if(argc != 0)
|
||||
filter = collapse_args(argc, argv);
|
||||
|
||||
if(filter) {
|
||||
struct bpf_program fp;
|
||||
|
||||
/* (F5 patch)
|
||||
* reformat filter to include traffic with or without the 802.1q
|
||||
* vlan header. for example, "port 80" becomes:
|
||||
* "( port 80 ) or ( vlan and port 80 )".
|
||||
* note that if the filter includes the literals vlan, tagged, or
|
||||
* untagged, then it is assumed that the user knows what she is
|
||||
* doing, and the filter is not reformatted.
|
||||
*/
|
||||
if((pcap_datalink(p) == DLT_EN10MB) && (filter != NULL) &&
|
||||
(strstr(filter, "vlan") == NULL)) {
|
||||
char *tmp_filter;
|
||||
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
||||
|
||||
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
||||
if(tmp_filter == NULL) {
|
||||
fprintf(stderr, "PCAP: malloc failed\n");
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
if(pcap_compile(p,&fp,filter,0,netmask)<0)
|
||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
||||
|
||||
if(pcap_setfilter(p,&fp)<0)
|
||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
||||
sprintf(tmp_filter, fmt, filter, filter);
|
||||
free(filter);
|
||||
filter = tmp_filter;
|
||||
}
|
||||
|
||||
pcap_if_type=pcap_datalink(p);
|
||||
if(pcap_compile(p, &fp, filter, 0, netmask) < 0)
|
||||
verr_exit("PCAP: %s\n", pcap_geterr(p));
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.nf\n.ps -2\n");
|
||||
|
||||
if((r=network_handler_create(mod,&n)))
|
||||
err_exit("Couldn't create network handler",r);
|
||||
|
||||
pcap_loop(p,-1,pcap_cb,(u_char *)n);
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.ps\n.fi\n");
|
||||
|
||||
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);
|
||||
|
||||
network_handler_destroy(mod, &n);
|
||||
pcap_close(p);
|
||||
|
||||
free(n);
|
||||
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(SSL_keyfile)
|
||||
free(SSL_keyfile);
|
||||