19
19
#include <stdbool.h>
20
20
#include <pthread.h>
21
21
#include <arpa/inet.h>
22
+ #include <sys/stat.h>
23
+ #include <sys/types.h>
22
24
#include <sys/socket.h>
23
25
24
26
#define SOCKET_ERROR_TRY 3
@@ -51,9 +53,11 @@ const static struct option long_options[] = {
51
53
{0 , 0 , 0 , 0 }
52
54
};
53
55
56
+ FILE * report_handle ;
54
57
uint8_t verbose_level = 0 ;
55
- int16_t recv_timeout = -1 ;
56
- int16_t send_timeout = -1 ;
58
+ int16_t recv_timeout = DEFAULT_RECV_TIMEOUT ;
59
+ int16_t send_timeout = DEFAULT_SEND_TIMEOUT ;
60
+ pthread_mutex_t lock_write_report = PTHREAD_MUTEX_INITIALIZER ;
57
61
58
62
void usage (char * app );
59
63
void do_scan (scanner_config * config );
@@ -102,7 +106,7 @@ void usage(char *app)
102
106
printf (" -h|--host <host>\tTarget host (IPv4)\n" );
103
107
printf (" -v|--verbose\tVerbose output (use more -v to increase verbose level)\n" );
104
108
printf (" -r|--recv-timeout\trecv(2) timeout (default: %d)\n" , DEFAULT_RECV_TIMEOUT );
105
- printf (" -s|--send-timeout\tsend(2) timeout (default: %d)\n" , DEFAULT_SEND_TIMEOUT );
109
+ printf (" -s|--send-timeout\tsend(2) timeout, this affects connect(2) too (default: %d)\n" , DEFAULT_SEND_TIMEOUT );
106
110
}
107
111
108
112
@@ -182,15 +186,48 @@ bool parse_argv(int argc, char *argv[], scanner_config *config)
182
186
void do_scan (scanner_config * config )
183
187
{
184
188
thread_job * jobs ;
185
- uint16_t free_thread ;
189
+ struct stat dirst ;
190
+ char report_file [128 ];
191
+ uint16_t free_thread , i ;
186
192
187
193
msg_log (2 , "Allocating thread jobs for %d threads...\n" , config -> num_thread );
188
194
189
195
jobs = (thread_job * )malloc (sizeof (thread_job ) * (config -> num_thread + 1 ));
190
196
191
197
memset (jobs , '\0' , sizeof (thread_job ) * (config -> num_thread + 1 ));
192
198
193
- for (uint16_t i = 1 ; i < 65535 ; i ++ ) {
199
+ if (stat ("reports" , & dirst ) < 0 ) {
200
+ if (
201
+ (mkdir ("reports" , 0700 ) < 0 ) ||
202
+ (stat ("reports" , & dirst ) < 0 )
203
+ ) {
204
+ perror ("mkdir" );
205
+ printf ("Cannot create directory ./reports\n" );
206
+ exit (1 );
207
+ }
208
+ }
209
+
210
+ if ((dirst .st_mode & S_IFMT ) != S_IFDIR ) {
211
+ printf ("Cannot create directory ./reports\n" );
212
+ exit (1 );
213
+ }
214
+
215
+ sprintf (report_file , "reports/%s" , config -> target_host );
216
+ if (stat (report_file , & dirst ) < 0 ) {
217
+ if (
218
+ (mkdir (report_file , 0700 ) < 0 ) ||
219
+ (stat (report_file , & dirst ) < 0 )
220
+ ) {
221
+ perror ("mkdir" );
222
+ printf ("Cannot create directory ./%s\n" , report_file );
223
+ exit (1 );
224
+ }
225
+ }
226
+
227
+ sprintf (report_file , "reports/%s/000_report.txt" , config -> target_host );
228
+ report_handle = fopen (report_file , "w" );
229
+
230
+ for (i = 1 ; i < 65535 ; i ++ ) {
194
231
195
232
free_thread = (uint16_t )get_non_busy_thread (jobs , config -> num_thread );
196
233
@@ -204,8 +241,21 @@ void do_scan(scanner_config *config)
204
241
pthread_detach (jobs [free_thread ].thread );
205
242
}
206
243
244
+ bool has_busy_thread = false;
245
+ do {
246
+ for (i = 0 ; i < config -> num_thread ; i ++ ) {
247
+ if (jobs [i ].is_busy ) {
248
+ has_busy_thread = true;
249
+ break ;
250
+ }
251
+ }
252
+ msg_log (1 , "Waiting for the last jobs...\n" );
253
+ sleep (THREAD_WAIT_SLEEP );
254
+ } while (has_busy_thread );
255
+
207
256
208
257
free (jobs );
258
+ fclose (report_handle );
209
259
}
210
260
211
261
@@ -226,7 +276,6 @@ uint16_t get_non_busy_thread(
226
276
227
277
check_threads :
228
278
for (i = 0 ; i < num_thread ; i ++ ) {
229
- printf ("%d\n" , jobs [i ].is_busy );
230
279
if (!jobs [i ].is_busy ) {
231
280
return (int32_t )i ;
232
281
}
@@ -235,8 +284,8 @@ uint16_t get_non_busy_thread(
235
284
236
285
if (counter % 5 == 0 ) {
237
286
msg_log (3 , "(%d) All threads all busy...\n" , counter );
238
- sleep (THREAD_WAIT_SLEEP );
239
287
}
288
+ sleep (THREAD_WAIT_SLEEP );
240
289
goto check_threads ;
241
290
}
242
291
@@ -269,36 +318,51 @@ void *thread_handler(thread_job *job)
269
318
if (net_fd < 0 ) goto ret ;
270
319
271
320
if (socket_connect (net_fd , job -> target_host , job -> target_port , & out_errno )) {
272
-
321
+ msg_log ( 3 , "Connect OK" );
273
322
} else {
274
323
275
- switch (ret_val ) {
324
+ switch (out_errno ) {
276
325
/*
277
326
* The port may not be DROPPED by the firewall.
278
327
*/
279
328
case ECONNREFUSED : /* Connection refused. */
329
+ msg_log (3 , "ECONNREFUSED\n" );
280
330
is_port_open = true;
281
331
break ;
282
332
283
333
/*
284
334
* The port may be DROPPED by the firewall.
285
335
*/
336
+ case EINPROGRESS :
286
337
case ETIMEDOUT : /* Connection timedout. */
338
+ msg_log (3 , "ETIMEDOUT\n" );
287
339
288
340
/*
289
341
* Error client.
290
342
*/
291
343
case ENETUNREACH : /* Network unreachable. */
344
+ msg_log (3 , "ENETUNREACH\n" );
292
345
case EINTR : /* Interrupted. */
346
+ msg_log (3 , "EINTR\n" );
293
347
case EFAULT : /* Fault. */
348
+ msg_log (3 , "EFAULT\n" );
294
349
case EBADF : /* Invalid sockfd. */
350
+ msg_log (3 , "EBADF\n" );
295
351
case ENOTSOCK : /* sockfd is not a socket file descriptor. */
352
+ msg_log (3 , "ENOTSOCK\n" );
296
353
case EPROTOTYPE : /* Socket does not support the protocol. */
354
+ msg_log (3 , "EPROTOTYPE\n" );
355
+ default :
356
+ msg_log (3 , "default ERR\n" );
297
357
is_error = true;
298
358
break ;
299
359
}
300
360
}
301
361
362
+ pthread_mutex_lock (& lock_write_report );
363
+ fprintf (report_handle , "%s:%d\n" , job -> target_host , job -> target_port );
364
+ fflush (report_handle );
365
+ pthread_mutex_unlock (& lock_write_report );
302
366
close_ret :
303
367
304
368
if (net_fd > -1 ) {
@@ -344,7 +408,7 @@ static int socket_init()
344
408
345
409
timeout .tv_sec = send_timeout ;
346
410
timeout .tv_usec = 0 ;
347
- if (setsockopt (net_fd , SOL_SOCKET , SO_RCVTIMEO ,
411
+ if (setsockopt (net_fd , SOL_SOCKET , SO_SNDTIMEO ,
348
412
(char * )& timeout , sizeof (timeout )) < 0
349
413
) {
350
414
perror ("setsockopt" );
@@ -386,8 +450,10 @@ static bool socket_connect(int net_fd,
386
450
if (connect (net_fd , (struct sockaddr * )& (server_addr ),
387
451
sizeof (struct sockaddr_in )) < 0 ) {
388
452
* out_errno = errno ;
453
+ perror ("connect" );
389
454
return false;
390
455
}
456
+ msg_log (1 , "Connection established %s:%d\n" , target_host , target_port );
391
457
392
458
return true;
393
459
}
0 commit comments