2323#include "icmp.h"
2424#include "banner.h"
2525
26+ // for convenience
27+ #ifndef u_int
28+ typedef unsigned int u_int ;
29+ #endif
30+
31+ #if __has_builtin (__builtin_expect )
32+ // "unlikely"
33+ #define unl (expr ) __builtin_expect((expr), 0)
34+ #else
35+ #define unl (expr ) expr
36+ #endif
37+
38+ enum {
39+ FULL_TCP_SIZE = FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE ,
40+ FULL_UDP_SIZE = FRAME_ETH_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE ,
41+ FULL_ICMP_SIZE = FRAME_ETH_SIZE + FRAME_IP_SIZE + ICMP_HEADER_SIZE ,
42+ };
43+
44+ // status_bits:
2645enum {
2746 SEND_FINISHED = (1 << 0 ),
2847 ERROR_SEND_THREAD = (1 << 1 ),
@@ -33,8 +52,8 @@ static uint8_t source_addr[16];
3352static int source_port ;
3453//
3554static struct ports ports ;
36- static unsigned int max_rate ;
37- static int show_closed , banners ;
55+ static u_int max_rate ;
56+ static bool show_closed , banners ;
3857static uint8_t ip_type ;
3958//
4059static FILE * outfile ;
@@ -50,17 +69,17 @@ static void *send_thread_udp(void *unused);
5069static void * send_thread_icmp (void * unused );
5170
5271static void * recv_thread (void * unused );
53- static void recv_handler (uint64_t ts , int len , const uint8_t * packet );
54- static void recv_handler_tcp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr );
55- static void recv_handler_udp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr );
56- static void recv_handler_icmp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr );
72+ static void recv_handler (uint64_t ts , u_int len , const uint8_t * packet );
73+ static void recv_handler_tcp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr );
74+ static void recv_handler_udp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr );
75+ static void recv_handler_icmp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr );
5776
5877#if ATOMIC_INT_LOCK_FREE != 2
59- #warning Non lock-free atomic types will severely affect performance.
78+ #warning Non lock-free atomic types will probably reduce performance.
6079#endif
6180
6281#define RATE_CONTROL () do { \
63- if(atomic_fetch_add(&pkts_sent, 1) >= max_rate) { \
82+ if(unl( atomic_fetch_add(&pkts_sent, 1) >= max_rate) ) { \
6483 do usleep(1000); while(atomic_load(&pkts_sent) != 0); \
6584 } \
6685 } while(0)
@@ -70,7 +89,7 @@ static void recv_handler_icmp(uint64_t ts, int len, const uint8_t *packet, const
7089void scan_set_general (const struct ports * _ports , int _max_rate , int _show_closed , int _banners )
7190{
7291 memcpy (& ports , _ports , sizeof (struct ports ));
73- max_rate = _max_rate < 0 ? UINT_MAX : _max_rate - 1 ;
92+ max_rate = _max_rate <= 0 ? UINT_MAX : ( _max_rate - 1 ) ;
7493 show_closed = _show_closed ;
7594 banners = _banners ;
7695}
@@ -139,13 +158,13 @@ int scan_main(const char *interface, int quiet)
139158 // Stats & progress watching
140159 unsigned char cur_status = 0 ;
141160 while (1 ) {
142- unsigned int cur_sent , cur_recv ;
161+ u_int cur_sent , cur_recv ;
143162 // (used for rate control)
144163 cur_sent = atomic_exchange (& pkts_sent , 0 );
145164 cur_recv = atomic_exchange (& pkts_recv , 0 );
146165 if (!quiet ) {
147166 float progress = target_gen_progress ();
148- unsigned int tcp_sent = 0 ;
167+ u_int tcp_sent = 0 ;
149168 char tmp [10 ] = {'?' , '?' , '?' , 0 };
150169 if (progress >= 0.0f )
151170 snprintf (tmp , sizeof (tmp ), "%3d" , (int ) (progress * 100 ));
@@ -178,8 +197,8 @@ int scan_main(const char *interface, int quiet)
178197 if (banners && ip_type == IP_TYPE_TCP )
179198 scan_responder_finish ();
180199 if (!quiet && !cur_status ) {
181- unsigned int cur_recv = atomic_exchange (& pkts_recv , 0 );
182- unsigned int tcp_sent = 0 ;
200+ u_int cur_recv = atomic_exchange (& pkts_recv , 0 );
201+ u_int tcp_sent = 0 ;
183202 if (banners && ip_type == IP_TYPE_TCP ) {
184203 scan_responder_stats (& tcp_sent );
185204 fprintf (stderr , "rcv:%5u tcp:%5u\n" , cur_recv , tcp_sent );
@@ -200,7 +219,7 @@ int scan_main(const char *interface, int quiet)
200219 goto ret ;
201220}
202221
203- static bool calc_bps (char * dst , unsigned int dstsize , uint64_t m1 , uint64_t m2 )
222+ static bool calc_bps (char * dst , u_int dstsize , uint64_t m1 , uint64_t m2 )
204223{
205224 uint64_t bps ;
206225#if __has_builtin (__builtin_mul_overflow )
@@ -222,31 +241,29 @@ static bool calc_bps(char *dst, unsigned int dstsize, uint64_t m1, uint64_t m2)
222241
223242void scan_print_summary (const struct ports * ports , int max_rate , int banners , uint8_t ip_type )
224243{
225- unsigned int payload_min = 9999 , payload_max = 0 ;
244+ u_int payload_min = 9999 , payload_max = 0 ;
226245 if (ip_type == IP_TYPE_TCP ) {
227- payload_min = payload_max = TCP_HEADER_SIZE ;
246+ payload_min = payload_max = FULL_TCP_SIZE ;
228247 } else if (ip_type == IP_TYPE_UDP && !banners ) {
229- payload_min = payload_max = UDP_HEADER_SIZE ;
248+ payload_min = payload_max = FULL_UDP_SIZE ;
230249 } else if (ip_type == IP_TYPE_UDP ) {
231250 // Need to know actual ports to know payload size
232251 if (!validate_ports (ports ))
233252 return ;
234253 struct ports_iter it ;
235254 ports_iter_begin (ports , & it );
236255 while (ports_iter_next (& it ) == 1 ) {
237- unsigned int len = 0 ;
256+ u_int len = 0 ;
238257 banner_get_query (IP_TYPE_UDP , it .val , & len );
239- len += UDP_HEADER_SIZE ;
258+ len += FULL_UDP_SIZE ;
240259 if (len < payload_min )
241260 payload_min = len ;
242261 if (len > payload_max )
243262 payload_max = len ;
244263 }
245264 } else if (ip_type == IP_TYPE_ICMPV6 ) {
246- payload_min = payload_max = ICMP_HEADER_SIZE ;
265+ payload_min = payload_max = FULL_ICMP_SIZE ;
247266 }
248- payload_min += FRAME_ETH_SIZE + FRAME_IP_SIZE ;
249- payload_max += FRAME_ETH_SIZE + FRAME_IP_SIZE ;
250267
251268 if (payload_min == payload_max ) {
252269 printf ("Scanning will send packets with %u octets (incl. Ethernet and IP headers).\n" ,
@@ -273,7 +290,7 @@ void scan_print_summary(const struct ports *ports, int max_rate, int banners, ui
273290
274291static void * send_thread_tcp (void * unused )
275292{
276- uint8_t _Alignas(uint32_t ) packet [FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE ];
293+ uint8_t _Alignas(uint32_t ) packet [FULL_TCP_SIZE ];
277294 uint8_t dstaddr [16 ];
278295 struct ports_iter it ;
279296
@@ -316,7 +333,7 @@ static void *send_thread_tcp(void *unused)
316333
317334static void * send_thread_udp (void * unused )
318335{
319- uint8_t _Alignas(uint32_t ) packet [FRAME_ETH_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE + BANNER_QUERY_MAX_LENGTH ];
336+ uint8_t _Alignas(uint32_t ) packet [FULL_UDP_SIZE + BANNER_QUERY_MAX_LENGTH ];
320337 uint8_t dstaddr [16 ];
321338 struct ports_iter it ;
322339
@@ -347,7 +364,7 @@ static void *send_thread_udp(void *unused)
347364
348365 uint16_t dstport = it .val ;
349366 udp_modify (UDP_HEADER (packet ), source_port == -1 ?source_port_rand ():source_port , dstport );
350- unsigned int dlen = 0 ;
367+ u_int dlen = 0 ;
351368 if (banners ) {
352369 const char * payload = banner_get_query (IP_TYPE_UDP , dstport , & dlen );
353370 if (payload && dlen > 0 )
@@ -357,7 +374,7 @@ static void *send_thread_udp(void *unused)
357374 }
358375
359376 udp_checksum (IP_FRAME (packet ), UDP_HEADER (packet ), dlen );
360- rawsock_send (packet , FRAME_ETH_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE + dlen );
377+ rawsock_send (packet , FULL_UDP_SIZE + dlen );
361378
362379 RATE_CONTROL ();
363380 }
@@ -371,7 +388,7 @@ static void *send_thread_udp(void *unused)
371388
372389static void * send_thread_icmp (void * unused )
373390{
374- uint8_t _Alignas(uint32_t ) packet [FRAME_ETH_SIZE + FRAME_IP_SIZE + ICMP_HEADER_SIZE ];
391+ uint8_t _Alignas(uint32_t ) packet [FULL_ICMP_SIZE ];
375392 uint8_t dstaddr [16 ];
376393
377394 (void ) unused ;
@@ -420,24 +437,23 @@ static void *recv_thread(void *unused)
420437 return NULL ;
421438}
422439
423- static void recv_handler (uint64_t ts , int len , const uint8_t * packet )
440+ static void recv_handler (uint64_t ts , u_int len , const uint8_t * packet )
424441{
425442 int v ;
426443 const uint8_t * csrcaddr ;
427444
428445 atomic_fetch_add (& pkts_recv , 1 );
429446
430- // decode
431447 if (rawsock_has_ethernet_headers ()) {
432- if (len < FRAME_ETH_SIZE )
448+ if (unl ( len < FRAME_ETH_SIZE ) )
433449 goto perr ;
434450 rawsock_eth_decode (ETH_FRAME (packet ), & v );
435451 } else {
436452 v = ETH_TYPE_IPV6 ;
437453 packet -= FRAME_ETH_SIZE ; // FIXME: convenient but horrible hack
438454 len += FRAME_ETH_SIZE ;
439455 }
440- if (v != ETH_TYPE_IPV6 || len < FRAME_ETH_SIZE + FRAME_IP_SIZE )
456+ if (unl ( v != ETH_TYPE_IPV6 || len < FRAME_ETH_SIZE + FRAME_IP_SIZE ) )
441457 goto perr ;
442458 rawsock_ip_decode (IP_FRAME (packet ), & v , NULL , NULL , & csrcaddr , NULL );
443459
@@ -458,11 +474,11 @@ static void recv_handler(uint64_t ts, int len, const uint8_t *packet)
458474#endif
459475}
460476
461- static void recv_handler_tcp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr )
477+ static void recv_handler_tcp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr )
462478{
463- if (ip_type != IP_TYPE_TCP )
479+ if (unl ( ip_type != IP_TYPE_TCP ) )
464480 goto perr ;
465- if (len < FRAME_ETH_SIZE + FRAME_IP_SIZE + TCP_HEADER_SIZE )
481+ if (unl ( len < FULL_TCP_SIZE ) )
466482 goto perr ;
467483
468484 // Output stuff
@@ -485,11 +501,11 @@ static void recv_handler_tcp(uint64_t ts, int len, const uint8_t *packet, const
485501#endif
486502}
487503
488- static void recv_handler_udp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr )
504+ static void recv_handler_udp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr )
489505{
490- if (ip_type != IP_TYPE_UDP )
506+ if (unl ( ip_type != IP_TYPE_UDP ) )
491507 goto perr ;
492- if (len < FRAME_ETH_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE )
508+ if (unl ( len < FULL_UDP_SIZE ) )
493509 goto perr ;
494510
495511 int v ;
@@ -502,7 +518,7 @@ static void recv_handler_udp(uint64_t ts, int len, const uint8_t *packet, const
502518 return ;
503519 }
504520
505- uint32_t plen = len - ( FRAME_ETH_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE ) ;
521+ uint32_t plen = len - FULL_UDP_SIZE ;
506522 if (plen == 0 )
507523 return ;
508524 else if (plen > BANNER_MAX_LENGTH )
@@ -520,20 +536,16 @@ static void recv_handler_udp(uint64_t ts, int len, const uint8_t *packet, const
520536#endif
521537}
522538
523- enum {
524- FULL_ICMP_SIZE = FRAME_ETH_SIZE + FRAME_IP_SIZE + ICMP_HEADER_SIZE ,
525- };
526-
527539#define INNER_IP_FRAME (buf ) ( (const struct frame_ip*) &(buf)[FULL_ICMP_SIZE] )
528540#define INNER_UDP_HEADER (buf ) ( (const struct udp_header*) &(buf)[FULL_ICMP_SIZE + FRAME_IP_SIZE] )
529541
530- static void handle_icmp_error (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr )
542+ static void handle_icmp_error (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr )
531543{
532544 // (detection of closed UDP ports only so far)
533- if (ip_type != IP_TYPE_UDP )
545+ if (unl ( ip_type != IP_TYPE_UDP ) )
534546 goto perr ;
535- const int minlen = FULL_ICMP_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE ;
536- if (len < minlen )
547+ const u_int minlen = FULL_ICMP_SIZE + FRAME_IP_SIZE + UDP_HEADER_SIZE ;
548+ if (unl ( len < minlen ) )
537549 goto perr ;
538550
539551 // Note: the destination ip/port and protocol type are already checked
@@ -570,17 +582,16 @@ static void handle_icmp_error(uint64_t ts, int len, const uint8_t *packet, const
570582#undef INNER_IP_FRAME
571583#undef INNER_UDP_HEADER
572584
573- static void recv_handler_icmp (uint64_t ts , int len , const uint8_t * packet , const uint8_t * csrcaddr )
585+ static void recv_handler_icmp (uint64_t ts , u_int len , const uint8_t * packet , const uint8_t * csrcaddr )
574586{
575- const int minlen = FRAME_ETH_SIZE + FRAME_IP_SIZE + ICMP_HEADER_SIZE ;
576- if (len < minlen )
587+ if (unl (len < FULL_ICMP_SIZE ))
577588 goto perr ;
578589
579590 if (ICMP_HEADER (packet )-> type < 128 )
580591 return handle_icmp_error (ts , len , packet , csrcaddr );
581592
582593 // handling for icmp echo scans follows:
583- if (len != minlen )
594+ if (len != FULL_ICMP_SIZE )
584595 return ;
585596 if (ICMP_HEADER (packet )-> type != 129 ) // Echo Reply
586597 return ;
0 commit comments