mirror of
https://github.com/adulau/ssldump.git
synced 2024-12-22 07:55:57 +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