Loading Makefile +5 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ SYS := $(shell gcc -dumpmachine) ifneq (, $(findstring linux, $(SYS))) LIBS = -lpcap -lm -lrt -ldl -rdynamic INCLUDES = -I. -I../PF_RING/userland/lib FLAGS2 = endif # MAC OS X Loading @@ -18,6 +19,7 @@ endif ifneq (, $(findstring darwin, $(SYS))) LIBS = -lpcap -lm -rdynamic INCLUDES = -I. FLAGS2 = endif # MinGW on Windows Loading @@ -29,6 +31,7 @@ endif ifneq (, $(findstring mingw, $(SYS))) INCLUDES = -I. -Ivs10/include LIBS = -L vs10/lib -lwpcap -lIPHLPAPI FLAGS2 = -march=i686 endif # Cygwin Loading @@ -38,6 +41,7 @@ endif ifneq (, $(findstring cygwin, $(SYS))) INCLUDES = -I. LIBS = -lwpcap FLAGS2 = endif Loading @@ -45,7 +49,7 @@ endif CC = gcc DEFINES = CFLAGS = -g $(INCLUDES) $(DEFINES) -Wall -O3 -Wno-format CFLAGS = -g $(FLAGS2) $(INCLUDES) $(DEFINES) -Wall -O3 -Wno-format .SUFFIXES: .c .cpp # just compile everything in the 'src' directory. Using this technique Loading src/main-conf.c +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "logger.h" #include <ctype.h> #include <limits.h> /*************************************************************************** Loading Loading @@ -799,6 +800,11 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val } else if (EQUALS("version-trace", name)) { fprintf(stderr, "nmap(%s): unsupported\n", name); exit(1); } else if (EQUALS("wait", name)) { if (EQUALS("forever", value)) masscan->wait = INT_MAX; else masscan->wait = (unsigned)parseInt(value); } else if (EQUALS("webxml", name)) { masscan_set_parameter(masscan, "stylesheet", "http://nmap.org/svn/docs/nmap.xsl"); } else { Loading src/main.c +60 −7 Original line number Diff line number Diff line Loading @@ -17,8 +17,11 @@ #include "main-status.h" /* printf() regular status updates */ #include "main-throttle.h" /* rate limit */ #include "main-dedup.h" /* ignore duplicate responses */ #include "proto-arp.h" /* for responding to ARP requests */ #include "syn-cookie.h" /* for SYN-cookies on send */ #include "output.h" /* for outputing results */ //#include "xring.h" /* producer/consumer ring buffer */ #include "rte-ring.h" /* producer/consumer ring buffer */ #include "pixie-timer.h" /* portable time functions */ #include "pixie-threads.h" /* portable threads */ Loading @@ -26,6 +29,7 @@ #include <string.h> #include <time.h> #include <stdlib.h> #include <signal.h> Loading Loading @@ -57,6 +61,8 @@ transmit_thread(void *v) /*aka. scanning_thread() */ unsigned packet_trace = masscan->nmap.packet_trace; double timestamp_start; unsigned *picker; struct rte_ring *pending_packets = masscan->pending_packets; struct Adapter *adapter = masscan->adapter; LOG(1, "xmit: starting transmit thread...\n"); Loading Loading @@ -114,7 +120,7 @@ transmit_thread(void *v) /*aka. scanning_thread() */ /* Send the probe */ rawsock_send_probe( masscan->adapter, adapter, ip, port, syn_hash(ip, port), Loading @@ -133,6 +139,17 @@ transmit_thread(void *v) /*aka. scanning_thread() */ if ((i & status.timer) == status.timer) status_print(&status, i, m); } /* end of batch */ /* Transmit packets from other thread */ for (;;) { unsigned char *p; int err; err = rte_ring_sc_dequeue(pending_packets, &p); if (err) break; rawsock_send_packet(adapter, p + sizeof(size_t), (unsigned)*(size_t*)p, 0); } /* If the user pressed <ctrl-c>, then we need to exit. but, in case Loading @@ -142,7 +159,7 @@ transmit_thread(void *v) /*aka. scanning_thread() */ masscan->resume.seed = seed; masscan->resume.index = i; masscan_save_state(masscan); fprintf(stderr, "waiting 10 seconds to exit...\n"); fprintf(stderr, "waiting %u seconds to exit...\n", masscan->wait); fflush(stderr); control_c_pressed = 0; /* a second ^C press exits faster */ break; Loading @@ -157,9 +174,21 @@ transmit_thread(void *v) /*aka. scanning_thread() */ */ { unsigned j; for (j=0; j<10 && !control_c_pressed; j++) { for (j=0; j<masscan->wait && !control_c_pressed; j++) { unsigned k; status_print(&status, i++, m); pixie_usleep(1000000); for (k=0; k<100; k++) { for (;;) { unsigned char *p; int err; err = rte_ring_sc_dequeue(pending_packets, &p); if (err) break; rawsock_send_packet(adapter, p + sizeof(size_t), (unsigned)*(size_t*)p, 0); } pixie_usleep(1000); } } fprintf(stderr, " \r"); } Loading Loading @@ -243,7 +272,11 @@ receive_thread(struct Masscan *masscan, /* OOPS: handle arp instead */ if (parsed.found == FOUND_ARP) { LOG(2, "found arp 0x%08x\n", parsed.ip_dst); arp_response(masscan->adapter, adapter_ip, adapter_mac, px, length); arp_response( adapter_ip, adapter_mac, px, length, masscan->packet_buffers, masscan->pending_packets); continue; } Loading Loading @@ -425,6 +458,22 @@ main_scan(struct Masscan *masscan) fprintf(stderr, " -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth\n"); fprintf(stderr, "Initiating SYN Stealth Scan\n"); /* * Allocate packet buffers for sending */ masscan->packet_buffers = rte_ring_create(256, RING_F_SP_ENQ|RING_F_SC_DEQ); masscan->pending_packets = rte_ring_create(256, RING_F_SP_ENQ|RING_F_SC_DEQ); { unsigned i; for (i=0; i<256; i++) { char *pkt = (char*)malloc(1600); err = rte_ring_sp_enqueue(masscan->packet_buffers, pkt); if (err) { LOG(0, "packet_buffers: enqueue: error %d\n", err); } } } /* * Start the scanning thread. Loading Loading @@ -460,6 +509,7 @@ int main(int argc, char *argv[]) * Initialize those defaults that aren't zero */ memset(masscan, 0, sizeof(*masscan)); masscan->wait = 10; /* how long to wait for responses when done */ masscan->max_rate = 100.0; /* max rate = hundred packets-per-second */ masscan->adapter_port = 0x10000; /* value not set */ strcpy_s( masscan->rotate_directory, Loading Loading @@ -540,13 +590,16 @@ int main(int argc, char *argv[]) x += tcpkt_selftest(); x += ranges_selftest(); x += pixie_time_selftest(); //x += xring_selftest(); x += rte_ring_selftest(); if (x != 0) { /* one of the selftests failed, so return error */ fprintf(stderr, "selftest: failed :( \n"); fprintf(stderr, "regression test: failed :( \n"); return 1; } else { fprintf(stderr, "selftest: success!\n"); fprintf(stderr, "regression test: success!\n"); return 0; } } Loading src/masscan.h +8 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,11 @@ struct Masscan unsigned is_pfring:1; unsigned is_sendq:1; /** * Wait forever for responses, instead of the default 10 seconds */ unsigned wait; struct { uint64_t seed; Loading Loading @@ -141,6 +146,9 @@ struct Masscan } nmap; char rotate_directory[256]; struct rte_ring *packet_buffers; struct rte_ring *pending_packets; }; Loading src/pixie-threads.h +28 −0 Original line number Diff line number Diff line #ifndef PORT_THREADS_H #define PORT_THREADS_H #include <stdio.h> #include <stdint.h> #if defined(_MSC_VER) #include <intrin.h> #endif size_t pixie_begin_thread(void (*worker_thread)(void*), unsigned flags, void *worker_data); void pixie_locked_subtract_u32(unsigned *lhs, unsigned rhs); #if defined(_MSC_VER) #define pixie_locked_add_u32(dst, src) _InterlockedExchangeAdd((volatile long*)(dst), (src)) #define pixie_locked_CAS32(dst, src, expected) (_InterlockedCompareExchange((volatile long*)dst, src, expected) == (expected)) #define pixie_locked_CAS64(dst, src, expected) (_InterlockedCompareExchange64((volatile long long*)dst, src, expected) == (expected)) #define rte_atomic32_cmpset(dst, exp, src) (_InterlockedCompareExchange((volatile long *)dst, (long)src, (long)exp)==(long)(exp)) #elif defined(__GNUC__) #define pixie_locked_add_u32(dst, src) __sync_add_and_fetch((volatile int*)(dst), (int)(src)); #define rte_atomic32_cmpset(dst, expected, src) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src) #define pixie_locked_CAS32(dst, src, expected) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src); #define pixie_locked_CAS64(dst, src, expected) __sync_bool_compare_and_swap((volatile long long int*)(dst),(long long int)expected,(long long int)src); #define rte_wmb() asm volatile("sfence;" : : : "memory") #define rte_rmb() asm volatile("lfence;" : : : "memory") #define rte_pause() asm volatile ("pause") #else unsigned pixie_locked_add_u32(volatile unsigned *lhs, unsigned rhs); int pixie_locked_CAS32(volatile unsigned *dst, unsigned src, unsigned expected); int pixie_locked_CAS64(volatile uint64_t *dst, uint64_t src, uint64_t expected); #endif #endif Loading
Makefile +5 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ SYS := $(shell gcc -dumpmachine) ifneq (, $(findstring linux, $(SYS))) LIBS = -lpcap -lm -lrt -ldl -rdynamic INCLUDES = -I. -I../PF_RING/userland/lib FLAGS2 = endif # MAC OS X Loading @@ -18,6 +19,7 @@ endif ifneq (, $(findstring darwin, $(SYS))) LIBS = -lpcap -lm -rdynamic INCLUDES = -I. FLAGS2 = endif # MinGW on Windows Loading @@ -29,6 +31,7 @@ endif ifneq (, $(findstring mingw, $(SYS))) INCLUDES = -I. -Ivs10/include LIBS = -L vs10/lib -lwpcap -lIPHLPAPI FLAGS2 = -march=i686 endif # Cygwin Loading @@ -38,6 +41,7 @@ endif ifneq (, $(findstring cygwin, $(SYS))) INCLUDES = -I. LIBS = -lwpcap FLAGS2 = endif Loading @@ -45,7 +49,7 @@ endif CC = gcc DEFINES = CFLAGS = -g $(INCLUDES) $(DEFINES) -Wall -O3 -Wno-format CFLAGS = -g $(FLAGS2) $(INCLUDES) $(DEFINES) -Wall -O3 -Wno-format .SUFFIXES: .c .cpp # just compile everything in the 'src' directory. Using this technique Loading
src/main-conf.c +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "logger.h" #include <ctype.h> #include <limits.h> /*************************************************************************** Loading Loading @@ -799,6 +800,11 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val } else if (EQUALS("version-trace", name)) { fprintf(stderr, "nmap(%s): unsupported\n", name); exit(1); } else if (EQUALS("wait", name)) { if (EQUALS("forever", value)) masscan->wait = INT_MAX; else masscan->wait = (unsigned)parseInt(value); } else if (EQUALS("webxml", name)) { masscan_set_parameter(masscan, "stylesheet", "http://nmap.org/svn/docs/nmap.xsl"); } else { Loading
src/main.c +60 −7 Original line number Diff line number Diff line Loading @@ -17,8 +17,11 @@ #include "main-status.h" /* printf() regular status updates */ #include "main-throttle.h" /* rate limit */ #include "main-dedup.h" /* ignore duplicate responses */ #include "proto-arp.h" /* for responding to ARP requests */ #include "syn-cookie.h" /* for SYN-cookies on send */ #include "output.h" /* for outputing results */ //#include "xring.h" /* producer/consumer ring buffer */ #include "rte-ring.h" /* producer/consumer ring buffer */ #include "pixie-timer.h" /* portable time functions */ #include "pixie-threads.h" /* portable threads */ Loading @@ -26,6 +29,7 @@ #include <string.h> #include <time.h> #include <stdlib.h> #include <signal.h> Loading Loading @@ -57,6 +61,8 @@ transmit_thread(void *v) /*aka. scanning_thread() */ unsigned packet_trace = masscan->nmap.packet_trace; double timestamp_start; unsigned *picker; struct rte_ring *pending_packets = masscan->pending_packets; struct Adapter *adapter = masscan->adapter; LOG(1, "xmit: starting transmit thread...\n"); Loading Loading @@ -114,7 +120,7 @@ transmit_thread(void *v) /*aka. scanning_thread() */ /* Send the probe */ rawsock_send_probe( masscan->adapter, adapter, ip, port, syn_hash(ip, port), Loading @@ -133,6 +139,17 @@ transmit_thread(void *v) /*aka. scanning_thread() */ if ((i & status.timer) == status.timer) status_print(&status, i, m); } /* end of batch */ /* Transmit packets from other thread */ for (;;) { unsigned char *p; int err; err = rte_ring_sc_dequeue(pending_packets, &p); if (err) break; rawsock_send_packet(adapter, p + sizeof(size_t), (unsigned)*(size_t*)p, 0); } /* If the user pressed <ctrl-c>, then we need to exit. but, in case Loading @@ -142,7 +159,7 @@ transmit_thread(void *v) /*aka. scanning_thread() */ masscan->resume.seed = seed; masscan->resume.index = i; masscan_save_state(masscan); fprintf(stderr, "waiting 10 seconds to exit...\n"); fprintf(stderr, "waiting %u seconds to exit...\n", masscan->wait); fflush(stderr); control_c_pressed = 0; /* a second ^C press exits faster */ break; Loading @@ -157,9 +174,21 @@ transmit_thread(void *v) /*aka. scanning_thread() */ */ { unsigned j; for (j=0; j<10 && !control_c_pressed; j++) { for (j=0; j<masscan->wait && !control_c_pressed; j++) { unsigned k; status_print(&status, i++, m); pixie_usleep(1000000); for (k=0; k<100; k++) { for (;;) { unsigned char *p; int err; err = rte_ring_sc_dequeue(pending_packets, &p); if (err) break; rawsock_send_packet(adapter, p + sizeof(size_t), (unsigned)*(size_t*)p, 0); } pixie_usleep(1000); } } fprintf(stderr, " \r"); } Loading Loading @@ -243,7 +272,11 @@ receive_thread(struct Masscan *masscan, /* OOPS: handle arp instead */ if (parsed.found == FOUND_ARP) { LOG(2, "found arp 0x%08x\n", parsed.ip_dst); arp_response(masscan->adapter, adapter_ip, adapter_mac, px, length); arp_response( adapter_ip, adapter_mac, px, length, masscan->packet_buffers, masscan->pending_packets); continue; } Loading Loading @@ -425,6 +458,22 @@ main_scan(struct Masscan *masscan) fprintf(stderr, " -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth\n"); fprintf(stderr, "Initiating SYN Stealth Scan\n"); /* * Allocate packet buffers for sending */ masscan->packet_buffers = rte_ring_create(256, RING_F_SP_ENQ|RING_F_SC_DEQ); masscan->pending_packets = rte_ring_create(256, RING_F_SP_ENQ|RING_F_SC_DEQ); { unsigned i; for (i=0; i<256; i++) { char *pkt = (char*)malloc(1600); err = rte_ring_sp_enqueue(masscan->packet_buffers, pkt); if (err) { LOG(0, "packet_buffers: enqueue: error %d\n", err); } } } /* * Start the scanning thread. Loading Loading @@ -460,6 +509,7 @@ int main(int argc, char *argv[]) * Initialize those defaults that aren't zero */ memset(masscan, 0, sizeof(*masscan)); masscan->wait = 10; /* how long to wait for responses when done */ masscan->max_rate = 100.0; /* max rate = hundred packets-per-second */ masscan->adapter_port = 0x10000; /* value not set */ strcpy_s( masscan->rotate_directory, Loading Loading @@ -540,13 +590,16 @@ int main(int argc, char *argv[]) x += tcpkt_selftest(); x += ranges_selftest(); x += pixie_time_selftest(); //x += xring_selftest(); x += rte_ring_selftest(); if (x != 0) { /* one of the selftests failed, so return error */ fprintf(stderr, "selftest: failed :( \n"); fprintf(stderr, "regression test: failed :( \n"); return 1; } else { fprintf(stderr, "selftest: success!\n"); fprintf(stderr, "regression test: success!\n"); return 0; } } Loading
src/masscan.h +8 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,11 @@ struct Masscan unsigned is_pfring:1; unsigned is_sendq:1; /** * Wait forever for responses, instead of the default 10 seconds */ unsigned wait; struct { uint64_t seed; Loading Loading @@ -141,6 +146,9 @@ struct Masscan } nmap; char rotate_directory[256]; struct rte_ring *packet_buffers; struct rte_ring *pending_packets; }; Loading
src/pixie-threads.h +28 −0 Original line number Diff line number Diff line #ifndef PORT_THREADS_H #define PORT_THREADS_H #include <stdio.h> #include <stdint.h> #if defined(_MSC_VER) #include <intrin.h> #endif size_t pixie_begin_thread(void (*worker_thread)(void*), unsigned flags, void *worker_data); void pixie_locked_subtract_u32(unsigned *lhs, unsigned rhs); #if defined(_MSC_VER) #define pixie_locked_add_u32(dst, src) _InterlockedExchangeAdd((volatile long*)(dst), (src)) #define pixie_locked_CAS32(dst, src, expected) (_InterlockedCompareExchange((volatile long*)dst, src, expected) == (expected)) #define pixie_locked_CAS64(dst, src, expected) (_InterlockedCompareExchange64((volatile long long*)dst, src, expected) == (expected)) #define rte_atomic32_cmpset(dst, exp, src) (_InterlockedCompareExchange((volatile long *)dst, (long)src, (long)exp)==(long)(exp)) #elif defined(__GNUC__) #define pixie_locked_add_u32(dst, src) __sync_add_and_fetch((volatile int*)(dst), (int)(src)); #define rte_atomic32_cmpset(dst, expected, src) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src) #define pixie_locked_CAS32(dst, src, expected) __sync_bool_compare_and_swap((volatile int*)(dst),(int)expected,(int)src); #define pixie_locked_CAS64(dst, src, expected) __sync_bool_compare_and_swap((volatile long long int*)(dst),(long long int)expected,(long long int)src); #define rte_wmb() asm volatile("sfence;" : : : "memory") #define rte_rmb() asm volatile("lfence;" : : : "memory") #define rte_pause() asm volatile ("pause") #else unsigned pixie_locked_add_u32(volatile unsigned *lhs, unsigned rhs); int pixie_locked_CAS32(volatile unsigned *dst, unsigned src, unsigned expected); int pixie_locked_CAS64(volatile uint64_t *dst, uint64_t src, uint64_t expected); #endif #endif