mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-07 12:06:27 +00:00
Initial cmake setup
This commit is contained in:
parent
a933d5b6a2
commit
bde08ddbd5
5 changed files with 848 additions and 574 deletions
76
CMakeLists.txt
Normal file
76
CMakeLists.txt
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
cmake_minimum_required(VERSION 3.18.4)
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
|
project(
|
||||||
|
ssldump
|
||||||
|
VERSION 1.9
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_file(base/pcap-snoop.c.in base/pcap-snoop.c)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
${CMAKE_BINARY_DIR}/base/pcap-snoop.c
|
||||||
|
base/network.c
|
||||||
|
base/proto_mod.c
|
||||||
|
base/tcppack.c
|
||||||
|
base/tcpconn.c
|
||||||
|
null/null_analyze.c
|
||||||
|
common/lib/r_data.c
|
||||||
|
common/lib/r_assoc.c
|
||||||
|
common/lib/r_errors.c
|
||||||
|
common/lib/debug.c
|
||||||
|
ssl/ssl_analyze.c
|
||||||
|
ssl/ssldecode.c
|
||||||
|
ssl/sslprint.c
|
||||||
|
ssl/ssl.enums.c
|
||||||
|
ssl/sslxprint.c
|
||||||
|
ssl/ciphersuites.c
|
||||||
|
ssl/ssl_rec.c
|
||||||
|
pcap/logpkt.c
|
||||||
|
pcap/pcap_logger.c
|
||||||
|
pcap/sys.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/modules/")
|
||||||
|
|
||||||
|
find_package(OpenSSL REQUIRED)
|
||||||
|
find_package(PCAP REQUIRED)
|
||||||
|
find_package(LIBNET REQUIRED)
|
||||||
|
find_package(json-c REQUIRED)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
|
check_symbol_exists(strdup "string.h" HAVE_STRDUP)
|
||||||
|
if(HAVE_STRDUP)
|
||||||
|
add_definitions(-DHAVE_STRDUP)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DLINUX)
|
||||||
|
add_definitions(-DOPENSSL)
|
||||||
|
add_definitions(-D_DEFAULT_SOURCE=1)
|
||||||
|
|
||||||
|
target_include_directories(ssldump
|
||||||
|
PRIVATE
|
||||||
|
${PROJECT_SOURCE_DIR}/common/include
|
||||||
|
${PROJECT_SOURCE_DIR}/common/lib
|
||||||
|
${PROJECT_SOURCE_DIR}/null
|
||||||
|
${PROJECT_SOURCE_DIR}/ssl
|
||||||
|
${PROJECT_SOURCE_DIR}/base
|
||||||
|
${PROJECT_SOURCE_DIR}/pcap
|
||||||
|
${OPENSSL_INCLUDE_DIR}
|
||||||
|
${PCAP_INCLUDE_DIR}
|
||||||
|
${LIBNET_INCLUDE_DIR}
|
||||||
|
${json-c_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(ssldump
|
||||||
|
PRIVATE
|
||||||
|
${OPENSSL_LIBRARIES}
|
||||||
|
pcap
|
||||||
|
net
|
||||||
|
json-c
|
||||||
|
)
|
||||||
|
|
|
@ -1,574 +0,0 @@
|
||||||
/**
|
|
||||||
pcap-snoop.c
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 1999-2001 RTFM, Inc.
|
|
||||||
All Rights Reserved
|
|
||||||
|
|
||||||
This package is a SSLv3/TLS protocol analyzer written by Eric
|
|
||||||
Rescorla <ekr@rtfm.com> and licensed by RTFM, Inc.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the 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.
|
|
||||||
|
|
||||||
4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may
|
|
||||||
be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``AS IS''
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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.
|
|
||||||
|
|
||||||
$Id: pcap-snoop.c,v 1.14 2002/09/09 21:02:58 ekr Exp $
|
|
||||||
|
|
||||||
|
|
||||||
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <pcap.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pcap-bpf.h>
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#else
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <bittypes.h>
|
|
||||||
#endif
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
#include "network.h"
|
|
||||||
#include <r_common.h>
|
|
||||||
#include <r_time.h>
|
|
||||||
#include "null_analyze.h"
|
|
||||||
#include "ssl_analyze.h"
|
|
||||||
#ifdef ENABLE_RECORD
|
|
||||||
#include "record_analyze.h"
|
|
||||||
#endif
|
|
||||||
#include "pcap_logger.h"
|
|
||||||
|
|
||||||
#ifndef ETHERTYPE_8021Q
|
|
||||||
# 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));
|
|
||||||
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));
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
int err_exit(str,num)
|
|
||||||
char *str;
|
|
||||||
int num;
|
|
||||||
{
|
|
||||||
fprintf(stderr,"ERROR: %s\n",str);
|
|
||||||
sig_handler(SIGQUIT);
|
|
||||||
exit(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
int usage()
|
|
||||||
{
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
printf(PACKAGE_STRING "\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;
|
|
||||||
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();
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if(p)
|
|
||||||
pcap_close(p);
|
|
||||||
if(interface_name)
|
|
||||||
free(interface_name);
|
|
||||||
if(filter)
|
|
||||||
free(filter);
|
|
||||||
if(file)
|
|
||||||
free(file);
|
|
||||||
|
|
||||||
exit(sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pcap_cb(ptr,hdr,data)
|
|
||||||
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:
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
type=ntohs(e_hdr->ether_type);
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
data+=4;
|
|
||||||
len+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
#ifdef __amigaos__
|
|
||||||
case DLT_MIAMI:
|
|
||||||
data+=16;
|
|
||||||
len-=16;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case DLT_SLIP:
|
|
||||||
#ifdef DLT_SLIP_BSDOS
|
|
||||||
case DLT_SLIP_BSDOS:
|
|
||||||
#endif
|
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
|
||||||
data+=16;
|
|
||||||
len-=16;
|
|
||||||
#else
|
|
||||||
data+=24;
|
|
||||||
len-=24;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case DLT_PPP:
|
|
||||||
#ifdef DLT_PPP_BSDOS
|
|
||||||
case DLT_PPP_BSDOS:
|
|
||||||
#endif
|
|
||||||
#ifdef DLT_PPP_SERIAL
|
|
||||||
case DLT_PPP_SERIAL:
|
|
||||||
#endif
|
|
||||||
#ifdef DLT_PPP_ETHER
|
|
||||||
case DLT_PPP_ETHER:
|
|
||||||
#endif
|
|
||||||
#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;
|
|
||||||
#else
|
|
||||||
data+=24;
|
|
||||||
len-=24;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
#ifdef DLT_ENC
|
|
||||||
case DLT_ENC:
|
|
||||||
data+=12;
|
|
||||||
len-=12;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DLT_LINUX_SLL
|
|
||||||
case DLT_LINUX_SLL:
|
|
||||||
data+=16;
|
|
||||||
len-=16;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DLT_IPNET
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct module_def_ {
|
|
||||||
char *name;
|
|
||||||
proto_mod *mod;
|
|
||||||
} module_def;
|
|
||||||
|
|
||||||
static module_def modules[]={
|
|
||||||
{"SSL",&ssl_mod},
|
|
||||||
{"NULL",&null_mod},
|
|
||||||
#ifdef ENABLE_RECORD
|
|
||||||
{"RECORD",&record_mod},
|
|
||||||
#endif
|
|
||||||
{0,0}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int parse_ssl_flag PROTO_LIST((int c));
|
|
||||||
|
|
||||||
int main(argc,argv)
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
#ifdef _WIN32
|
|
||||||
__declspec(dllimport) char *optarg;
|
|
||||||
__declspec(dllimport) int optind;
|
|
||||||
#else
|
|
||||||
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];
|
|
||||||
|
|
||||||
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");
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(tmp_filter,fmt,filter,filter);
|
|
||||||
free(filter);
|
|
||||||
filter = tmp_filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
pcap_if_type=pcap_datalink(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);
|
|
||||||
if(SSL_keylogfile)
|
|
||||||
free(SSL_keylogfile);
|
|
||||||
if(SSL_password)
|
|
||||||
free(SSL_password);
|
|
||||||
if (logger)
|
|
||||||
{
|
|
||||||
logger->vtbl->deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *collapse_args(argc,argv)
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
{
|
|
||||||
int i,len=0;
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
if(!argc)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
for(i=0;i<argc;i++){
|
|
||||||
len+=strlen(argv[i])+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(ret=(char *)malloc(len)))
|
|
||||||
err_exit("Out of memory",1);
|
|
||||||
|
|
||||||
len=0;
|
|
||||||
for(i=0;i<argc;i++){
|
|
||||||
strcpy(ret+len,argv[i]);
|
|
||||||
len+=strlen(argv[i]);
|
|
||||||
|
|
||||||
if(i!=(argc-1))
|
|
||||||
ret[len++]=' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
1
base/pcap-snoop.c
Symbolic link
1
base/pcap-snoop.c
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../build/base/pcap-snoop.c
|
574
base/pcap-snoop.c.in
Normal file
574
base/pcap-snoop.c.in
Normal file
|
@ -0,0 +1,574 @@
|
||||||
|
/**
|
||||||
|
pcap-snoop.c
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 1999-2001 RTFM, Inc.
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This package is a SSLv3/TLS protocol analyzer written by Eric
|
||||||
|
Rescorla <ekr@rtfm.com> and licensed by RTFM, Inc.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the 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.
|
||||||
|
|
||||||
|
4. Neither the name of RTFM, Inc. nor the name of Eric Rescorla may
|
||||||
|
be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY ERIC RESCORLA AND RTFM, INC. ``AS IS''
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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.
|
||||||
|
|
||||||
|
$Id: pcap-snoop.c,v 1.14 2002/09/09 21:02:58 ekr Exp $
|
||||||
|
|
||||||
|
|
||||||
|
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <pcap.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pcap-bpf.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#else
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <bittypes.h>
|
||||||
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
#include "network.h"
|
||||||
|
#include <r_common.h>
|
||||||
|
#include <r_time.h>
|
||||||
|
#include "null_analyze.h"
|
||||||
|
#include "ssl_analyze.h"
|
||||||
|
#ifdef ENABLE_RECORD
|
||||||
|
#include "record_analyze.h"
|
||||||
|
#endif
|
||||||
|
#include "pcap_logger.h"
|
||||||
|
|
||||||
|
#ifndef ETHERTYPE_8021Q
|
||||||
|
# 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));
|
||||||
|
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));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
int err_exit(str,num)
|
||||||
|
char *str;
|
||||||
|
int num;
|
||||||
|
{
|
||||||
|
fprintf(stderr,"ERROR: %s\n",str);
|
||||||
|
sig_handler(SIGQUIT);
|
||||||
|
exit(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage()
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
printf("@ssldump_VERSION@\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;
|
||||||
|
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();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(p)
|
||||||
|
pcap_close(p);
|
||||||
|
if(interface_name)
|
||||||
|
free(interface_name);
|
||||||
|
if(filter)
|
||||||
|
free(filter);
|
||||||
|
if(file)
|
||||||
|
free(file);
|
||||||
|
|
||||||
|
exit(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pcap_cb(ptr,hdr,data)
|
||||||
|
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:
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
type=ntohs(e_hdr->ether_type);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
data+=4;
|
||||||
|
len+=4;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
#ifdef __amigaos__
|
||||||
|
case DLT_MIAMI:
|
||||||
|
data+=16;
|
||||||
|
len-=16;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DLT_SLIP:
|
||||||
|
#ifdef DLT_SLIP_BSDOS
|
||||||
|
case DLT_SLIP_BSDOS:
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
||||||
|
data+=16;
|
||||||
|
len-=16;
|
||||||
|
#else
|
||||||
|
data+=24;
|
||||||
|
len-=24;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case DLT_PPP:
|
||||||
|
#ifdef DLT_PPP_BSDOS
|
||||||
|
case DLT_PPP_BSDOS:
|
||||||
|
#endif
|
||||||
|
#ifdef DLT_PPP_SERIAL
|
||||||
|
case DLT_PPP_SERIAL:
|
||||||
|
#endif
|
||||||
|
#ifdef DLT_PPP_ETHER
|
||||||
|
case DLT_PPP_ETHER:
|
||||||
|
#endif
|
||||||
|
#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;
|
||||||
|
#else
|
||||||
|
data+=24;
|
||||||
|
len-=24;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#ifdef DLT_ENC
|
||||||
|
case DLT_ENC:
|
||||||
|
data+=12;
|
||||||
|
len-=12;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef DLT_LINUX_SLL
|
||||||
|
case DLT_LINUX_SLL:
|
||||||
|
data+=16;
|
||||||
|
len-=16;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef DLT_IPNET
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct module_def_ {
|
||||||
|
char *name;
|
||||||
|
proto_mod *mod;
|
||||||
|
} module_def;
|
||||||
|
|
||||||
|
static module_def modules[]={
|
||||||
|
{"SSL",&ssl_mod},
|
||||||
|
{"NULL",&null_mod},
|
||||||
|
#ifdef ENABLE_RECORD
|
||||||
|
{"RECORD",&record_mod},
|
||||||
|
#endif
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int parse_ssl_flag PROTO_LIST((int c));
|
||||||
|
|
||||||
|
int main(argc,argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllimport) char *optarg;
|
||||||
|
__declspec(dllimport) int optind;
|
||||||
|
#else
|
||||||
|
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];
|
||||||
|
|
||||||
|
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");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(tmp_filter,fmt,filter,filter);
|
||||||
|
free(filter);
|
||||||
|
filter = tmp_filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
pcap_if_type=pcap_datalink(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);
|
||||||
|
if(SSL_keylogfile)
|
||||||
|
free(SSL_keylogfile);
|
||||||
|
if(SSL_password)
|
||||||
|
free(SSL_password);
|
||||||
|
if (logger)
|
||||||
|
{
|
||||||
|
logger->vtbl->deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *collapse_args(argc,argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
int i,len=0;
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if(!argc)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
for(i=0;i<argc;i++){
|
||||||
|
len+=strlen(argv[i])+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(ret=(char *)malloc(len)))
|
||||||
|
err_exit("Out of memory",1);
|
||||||
|
|
||||||
|
len=0;
|
||||||
|
for(i=0;i<argc;i++){
|
||||||
|
strcpy(ret+len,argv[i]);
|
||||||
|
len+=strlen(argv[i]);
|
||||||
|
|
||||||
|
if(i!=(argc-1))
|
||||||
|
ret[len++]=' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
111
cmake/modules/FindLIBNET.cmake
Normal file
111
cmake/modules/FindLIBNET.cmake
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
# Copyright 2013 Ettercap Development Team.
|
||||||
|
#
|
||||||
|
# Distributed under GPL license.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Look for the header file
|
||||||
|
find_path(LIBNET_INCLUDE_DIR
|
||||||
|
NAMES libnet.h
|
||||||
|
PATH_SUFFIXES libnet11 libnet-1.1)
|
||||||
|
mark_as_advanced(LIBNET_INCLUDE_DIR)
|
||||||
|
|
||||||
|
#Look for the library
|
||||||
|
find_library(LIBNET_LIBRARY
|
||||||
|
NAMES net libnet
|
||||||
|
PATH_SUFFIXES libnet11 libnet-1.1)
|
||||||
|
mark_as_advanced(LIBNET_LIBRARY)
|
||||||
|
|
||||||
|
# Make sure we've got an include dir.
|
||||||
|
if(NOT LIBNET_INCLUDE_DIR)
|
||||||
|
if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY)
|
||||||
|
message(FATAL_ERROR "Could not find LIBNET include directory.")
|
||||||
|
endif()
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT LIBNET_LIBRARY)
|
||||||
|
if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY)
|
||||||
|
message(FATAL_ERROR "Could not find LIBNET library.")
|
||||||
|
endif()
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#=============================================================
|
||||||
|
# _LIBNET_GET_VERSION
|
||||||
|
# Internal function to parse the version number in libnet.h
|
||||||
|
# _OUT_version = The full version number
|
||||||
|
# _OUT_version_major = The major version number only
|
||||||
|
# _OUT_version_minor = The minor version number only
|
||||||
|
# _libnet_hdr = Header file to parse
|
||||||
|
#=============================================================
|
||||||
|
function(_LIBNET_GET_VERSION _OUT_version _OUT_version_major _OUT_version_minor _libnet_hdr)
|
||||||
|
file(READ ${_libnet_hdr} _contents)
|
||||||
|
if(_contents)
|
||||||
|
string(REGEX REPLACE ".*#define LIBNET_VERSION[ \t]+\"([0-9.a-zA-Z-]+)\".*" "\\1" ${_OUT_version} "${_contents}")
|
||||||
|
|
||||||
|
if(NOT ${_OUT_version} MATCHES "[0-9.a-zA-Z-]+")
|
||||||
|
message(FATAL_ERROR "Version parsing failed for LIBNET_VERSION!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${_OUT_version} ${${_OUT_version}} PARENT_SCOPE)
|
||||||
|
|
||||||
|
string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" ${_OUT_version_major} "${${_OUT_version}}")
|
||||||
|
string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" ${_OUT_version_minor} "${${_OUT_version}}")
|
||||||
|
|
||||||
|
if(NOT ${_OUT_version_major} MATCHES "[0-9]+" OR NOT ${_OUT_version_minor} MATCHES "[0-9]+")
|
||||||
|
message(FATAL_ERROR "Version parsing failed for detailed LIBNET_VERSION!:
|
||||||
|
'${_OUT_version}' '${_OUT_version_major}' '${_OUT_version_minor}'")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${_OUT_version_major} ${${_OUT_version_major}} PARENT_SCOPE)
|
||||||
|
set(${_OUT_version_minor} ${${_OUT_version_minor}} PARENT_SCOPE)
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Include file ${_libnet_hdr} does not exist")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if(LIBNET_FIND_VERSION)
|
||||||
|
set(LIBNET_FAILED_VERSION_CHECK true)
|
||||||
|
_libnet_get_version(LIBNET_VERSION LIBNET_VERSION_MAJOR LIBNET_VERSION_MINOR ${LIBNET_INCLUDE_DIR}/libnet.h)
|
||||||
|
|
||||||
|
if(LIBNET_FIND_VERSION_EXACT)
|
||||||
|
if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION)
|
||||||
|
set(LIBNET_FAILED_VERSION_CHECK false)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION OR
|
||||||
|
LIBNET_VERSION VERSION_GREATER LIBNET_FIND_VERSION)
|
||||||
|
set(LIBNET_FAILED_VERSION_CHECK false)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LIBNET_FAILED_VERSION_CHECK)
|
||||||
|
if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY)
|
||||||
|
if(LIBNET_FIND_VERSION_EXACT)
|
||||||
|
message(FATAL_ERROR "LIBNET version check failed.
|
||||||
|
Version ${LIBNET_VERSION} was found, version ${LIBNET_FIND_VERSION} is needed exactly.")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "LIBNET version check failed.
|
||||||
|
Version ${LIBNET_VERSION} was found, at least version ${LIBNET_FIND_VERSION} is required")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# If the version check fails, exit out of the module here
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#handle the QUIETLY and REQUIRED arguments and set LIBNET_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(LIBNET DEFAULT_MSG LIBNET_LIBRARY LIBNET_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if(LIBNET_FOUND)
|
||||||
|
set(LIBNET_LIBRARY ${LIBNET_LIBRARY})
|
||||||
|
set(LIBNET_INCLUDE_DIR ${LIBNET_INCLUDE_DIR})
|
||||||
|
set(LIBNET_VERSION ${LIBNET_VERSION})
|
||||||
|
set(LIBNET_VERSION_MAJOR ${LIBNET_VERSION_MAJOR})
|
||||||
|
set(LIBNET_VERSION_MINOR ${LIBNET_VERSION_MINOR})
|
||||||
|
endif()
|
86
cmake/modules/FindPCAP.cmake
Normal file
86
cmake/modules/FindPCAP.cmake
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
# - Try to find libpcap include dirs and libraries
|
||||||
|
#
|
||||||
|
# Usage of this module as follows:
|
||||||
|
#
|
||||||
|
# find_package(PCAP)
|
||||||
|
#
|
||||||
|
# Variables used by this module, they can change the default behaviour and need
|
||||||
|
# to be set before calling find_package:
|
||||||
|
#
|
||||||
|
# PCAP_ROOT_DIR Set this variable to the root installation of
|
||||||
|
# libpcap if the module has problems finding the
|
||||||
|
# proper installation path.
|
||||||
|
#
|
||||||
|
# Variables defined by this module:
|
||||||
|
#
|
||||||
|
# PCAP_FOUND System has libpcap, include and library dirs found
|
||||||
|
# PCAP_INCLUDE_DIR The libpcap include directories.
|
||||||
|
# PCAP_LIBRARY The libpcap library (possibly includes a thread
|
||||||
|
# library e.g. required by pf_ring's libpcap)
|
||||||
|
# HAVE_PF_RING If a found version of libpcap supports PF_RING
|
||||||
|
|
||||||
|
find_path(PCAP_ROOT_DIR
|
||||||
|
NAMES include/pcap.h Include/pcap.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(PCAP_INCLUDE_DIR
|
||||||
|
NAMES pcap.h
|
||||||
|
HINTS ${PCAP_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
if ( MSVC AND COMPILER_ARCHITECTURE STREQUAL "x86_64" )
|
||||||
|
set(_pcap_lib_hint_path ${PCAP_ROOT_DIR}/lib/x64)
|
||||||
|
else()
|
||||||
|
set(_pcap_lib_hint_path ${PCAP_ROOT_DIR}/lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_library(PCAP_LIBRARY
|
||||||
|
NAMES pcap wpcap
|
||||||
|
HINTS ${_pcap_lib_hint_path}
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(PCAP DEFAULT_MSG
|
||||||
|
PCAP_LIBRARY
|
||||||
|
PCAP_INCLUDE_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
include(CheckCSourceCompiles)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||||
|
check_c_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES)
|
||||||
|
|
||||||
|
# check if linking against libpcap also needs to link against a thread library
|
||||||
|
if (NOT PCAP_LINKS_SOLO)
|
||||||
|
find_package(Threads)
|
||||||
|
if (THREADS_FOUND)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
check_c_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES)
|
||||||
|
endif ()
|
||||||
|
if (THREADS_FOUND AND PCAP_NEEDS_THREADS)
|
||||||
|
set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
list(REMOVE_DUPLICATES _tmp)
|
||||||
|
set(PCAP_LIBRARY ${_tmp}
|
||||||
|
CACHE STRING "Libraries needed to link against libpcap" FORCE)
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR "Couldn't determine how to link against libpcap")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
string(FIND "${PCAP_LIBRARY}" "wpcap" _pcap_lib_is_wpcap)
|
||||||
|
if ( _pcap_lib_is_wpcap GREATER_EQUAL 0 )
|
||||||
|
set(HAVE_WPCAP TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
|
||||||
|
check_function_exists(pcap_get_pfring_id HAVE_PF_RING)
|
||||||
|
check_function_exists(pcap_dump_open_append HAVE_PCAP_DUMP_OPEN_APPEND)
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES)
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
PCAP_ROOT_DIR
|
||||||
|
PCAP_INCLUDE_DIR
|
||||||
|
PCAP_LIBRARY
|
||||||
|
)
|
Loading…
Reference in a new issue