From 796ee67eae636547678366fb9147a2d5d666668e Mon Sep 17 00:00:00 2001 From: Robert David Graham Date: Sun, 11 Jun 2017 20:14:44 -0400 Subject: [PATCH] cleanup --- src/in-report.c | 2 +- src/main-initadapter.c | 3 + src/main.c | 5 +- src/output.c | 10 +-- src/pixie-threads.c | 2 +- src/rawsock-pcap.c | 8 ++- src/rawsock-pcap.h | 151 +++++++++++++++++++++++++++-------------- src/smack1.c | 4 +- 8 files changed, 121 insertions(+), 64 deletions(-) diff --git a/src/in-report.c b/src/in-report.c index db0c131..01daf5e 100644 --- a/src/in-report.c +++ b/src/in-report.c @@ -272,7 +272,7 @@ struct Names { }; static struct SMACK *global_xnames; -void +static void xname_init(void) { unsigned i; diff --git a/src/main-initadapter.c b/src/main-initadapter.c index 0e97b9c..d38fd25 100644 --- a/src/main-initadapter.c +++ b/src/main-initadapter.c @@ -25,6 +25,9 @@ masscan_initialize_adapter( char *ifname; char ifname2[256]; unsigned adapter_ip = 0; + + if (masscan == NULL) + return -1; LOG(1, "initializing adapter\n"); diff --git a/src/main.c b/src/main.c index b899141..774031f 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,7 @@ #include "output.h" /* for outputing results */ #include "rte-ring.h" /* producer/consumer ring buffer */ #include "rawsock-pcapfile.h" /* for saving pcap files w/ raw packets */ +#include "rawsock-pcap.h" /* dynamically load libpcap library */ #include "smack.h" /* Aho-corasick state-machine pattern-matcher */ #include "pixie-timer.h" /* portable time functions */ #include "pixie-threads.h" /* portable threads */ @@ -1440,7 +1441,6 @@ main_scan(struct Masscan *masscan) -void pcap_init(void); /*************************************************************************** ***************************************************************************/ @@ -1519,7 +1519,8 @@ int main(int argc, char *argv[]) /* We need to do a separate "raw socket" initialization step. This is * for Windows and PF_RING. */ - pcap_init(); + if (pcap_init() != 0) + LOG(2, "libpcap: failed to load\n"); rawsock_init(); /* Init some protocol parser data structures */ diff --git a/src/output.c b/src/output.c index fd4772b..b82c042 100644 --- a/src/output.c +++ b/src/output.c @@ -308,14 +308,15 @@ duplicate_string(const char *str) length = strlen(str); /* Allocate memory for the string */ - result = (char*)malloc(length + 1); + result = malloc(length + 1); if (result == 0) { fprintf(stderr, "output: out of memory error\n"); exit(1); } /* Copy the string */ - memcpy(result, str, length+1); + if (str) + memcpy(result, str, length+1); result[length] = '\0'; return result; @@ -512,7 +513,7 @@ output_do_rotate(struct Output *out, int is_closing) int err; /* Don't do anything if there is no file */ - if (out->fp == NULL) + if (out == NULL || out->fp == NULL) return NULL; /* Make sure that all output has been flushed to the file */ @@ -537,7 +538,7 @@ output_do_rotate(struct Output *out, int is_closing) + strlen(filename) + 1 /* - */ + 1; /* nul */ - new_filename = (char*)malloc(new_filename_size); + new_filename = malloc(new_filename_size); if (new_filename == NULL) { LOG(0, "rotate: out of memory error\n"); return out->fp; @@ -550,6 +551,7 @@ output_do_rotate(struct Output *out, int is_closing) err = localtime_s(&tm, &out->rotate.last); } if (err != 0) { + free(new_filename); perror("gmtime(): file rotation ended"); return out->fp; } diff --git a/src/pixie-threads.c b/src/pixie-threads.c index d6cf51f..997efb6 100644 --- a/src/pixie-threads.c +++ b/src/pixie-threads.c @@ -184,7 +184,7 @@ pixie_begin_thread( typedef void *(*PTHREADFUNC)(void*); pthread_t thread_id = 0; - (size_t)pthread_create( + pthread_create( &thread_id, NULL, (PTHREADFUNC)worker_thread, diff --git a/src/rawsock-pcap.c b/src/rawsock-pcap.c index cf66f3b..ac83df1 100644 --- a/src/rawsock-pcap.c +++ b/src/rawsock-pcap.c @@ -339,7 +339,7 @@ static int null_PCAP_SENDQUEUE_QUEUE(pcap_send_queue *queue, * be used to process offline content, and to provide more helpful * messages to people who don't realize they need to install PCAP. */ -void pcap_init(void) +int pcap_init(void) { struct PcapFunctions *pl = &PCAP; #ifdef WIN32 @@ -475,8 +475,10 @@ pl->func_err=0, pl->datalink = null_##PCAP_DATALINK; pl->can_transmit = null_CAN_TRANSMIT; if (!pl->func_err) - pl->is_available = 1; + pl->is_available = 1; else - pl->is_available = 0; + pl->is_available = 0; + + return 0; } diff --git a/src/rawsock-pcap.h b/src/rawsock-pcap.h index 0a5180b..c848237 100644 --- a/src/rawsock-pcap.h +++ b/src/rawsock-pcap.h @@ -1,26 +1,54 @@ +/* + Dynamically load libpcap at runtime + + This library optionally loads the 'libpcap' library at runtime, rather + than statically linked at compile time. The advantage of this is that + the user can build this project with no dependencies -- although they + may require this dependency in order to run the program. + + As of 2017, libpcap shared libraries are standard on major Linux + distributions (Debian, Readhat), FreeBSD, OpenBSD, and macOS. On + Windows, "winpcap" must be downloaded. +*/ #ifndef RAWSOCK_PCAP_H #define RAWSOCK_PCAP_H -#include - -struct pcap_timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ +#include + + + +/* Including the right ".h" file to define "timeval" is difficult, so instead + * so instead we are simply going to define our own structure. This should + * match the binary definition within the operating system + */ +struct pcap_timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ }; +/* Forward reference of opaque 'pcap_t' structure */ struct pcap; typedef struct pcap pcap_t; + +/* Forward reference of opaque 'pcap_if_t' structure */ +struct pcap_if; typedef struct pcap_if pcap_if_t; +/* How many bytes to reserve for error messages. This is the number specified + * in libpcap, smaller numbers can crash */ enum { PCAP_ERRBUF_SIZE=256, }; +/* used in pcap_setdirection() */ typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT + PCAP_D_INOUT = 0, + PCAP_D_IN = 1, + PCAP_D_OUT = 2, } pcap_direction_t; +/* The packet header for capturing packets. Apple macOS inexplicably adds + * an extra comment-field onto the end of this, so the definition needs + * to be careful to match the real definition */ struct pcap_pkthdr { struct pcap_timeval ts; unsigned caplen; @@ -30,28 +58,31 @@ struct pcap_pkthdr { #endif }; -typedef void (*PCAP_HANDLE_PACKET)(unsigned char *v_seap, const struct pcap_pkthdr *framehdr, const unsigned char *buf); -typedef void (*PCAP_CLOSE)(void *hPcap); -typedef unsigned (*PCAP_DATALINK)(void *hPcap); -typedef unsigned (*PCAP_DISPATCH)(void *hPcap, unsigned how_many_packets, PCAP_HANDLE_PACKET handler, void *handle_data); -typedef int (*PCAP_FINDALLDEVS)(pcap_if_t **alldevs, char *errbuf); +/* + * This block is for function declarations. Consult the libpcap + * documentation for what these functions really mean + */ +typedef void (*PCAP_HANDLE_PACKET)(unsigned char *v_seap, const struct pcap_pkthdr *framehdr, const unsigned char *buf); +typedef void (*PCAP_CLOSE)(void *hPcap); +typedef unsigned (*PCAP_DATALINK)(void *hPcap); +typedef unsigned (*PCAP_DISPATCH)(void *hPcap, unsigned how_many_packets, PCAP_HANDLE_PACKET handler, void *handle_data); +typedef int (*PCAP_FINDALLDEVS)(pcap_if_t **alldevs, char *errbuf); typedef const char *(*PCAP_LIB_VERSION)(void); -typedef char *(*PCAP_LOOKUPDEV)(char *errbuf); -typedef int (*PCAP_MAJOR_VERSION)(void *p); -typedef int (*PCAP_MINOR_VERSION)(void *p); -typedef void * (*PCAP_OPEN_LIVE)(const char *devicename, unsigned snap_length, unsigned is_promiscuous, unsigned read_timeout, char *errbuf); -typedef void (*PCAP_FREEALLDEVS)(pcap_if_t *alldevs); -typedef void * (*PCAP_GET_AIRPCAP_HANDLE)(void *p); -typedef unsigned (*AIRPCAP_SET_DEVICE_CHANNEL)(void *p, unsigned channel); -typedef unsigned (*CAN_TRANSMIT)(const char *devicename); - -typedef pcap_t *(*PCAP_OPEN_OFFLINE)(const char *fname, char *errbuf); -typedef int (*PCAP_SENDPACKET)(pcap_t *p, const unsigned char *buf, int size); +typedef char * (*PCAP_LOOKUPDEV)(char *errbuf); +typedef int (*PCAP_MAJOR_VERSION)(void *p); +typedef int (*PCAP_MINOR_VERSION)(void *p); +typedef void * (*PCAP_OPEN_LIVE)(const char *devicename, unsigned snap_length, unsigned is_promiscuous, unsigned read_timeout, char *errbuf); +typedef void (*PCAP_FREEALLDEVS)(pcap_if_t *alldevs); +typedef void * (*PCAP_GET_AIRPCAP_HANDLE)(void *p); +typedef unsigned (*AIRPCAP_SET_DEVICE_CHANNEL)(void *p, unsigned channel); +typedef unsigned (*CAN_TRANSMIT)(const char *devicename); +typedef pcap_t * (*PCAP_OPEN_OFFLINE)(const char *fname, char *errbuf); +typedef int (*PCAP_SENDPACKET)(pcap_t *p, const unsigned char *buf, int size); typedef const unsigned char *(*PCAP_NEXT)(pcap_t *p, struct pcap_pkthdr *h); -typedef int (*PCAP_SETDIRECTION)(pcap_t *, pcap_direction_t); +typedef int (*PCAP_SETDIRECTION)(pcap_t *, pcap_direction_t); typedef const char *(*PCAP_DATALINK_VAL_TO_NAME)(int dlt); -typedef void (*PCAP_PERROR)(pcap_t *p, char *prefix); +typedef void (*PCAP_PERROR)(pcap_t *p, char *prefix); typedef const char *(*PCAP_DEV_NAME)(const pcap_if_t *dev); typedef const char *(*PCAP_DEV_DESCRIPTION)(const pcap_if_t *dev); typedef const pcap_if_t *(*PCAP_DEV_NEXT)(const pcap_if_t *dev); @@ -80,42 +111,60 @@ struct PcapFunctions { unsigned status; unsigned errcode; - PCAP_CLOSE close; - PCAP_DATALINK datalink; - PCAP_DISPATCH dispatch; - PCAP_FINDALLDEVS findalldevs; - PCAP_FREEALLDEVS freealldevs; - PCAP_LOOKUPDEV lookupdev; - PCAP_LIB_VERSION lib_version; - PCAP_MAJOR_VERSION major_version; - PCAP_MINOR_VERSION minor_version; - PCAP_OPEN_LIVE open_live; + PCAP_CLOSE close; + PCAP_DATALINK datalink; + PCAP_DISPATCH dispatch; + PCAP_FINDALLDEVS findalldevs; + PCAP_FREEALLDEVS freealldevs; + PCAP_LOOKUPDEV lookupdev; + PCAP_LIB_VERSION lib_version; + PCAP_MAJOR_VERSION major_version; + PCAP_MINOR_VERSION minor_version; + PCAP_OPEN_LIVE open_live; PCAP_GET_AIRPCAP_HANDLE get_airpcap_handle; AIRPCAP_SET_DEVICE_CHANNEL airpcap_set_device_channel; //AIRPCAP_SET_FCS_PRESENCE airpcap_set_fcs_presence; //BOOL AirpcapSetFcsPresence(PAirpcapHandle AdapterHandle, BOOL IsFcsPresent); - CAN_TRANSMIT can_transmit; + CAN_TRANSMIT can_transmit; - PCAP_OPEN_OFFLINE open_offline; - PCAP_SENDPACKET sendpacket; - PCAP_NEXT next; - PCAP_SETDIRECTION setdirection; + PCAP_OPEN_OFFLINE open_offline; + PCAP_SENDPACKET sendpacket; + PCAP_NEXT next; + PCAP_SETDIRECTION setdirection; PCAP_DATALINK_VAL_TO_NAME datalink_val_to_name; - PCAP_PERROR perror; + PCAP_PERROR perror; - PCAP_DEV_NAME dev_name; - PCAP_DEV_DESCRIPTION dev_description; - PCAP_DEV_NEXT dev_next; - - PCAP_SENDQUEUE_ALLOC sendqueue_alloc; - PCAP_SENDQUEUE_TRANSMIT sendqueue_transmit; - PCAP_SENDQUEUE_DESTROY sendqueue_destroy; - PCAP_SENDQUEUE_QUEUE sendqueue_queue; + /* Accessor functions for opaque data structure, don't really + * exist in libpcap */ + PCAP_DEV_NAME dev_name; + PCAP_DEV_DESCRIPTION dev_description; + PCAP_DEV_NEXT dev_next; + + /* Windows-only functions */ + PCAP_SENDQUEUE_ALLOC sendqueue_alloc; + PCAP_SENDQUEUE_TRANSMIT sendqueue_transmit; + PCAP_SENDQUEUE_DESTROY sendqueue_destroy; + PCAP_SENDQUEUE_QUEUE sendqueue_queue; }; +/** + * This is global structure containing all the libpcap function pointers. + * use in the form "PCAP.functionname()" rather than "pcap_functioname()". + */ extern struct PcapFunctions PCAP; -void pcap_init(void); + +/** + * Dynamically loads the shared library (libpcap.so, libpcap.dynlib, + * or libpcap.dll. Call this during program startup like main() in order + * to load the libraries. Not thread safe, so call from the startup + * thread, but not within threads. + * @return + * 0 on success or + * -1 on failure + */ +int pcap_init(void); + #endif diff --git a/src/smack1.c b/src/smack1.c index 1c0e5e0..d7baa74 100644 --- a/src/smack1.c +++ b/src/smack1.c @@ -966,12 +966,12 @@ smack_stage4_make_final_table(struct SMACK *smack) * Allocate table: * rows*columns */ - table = (transition_t*)malloc(sizeof(transition_t*) * row_count * column_count); + table = malloc(sizeof(transition_t) * row_count * column_count); if (table == NULL) { fprintf(stderr, "%s: out of memory error\n", "smack"); exit(1); } - memset(table, 0, sizeof(transition_t*) * row_count * column_count); + memset(table, 0, sizeof(transition_t) * row_count * column_count); for (row=0; row