@ -28,6 +28,7 @@
# include <sys/socket.h>
# include <sys/socket.h>
# include <sys/stat.h>
# include <sys/stat.h>
# include <netinet/in.h>
# include <netinet/in.h>
# include <syslog.h>
# ifdef __CYGWIN__
# ifdef __CYGWIN__
# include "win.h"
# include "win.h"
@ -99,7 +100,7 @@ static uint8_t processPacketData(uint32_t *mark, const char *ifout, uint8_t *dat
# ifdef __linux__
# ifdef __linux__
if ( * mark & params . desync_fwmark )
if ( * mark & params . desync_fwmark )
{
{
DLOG ( " ignoring generated packet \n " )
DLOG ( " ignoring generated packet \n " ) ;
return VERDICT_PASS ;
return VERDICT_PASS ;
}
}
# endif
# endif
@ -129,11 +130,11 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
ifidx = nfq_get_outdev ( nfa ) ;
ifidx = nfq_get_outdev ( nfa ) ;
if ( ifidx ) if_indextoname ( ifidx , ifout ) ;
if ( ifidx ) if_indextoname ( ifidx , ifout ) ;
DLOG ( " packet: id=%d len=%d mark=%08X ifout=%s(%u) \n " , id , ilen , mark , ifout , ifidx )
DLOG ( " packet: id=%d len=%d mark=%08X ifout=%s(%u) \n " , id , ilen , mark , ifout , ifidx ) ;
}
}
else
else
// save some syscalls
// save some syscalls
DLOG ( " packet: id=%d len=%d mark=%08X \n " , id , ilen , mark )
DLOG ( " packet: id=%d len=%d mark=%08X \n " , id , ilen , mark ) ;
if ( ilen > = 0 )
if ( ilen > = 0 )
{
{
len = ilen ;
len = ilen ;
@ -158,49 +159,49 @@ static int nfq_main(void)
int fd , rv ;
int fd , rv ;
uint8_t buf [ 16384 ] __attribute__ ( ( aligned ) ) ;
uint8_t buf [ 16384 ] __attribute__ ( ( aligned ) ) ;
printf ( " opening library handle \n " ) ;
DLOG_CONDUP ( " opening library handle \n " ) ;
h = nfq_open ( ) ;
h = nfq_open ( ) ;
if ( ! h ) {
if ( ! h ) {
perror ( " nfq_open() " ) ;
DLOG_PERROR ( " nfq_open() " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " unbinding existing nf_queue handler for AF_INET (if any) \n " ) ;
DLOG_CONDUP ( " unbinding existing nf_queue handler for AF_INET (if any) \n " ) ;
if ( nfq_unbind_pf ( h , AF_INET ) < 0 ) {
if ( nfq_unbind_pf ( h , AF_INET ) < 0 ) {
perror ( " nfq_unbind_pf() " ) ;
DLOG_PERROR ( " nfq_unbind_pf() " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " binding nfnetlink_queue as nf_queue handler for AF_INET \n " ) ;
DLOG_CONDUP ( " binding nfnetlink_queue as nf_queue handler for AF_INET \n " ) ;
if ( nfq_bind_pf ( h , AF_INET ) < 0 ) {
if ( nfq_bind_pf ( h , AF_INET ) < 0 ) {
perror ( " nfq_bind_pf() " ) ;
DLOG_PERROR ( " nfq_bind_pf() " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " binding this socket to queue '%u' \n " , params . qnum ) ;
DLOG_CONDUP ( " binding this socket to queue '%u' \n " , params . qnum ) ;
qh = nfq_create_queue ( h , params . qnum , & nfq_cb , & params ) ;
qh = nfq_create_queue ( h , params . qnum , & nfq_cb , & params ) ;
if ( ! qh ) {
if ( ! qh ) {
perror ( " nfq_create_queue() " ) ;
DLOG_PERROR ( " nfq_create_queue() " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " setting copy_packet mode \n " ) ;
DLOG_CONDUP ( " setting copy_packet mode \n " ) ;
if ( nfq_set_mode ( qh , NFQNL_COPY_PACKET , 0xffff ) < 0 ) {
if ( nfq_set_mode ( qh , NFQNL_COPY_PACKET , 0xffff ) < 0 ) {
perror ( " can't set packet_copy mode " ) ;
DLOG_PERROR ( " can't set packet_copy mode " ) ;
goto exiterr ;
goto exiterr ;
}
}
if ( nfq_set_queue_maxlen ( qh , Q_MAXLEN ) < 0 ) {
if ( nfq_set_queue_maxlen ( qh , Q_MAXLEN ) < 0 ) {
perror ( " can't set queue maxlen " ) ;
DLOG_PERROR ( " can't set queue maxlen " ) ;
goto exiterr ;
goto exiterr ;
}
}
// accept packets if they cant be handled
// accept packets if they cant be handled
if ( nfq_set_queue_flags ( qh , NFQA_CFG_F_FAIL_OPEN , NFQA_CFG_F_FAIL_OPEN ) )
if ( nfq_set_queue_flags ( qh , NFQA_CFG_F_FAIL_OPEN , NFQA_CFG_F_FAIL_OPEN ) )
{
{
fprintf ( stderr , " can't set queue flags. its OK on linux <3.6 \n " ) ;
DLOG_ERR ( " can't set queue flags. its OK on linux <3.6 \n " ) ;
// dot not fail. not supported on old linuxes <3.6
// dot not fail. not supported on old linuxes <3.6
}
}
printf ( " initializing raw sockets bind-fix4=%u bind-fix6=%u \n " , params . bind_fix4 , params . bind_fix6 ) ;
DLOG_CONDUP ( " initializing raw sockets bind-fix4=%u bind-fix6=%u \n " , params . bind_fix4 , params . bind_fix6 ) ;
if ( ! rawsend_preinit ( params . bind_fix4 , params . bind_fix6 ) )
if ( ! rawsend_preinit ( params . bind_fix4 , params . bind_fix6 ) )
goto exiterr ;
goto exiterr ;
@ -227,24 +228,24 @@ static int nfq_main(void)
{
{
dohup ( ) ;
dohup ( ) ;
int r = nfq_handle_packet ( h , ( char * ) buf , rv ) ;
int r = nfq_handle_packet ( h , ( char * ) buf , rv ) ;
if ( r ) fprintf ( stderr , " nfq_handle_packet error %d \n " , r ) ;
if ( r ) DLOG_ERR ( " nfq_handle_packet error %d \n " , r ) ;
}
}
fprintf ( stderr , " recv: errno %d \n " , errno ) ;
DLOG_ERR ( " recv: errno %d \n " , errno ) ;
perror ( " recv " ) ;
DLOG_PERROR ( " recv " ) ;
// do not fail on ENOBUFS
// do not fail on ENOBUFS
} while ( errno = = ENOBUFS ) ;
} while ( errno = = ENOBUFS ) ;
printf ( " unbinding from queue %u \n " , params . qnum ) ;
DLOG_CONDUP ( " unbinding from queue %u \n " , params . qnum ) ;
nfq_destroy_queue ( qh ) ;
nfq_destroy_queue ( qh ) ;
# ifdef INSANE
# ifdef INSANE
/* normally, applications SHOULD NOT issue this command, since
/* normally, applications SHOULD NOT issue this command, since
* it detaches other programs / sockets from AF_INET , too ! */
* it detaches other programs / sockets from AF_INET , too ! */
printf ( " unbinding from AF_INET \n " ) ;
DLOG_CONDUP ( " unbinding from AF_INET \n " ) ;
nfq_unbind_pf ( h , AF_INET ) ;
nfq_unbind_pf ( h , AF_INET ) ;
# endif
# endif
printf ( " closing library handle \n " ) ;
DLOG_CONDUP ( " closing library handle \n " ) ;
nfq_close ( h ) ;
nfq_close ( h ) ;
return 0 ;
return 0 ;
@ -273,16 +274,16 @@ static int dvt_main(void)
bp4 . sin_port = htons ( params . port ) ;
bp4 . sin_port = htons ( params . port ) ;
bp4 . sin_addr . s_addr = INADDR_ANY ;
bp4 . sin_addr . s_addr = INADDR_ANY ;
printf ( " creating divert4 socket \n " ) ;
DLOG_CONDUP ( " creating divert4 socket \n " ) ;
fd [ 0 ] = socket_divert ( AF_INET ) ;
fd [ 0 ] = socket_divert ( AF_INET ) ;
if ( fd [ 0 ] = = - 1 ) {
if ( fd [ 0 ] = = - 1 ) {
perror ( " socket (DIVERT4) " ) ;
DLOG_PERROR ( " socket (DIVERT4) " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " binding divert4 socket \n " ) ;
DLOG_CONDUP ( " binding divert4 socket \n " ) ;
if ( bind ( fd [ 0 ] , ( struct sockaddr * ) & bp4 , sizeof ( bp4 ) ) < 0 )
if ( bind ( fd [ 0 ] , ( struct sockaddr * ) & bp4 , sizeof ( bp4 ) ) < 0 )
{
{
perror ( " bind (DIVERT4) " ) ;
DLOG_PERROR ( " bind (DIVERT4) " ) ;
goto exiterr ;
goto exiterr ;
}
}
if ( ! set_socket_buffers ( fd [ 0 ] , Q_RCVBUF , Q_SNDBUF ) )
if ( ! set_socket_buffers ( fd [ 0 ] , Q_RCVBUF , Q_SNDBUF ) )
@ -298,16 +299,16 @@ static int dvt_main(void)
bp6 . sin6_family = AF_INET6 ;
bp6 . sin6_family = AF_INET6 ;
bp6 . sin6_port = htons ( params . port ) ;
bp6 . sin6_port = htons ( params . port ) ;
printf ( " creating divert6 socket \n " ) ;
DLOG_CONDUP ( " creating divert6 socket \n " ) ;
fd [ 1 ] = socket_divert ( AF_INET6 ) ;
fd [ 1 ] = socket_divert ( AF_INET6 ) ;
if ( fd [ 1 ] = = - 1 ) {
if ( fd [ 1 ] = = - 1 ) {
perror ( " socket (DIVERT6) " ) ;
DLOG_PERROR ( " socket (DIVERT6) " ) ;
goto exiterr ;
goto exiterr ;
}
}
printf ( " binding divert6 socket \n " ) ;
DLOG_CONDUP ( " binding divert6 socket \n " ) ;
if ( bind ( fd [ 1 ] , ( struct sockaddr * ) & bp6 , sizeof ( bp6 ) ) < 0 )
if ( bind ( fd [ 1 ] , ( struct sockaddr * ) & bp6 , sizeof ( bp6 ) ) < 0 )
{
{
perror ( " bind (DIVERT6) " ) ;
DLOG_PERROR ( " bind (DIVERT6) " ) ;
goto exiterr ;
goto exiterr ;
}
}
fdct + + ;
fdct + + ;
@ -317,7 +318,7 @@ static int dvt_main(void)
# endif
# endif
fdmax = ( fd [ 0 ] > fd [ 1 ] ? fd [ 0 ] : fd [ 1 ] ) + 1 ;
fdmax = ( fd [ 0 ] > fd [ 1 ] ? fd [ 0 ] : fd [ 1 ] ) + 1 ;
printf ( " initializing raw sockets \n " ) ;
DLOG_CONDUP ( " initializing raw sockets \n " ) ;
if ( ! rawsend_preinit ( false , false ) )
if ( ! rawsend_preinit ( false , false ) )
goto exiterr ;
goto exiterr ;
@ -340,7 +341,7 @@ static int dvt_main(void)
dohup ( ) ;
dohup ( ) ;
continue ;
continue ;
}
}
perror ( " select " ) ;
DLOG_PERROR ( " select " ) ;
goto exiterr ;
goto exiterr ;
}
}
for ( i = 0 ; i < fdct ; i + + )
for ( i = 0 ; i < fdct ; i + + )
@ -351,7 +352,7 @@ static int dvt_main(void)
rd = recvfrom ( fd [ i ] , buf , sizeof ( buf ) , 0 , ( struct sockaddr * ) & sa_from , & socklen ) ;
rd = recvfrom ( fd [ i ] , buf , sizeof ( buf ) , 0 , ( struct sockaddr * ) & sa_from , & socklen ) ;
if ( rd < 0 )
if ( rd < 0 )
{
{
perror ( " recvfrom " ) ;
DLOG_PERROR ( " recvfrom " ) ;
goto exiterr ;
goto exiterr ;
}
}
else if ( rd > 0 )
else if ( rd > 0 )
@ -360,21 +361,21 @@ static int dvt_main(void)
uint8_t verdict ;
uint8_t verdict ;
size_t len = rd ;
size_t len = rd ;
DLOG ( " packet: id=%u len=%zu \n " , id , len )
DLOG ( " packet: id=%u len=%zu \n " , id , len ) ;
verdict = processPacketData ( & mark , NULL , buf , & len ) ;
verdict = processPacketData ( & mark , NULL , buf , & len ) ;
switch ( verdict & VERDICT_MASK )
switch ( verdict & VERDICT_MASK )
{
{
case VERDICT_PASS :
case VERDICT_PASS :
case VERDICT_MODIFY :
case VERDICT_MODIFY :
if ( ( verdict & VERDICT_MASK ) = = VERDICT_PASS )
if ( ( verdict & VERDICT_MASK ) = = VERDICT_PASS )
DLOG ( " packet: id=%u reinject unmodified \n " , id )
DLOG ( " packet: id=%u reinject unmodified \n " , id ) ;
else
else
DLOG ( " packet: id=%u reinject modified len=%zu \n " , id , len )
DLOG ( " packet: id=%u reinject modified len=%zu \n " , id , len ) ;
wr = sendto ( fd [ i ] , buf , len , 0 , ( struct sockaddr * ) & sa_from , socklen ) ;
wr = sendto ( fd [ i ] , buf , len , 0 , ( struct sockaddr * ) & sa_from , socklen ) ;
if ( wr < 0 )
if ( wr < 0 )
perror ( " reinject sendto " ) ;
DLOG_PERROR ( " reinject sendto " ) ;
else if ( wr ! = len )
else if ( wr ! = len )
fprintf ( stderr , " reinject sendto: not all data was reinjected. received %zu, sent %zd \n " , len , wr ) ;
DLOG_ERR ( " reinject sendto: not all data was reinjected. received %zu, sent %zd \n " , len , wr ) ;
break ;
break ;
default :
default :
DLOG ( " packet: id=%u drop \n " , id ) ;
DLOG ( " packet: id=%u drop \n " , id ) ;
@ -383,7 +384,7 @@ static int dvt_main(void)
}
}
else
else
{
{
DLOG ( " unexpected zero size recvfrom \n " )
DLOG ( " unexpected zero size recvfrom \n " ) ;
}
}
}
}
}
}
@ -414,7 +415,7 @@ static int win_main(const char *windivert_filter)
if ( ! win_dark_init ( & params . ssid_filter , & params . nlm_filter ) )
if ( ! win_dark_init ( & params . ssid_filter , & params . nlm_filter ) )
{
{
fprintf ( stderr , " win_dark_init failed. win32 error %u (0x%08X) \n " , w_win32_error , w_win32_error ) ;
DLOG_ERR ( " win_dark_init failed. win32 error %u (0x%08X) \n " , w_win32_error , w_win32_error ) ;
return w_win32_error ;
return w_win32_error ;
}
}
@ -422,20 +423,20 @@ static int win_main(const char *windivert_filter)
{
{
if ( ! logical_net_filter_match ( ) )
if ( ! logical_net_filter_match ( ) )
{
{
printf ( " logical network is not present. waiting it to appear. \n " ) ;
DLOG_CONDUP ( " logical network is not present. waiting it to appear. \n " ) ;
fflush ( stdout ) ;
fflush ( stdout ) ;
do
do
{
{
if ( bQuit )
if ( bQuit )
{
{
DLOG ( " QUIT requested \n " )
DLOG ( " QUIT requested \n " ) ;
win_dark_deinit ( ) ;
win_dark_deinit ( ) ;
return 0 ;
return 0 ;
}
}
usleep ( 500000 ) ;
usleep ( 500000 ) ;
}
}
while ( ! logical_net_filter_match ( ) ) ;
while ( ! logical_net_filter_match ( ) ) ;
printf ( " logical network now present \n " ) ;
DLOG_CONDUP ( " logical network now present \n " ) ;
fflush ( stdout ) ;
fflush ( stdout ) ;
}
}
@ -445,7 +446,7 @@ static int win_main(const char *windivert_filter)
return w_win32_error ;
return w_win32_error ;
}
}
printf ( " windivert initialized. capture is started. \n " ) ;
DLOG_CONDUP ( " windivert initialized. capture is started. \n " ) ;
// cygwin auto flush fails when piping
// cygwin auto flush fails when piping
fflush ( stdout ) ;
fflush ( stdout ) ;
@ -458,36 +459,36 @@ static int win_main(const char *windivert_filter)
{
{
if ( errno = = ENOBUFS )
if ( errno = = ENOBUFS )
{
{
DLOG ( " windivert: ignoring too large packet \n " )
DLOG ( " windivert: ignoring too large packet \n " ) ;
continue ; // too large packet
continue ; // too large packet
}
}
else if ( errno = = ENODEV )
else if ( errno = = ENODEV )
{
{
printf ( " logical network disappeared. deinitializing windivert. \n " ) ;
DLOG_CONDUP ( " logical network disappeared. deinitializing windivert. \n " ) ;
rawsend_cleanup ( ) ;
rawsend_cleanup ( ) ;
break ;
break ;
}
}
else if ( errno = = EINTR )
else if ( errno = = EINTR )
{
{
DLOG ( " QUIT requested \n " )
DLOG ( " QUIT requested \n " ) ;
win_dark_deinit ( ) ;
win_dark_deinit ( ) ;
return 0 ;
return 0 ;
}
}
fprintf ( stderr , " windivert: recv failed. errno %d \n " , errno ) ;
DLOG_ERR ( " windivert: recv failed. errno %d \n " , errno ) ;
win_dark_deinit ( ) ;
win_dark_deinit ( ) ;
return w_win32_error ;
return w_win32_error ;
}
}
* ifout = 0 ;
* ifout = 0 ;
if ( wa . Outbound ) snprintf ( ifout , sizeof ( ifout ) , " %u.%u " , wa . Network . IfIdx , wa . Network . SubIfIdx ) ;
if ( wa . Outbound ) snprintf ( ifout , sizeof ( ifout ) , " %u.%u " , wa . Network . IfIdx , wa . Network . SubIfIdx ) ;
DLOG ( " packet: id=%u len=%zu %s IPv6=%u IPChecksum=%u TCPChecksum=%u UDPChecksum=%u IfIdx=%u.%u \n " , id , len , wa . Outbound ? " outbound " : " inbound " , wa . IPv6 , wa . IPChecksum , wa . TCPChecksum , wa . UDPChecksum , wa . Network . IfIdx , wa . Network . SubIfIdx )
DLOG ( " packet: id=%u len=%zu %s IPv6=%u IPChecksum=%u TCPChecksum=%u UDPChecksum=%u IfIdx=%u.%u \n " , id , len , wa . Outbound ? " outbound " : " inbound " , wa . IPv6 , wa . IPChecksum , wa . TCPChecksum , wa . UDPChecksum , wa . Network . IfIdx , wa . Network . SubIfIdx ) ;
if ( wa . Impostor )
if ( wa . Impostor )
{
{
DLOG ( " windivert: passing impostor packet \n " )
DLOG ( " windivert: passing impostor packet \n " ) ;
verdict = VERDICT_PASS ;
verdict = VERDICT_PASS ;
}
}
else if ( wa . Loopback )
else if ( wa . Loopback )
{
{
DLOG ( " windivert: passing loopback packet \n " )
DLOG ( " windivert: passing loopback packet \n " ) ;
verdict = VERDICT_PASS ;
verdict = VERDICT_PASS ;
}
}
else
else
@ -501,11 +502,11 @@ static int win_main(const char *windivert_filter)
case VERDICT_PASS :
case VERDICT_PASS :
case VERDICT_MODIFY :
case VERDICT_MODIFY :
if ( ( verdict & VERDICT_MASK ) = = VERDICT_PASS )
if ( ( verdict & VERDICT_MASK ) = = VERDICT_PASS )
DLOG ( " packet: id=%u reinject unmodified \n " , id )
DLOG ( " packet: id=%u reinject unmodified \n " , id ) ;
else
else
DLOG ( " packet: id=%u reinject modified len=%zu \n " , id , len )
DLOG ( " packet: id=%u reinject modified len=%zu \n " , id , len ) ;
if ( ! windivert_send ( packet , len , & wa ) )
if ( ! windivert_send ( packet , len , & wa ) )
fprintf ( stderr , " windivert: reinject of packet id=%u failed \n " , id ) ;
DLOG_ERR ( " windivert: reinject of packet id=%u failed \n " , id ) ;
break ;
break ;
default :
default :
DLOG ( " packet: id=%u drop \n " , id ) ;
DLOG ( " packet: id=%u drop \n " , id ) ;
@ -533,7 +534,7 @@ static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
v = atoi ( s ) ;
v = atoi ( s ) ;
if ( v < 0 | | v > 65535 )
if ( v < 0 | | v > 65535 )
{
{
fprintf ( stderr , " bad wsize \n " ) ;
DLOG_ERR ( " bad wsize \n " ) ;
return false ;
return false ;
}
}
* wsize = ( uint16_t ) v ;
* wsize = ( uint16_t ) v ;
@ -542,7 +543,7 @@ static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
v = atoi ( p ) ;
v = atoi ( p ) ;
if ( v < 0 | | v > 255 )
if ( v < 0 | | v > 255 )
{
{
fprintf ( stderr , " bad wscale \n " ) ;
DLOG_ERR ( " bad wscale \n " ) ;
return false ;
return false ;
}
}
* wscale = ( uint8_t ) v ;
* wscale = ( uint8_t ) v ;
@ -595,19 +596,19 @@ static void load_file_or_exit(const char *filename, void *buf, size_t *size)
{
{
if ( ! parse_hex_str ( filename + 2 , buf , size ) | | ! * size )
if ( ! parse_hex_str ( filename + 2 , buf , size ) | | ! * size )
{
{
fprintf ( stderr , " invalid hex string: %s \n " , filename + 2 ) ;
DLOG_ERR ( " invalid hex string: %s \n " , filename + 2 ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
DLOG ( " read %zu bytes from hex string \n " , * size )
DLOG ( " read %zu bytes from hex string \n " , * size ) ;
}
}
else
else
{
{
if ( ! load_file_nonempty ( filename , buf , size ) )
if ( ! load_file_nonempty ( filename , buf , size ) )
{
{
fprintf ( stderr , " could not read %s \n " , filename ) ;
DLOG_ERR ( " could not read %s \n " , filename ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
DLOG ( " read %zu bytes from %s \n " , * size , filename )
DLOG ( " read %zu bytes from %s \n " , * size , filename ) ;
}
}
}
}
@ -786,7 +787,7 @@ static unsigned int hash_jen(const void *data,unsigned int len)
static void exithelp ( void )
static void exithelp ( void )
{
{
printf (
printf (
" --debug=0|1 \n "
" --debug=0|1|syslog|@<filename> \n "
# ifdef __linux__
# ifdef __linux__
" --qnum=<nfqueue_number> \n "
" --qnum=<nfqueue_number> \n "
# elif defined(BSD)
# elif defined(BSD)
@ -1078,7 +1079,41 @@ int main(int argc, char **argv)
switch ( option_index )
switch ( option_index )
{
{
case 0 : /* debug */
case 0 : /* debug */
params . debug = ! optarg | | atoi ( optarg ) ;
if ( optarg )
{
if ( * optarg = = ' @ ' )
{
strncpy ( params . debug_logfile , optarg + 1 , sizeof ( params . debug_logfile ) ) ;
params . debug_logfile [ sizeof ( params . debug_logfile ) - 1 ] = 0 ;
FILE * F = fopen ( params . debug_logfile , " wt " ) ;
if ( ! F )
{
fprintf ( stderr , " cannot create %s \n " , params . debug_logfile ) ;
exit_clean ( 1 ) ;
}
# ifndef __CYGWIN__
if ( params . droproot & & chown ( params . debug_logfile , params . uid , - 1 ) )
fprintf ( stderr , " could not chown %s. log file may not be writable after privilege drop \n " , params . debug_logfile ) ;
# endif
params . debug = true ;
params . debug_target = LOG_TARGET_FILE ;
}
else if ( ! strcmp ( optarg , " syslog " ) )
{
params . debug = true ;
params . debug_target = LOG_TARGET_SYSLOG ;
}
else
{
params . debug = ! ! atoi ( optarg ) ;
params . debug_target = LOG_TARGET_CONSOLE ;
}
}
else
{
params . debug = true ;
params . debug_target = LOG_TARGET_CONSOLE ;
}
break ;
break ;
# ifndef __CYGWIN__
# ifndef __CYGWIN__
case 1 : /* qnum or port */
case 1 : /* qnum or port */
@ -1086,7 +1121,7 @@ int main(int argc, char **argv)
params . qnum = atoi ( optarg ) ;
params . qnum = atoi ( optarg ) ;
if ( params . qnum < 0 | | params . qnum > 65535 )
if ( params . qnum < 0 | | params . qnum > 65535 )
{
{
fprintf ( stderr , " bad qnum \n " ) ;
DLOG_ERR ( " bad qnum \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# elif defined(BSD)
# elif defined(BSD)
@ -1094,7 +1129,7 @@ int main(int argc, char **argv)
int i = atoi ( optarg ) ;
int i = atoi ( optarg ) ;
if ( i < = 0 | | i > 65535 )
if ( i < = 0 | | i > 65535 )
{
{
fprintf ( stderr , " bad port number \n " ) ;
DLOG_ERR ( " bad port number \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
params . port = ( uint16_t ) i ;
params . port = ( uint16_t ) i ;
@ -1115,7 +1150,7 @@ int main(int argc, char **argv)
struct passwd * pwd = getpwnam ( optarg ) ;
struct passwd * pwd = getpwnam ( optarg ) ;
if ( ! pwd )
if ( ! pwd )
{
{
fprintf ( stderr , " non-existent username supplied \n " ) ;
DLOG_ERR ( " non-existent username supplied \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
params . uid = pwd - > pw_uid ;
params . uid = pwd - > pw_uid ;
@ -1128,7 +1163,7 @@ int main(int argc, char **argv)
params . droproot = true ;
params . droproot = true ;
if ( sscanf ( optarg , " %u:%u " , & params . uid , & params . gid ) < 1 )
if ( sscanf ( optarg , " %u:%u " , & params . uid , & params . gid ) < 1 )
{
{
fprintf ( stderr , " --uid should be : uid[:gid] \n " ) ;
DLOG_ERR ( " --uid should be : uid[:gid] \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1144,14 +1179,14 @@ int main(int argc, char **argv)
case 8 : /* wssize-cutoff */
case 8 : /* wssize-cutoff */
if ( ! parse_cutoff ( optarg , & params . wssize_cutoff , & params . wssize_cutoff_mode ) )
if ( ! parse_cutoff ( optarg , & params . wssize_cutoff , & params . wssize_cutoff_mode ) )
{
{
fprintf ( stderr , " invalid wssize-cutoff value \n " ) ;
DLOG_ERR ( " invalid wssize-cutoff value \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 9 : /* ctrack-timeouts */
case 9 : /* ctrack-timeouts */
if ( sscanf ( optarg , " %u:%u:%u:%u " , & params . ctrack_t_syn , & params . ctrack_t_est , & params . ctrack_t_fin , & params . ctrack_t_udp ) < 3 )
if ( sscanf ( optarg , " %u:%u:%u:%u " , & params . ctrack_t_syn , & params . ctrack_t_est , & params . ctrack_t_fin , & params . ctrack_t_udp ) < 3 )
{
{
fprintf ( stderr , " invalid ctrack-timeouts value \n " ) ;
DLOG_ERR ( " invalid ctrack-timeouts value \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1161,7 +1196,7 @@ int main(int argc, char **argv)
case 11 : /* hostspell */
case 11 : /* hostspell */
if ( strlen ( optarg ) ! = 4 )
if ( strlen ( optarg ) ! = 4 )
{
{
fprintf ( stderr , " hostspell must be exactly 4 chars long \n " ) ;
DLOG_ERR ( " hostspell must be exactly 4 chars long \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
params . hostcase = true ;
params . hostcase = true ;
@ -1196,23 +1231,23 @@ int main(int argc, char **argv)
params . desync_mode2 = desync_mode_from_string ( mode2 ) ;
params . desync_mode2 = desync_mode_from_string ( mode2 ) ;
if ( params . desync_mode0 = = DESYNC_INVALID | | params . desync_mode = = DESYNC_INVALID | | params . desync_mode2 = = DESYNC_INVALID )
if ( params . desync_mode0 = = DESYNC_INVALID | | params . desync_mode = = DESYNC_INVALID | | params . desync_mode2 = = DESYNC_INVALID )
{
{
fprintf ( stderr , " invalid dpi-desync mode \n " ) ;
DLOG_ERR ( " invalid dpi-desync mode \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( mode3 )
if ( mode3 )
{
{
fprintf ( stderr , " invalid desync combo : %s+%s+%s \n " , mode , mode2 , mode3 ) ;
DLOG_ERR ( " invalid desync combo : %s+%s+%s \n " , mode , mode2 , mode3 ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( params . desync_mode2 & & ( desync_only_first_stage ( params . desync_mode ) | | ! ( desync_valid_first_stage ( params . desync_mode ) & & desync_valid_second_stage ( params . desync_mode2 ) ) ) )
if ( params . desync_mode2 & & ( desync_only_first_stage ( params . desync_mode ) | | ! ( desync_valid_first_stage ( params . desync_mode ) & & desync_valid_second_stage ( params . desync_mode2 ) ) ) )
{
{
fprintf ( stderr , " invalid desync combo : %s+%s \n " , mode , mode2 ) ;
DLOG_ERR ( " invalid desync combo : %s+%s \n " , mode , mode2 ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# if defined(__OpenBSD__)
# if defined(__OpenBSD__)
if ( params . desync_mode = = DESYNC_IPFRAG2 | | params . desync_mode2 = = DESYNC_IPFRAG2 )
if ( params . desync_mode = = DESYNC_IPFRAG2 | | params . desync_mode2 = = DESYNC_IPFRAG2 )
{
{
fprintf ( stderr , " OpenBSD has checksum issues with fragmented packets. ipfrag disabled. \n " ) ;
DLOG_ERR ( " OpenBSD has checksum issues with fragmented packets. ipfrag disabled. \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# endif
# endif
@ -1225,11 +1260,11 @@ int main(int argc, char **argv)
if ( sscanf ( optarg , " 0x%X " , & params . desync_fwmark ) < = 0 ) sscanf ( optarg , " %u " , & params . desync_fwmark ) ;
if ( sscanf ( optarg , " 0x%X " , & params . desync_fwmark ) < = 0 ) sscanf ( optarg , " %u " , & params . desync_fwmark ) ;
if ( ! params . desync_fwmark )
if ( ! params . desync_fwmark )
{
{
fprintf ( stderr , " fwmark/sockarg should be decimal or 0xHEX and should not be zero \n " ) ;
DLOG_ERR ( " fwmark/sockarg should be decimal or 0xHEX and should not be zero \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# else
# else
fprintf ( stderr , " fmwark/sockarg not supported in this OS \n " ) ;
DLOG_ERR ( " fmwark/sockarg not supported in this OS \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
# endif
# endif
break ;
break ;
@ -1243,14 +1278,14 @@ int main(int argc, char **argv)
case 18 : /* dpi-desync-autottl */
case 18 : /* dpi-desync-autottl */
if ( ! parse_autottl ( optarg , & params . desync_autottl ) )
if ( ! parse_autottl ( optarg , & params . desync_autottl ) )
{
{
fprintf ( stderr , " dpi-desync-autottl value error \n " ) ;
DLOG_ERR ( " dpi-desync-autottl value error \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 19 : /* dpi-desync-autottl6 */
case 19 : /* dpi-desync-autottl6 */
if ( ! parse_autottl ( optarg , & params . desync_autottl6 ) )
if ( ! parse_autottl ( optarg , & params . desync_autottl6 ) )
{
{
fprintf ( stderr , " dpi-desync-autottl6 value error \n " ) ;
DLOG_ERR ( " dpi-desync-autottl6 value error \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1268,7 +1303,7 @@ int main(int argc, char **argv)
else if ( ! strcmp ( p , " badsum " ) )
else if ( ! strcmp ( p , " badsum " ) )
{
{
# ifdef __OpenBSD__
# ifdef __OpenBSD__
printf ( " \n WARNING !!! OpenBSD may forcibly recompute tcp/udp checksums !!! In this case badsum fooling will not work. \n You should check tcp checksum correctness in tcpdump manually before using badsum. \n \n " ) ;
DLOG_CONDUP ( " \n WARNING !!! OpenBSD may forcibly recompute tcp/udp checksums !!! In this case badsum fooling will not work. \n You should check tcp checksum correctness in tcpdump manually before using badsum. \n \n " ) ;
# endif
# endif
params . desync_fooling_mode | = FOOL_BADSUM ;
params . desync_fooling_mode | = FOOL_BADSUM ;
}
}
@ -1282,7 +1317,7 @@ int main(int argc, char **argv)
params . desync_fooling_mode | = FOOL_HOPBYHOP2 ;
params . desync_fooling_mode | = FOOL_HOPBYHOP2 ;
else if ( strcmp ( p , " none " ) )
else if ( strcmp ( p , " none " ) )
{
{
fprintf ( stderr , " dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum,datanoack,hopbyhop,hopbyhop2 \n " ) ;
DLOG_ERR ( " dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum,datanoack,hopbyhop,hopbyhop2 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
p = e ;
p = e ;
@ -1292,7 +1327,7 @@ int main(int argc, char **argv)
case 21 : /* dpi-desync-repeats */
case 21 : /* dpi-desync-repeats */
if ( sscanf ( optarg , " %u " , & params . desync_repeats ) < 1 | | ! params . desync_repeats | | params . desync_repeats > 20 )
if ( sscanf ( optarg , " %u " , & params . desync_repeats ) < 1 | | ! params . desync_repeats | | params . desync_repeats > 20 )
{
{
fprintf ( stderr , " dpi-desync-repeats must be within 1..20 \n " ) ;
DLOG_ERR ( " dpi-desync-repeats must be within 1..20 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1302,28 +1337,28 @@ int main(int argc, char **argv)
case 23 : /* dpi-desync-split-pos */
case 23 : /* dpi-desync-split-pos */
if ( sscanf ( optarg , " %u " , & params . desync_split_pos ) < 1 | | params . desync_split_pos < 1 )
if ( sscanf ( optarg , " %u " , & params . desync_split_pos ) < 1 | | params . desync_split_pos < 1 )
{
{
fprintf ( stderr , " dpi-desync-split-pos is not valid \n " ) ;
DLOG_ERR ( " dpi-desync-split-pos is not valid \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 24 : /* dpi-desync-split-http-req */
case 24 : /* dpi-desync-split-http-req */
if ( ! parse_httpreqpos ( optarg , & params . desync_split_http_req ) )
if ( ! parse_httpreqpos ( optarg , & params . desync_split_http_req ) )
{
{
fprintf ( stderr , " Invalid argument for dpi-desync-split-http-req \n " ) ;
DLOG_ERR ( " Invalid argument for dpi-desync-split-http-req \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 25 : /* dpi-desync-split-tls */
case 25 : /* dpi-desync-split-tls */
if ( ! parse_tlspos ( optarg , & params . desync_split_tls ) )
if ( ! parse_tlspos ( optarg , & params . desync_split_tls ) )
{
{
fprintf ( stderr , " Invalid argument for dpi-desync-split-tls \n " ) ;
DLOG_ERR ( " Invalid argument for dpi-desync-split-tls \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 26 : /* dpi-desync-split-seqovl */
case 26 : /* dpi-desync-split-seqovl */
if ( sscanf ( optarg , " %u " , & params . desync_seqovl ) < 1 )
if ( sscanf ( optarg , " %u " , & params . desync_seqovl ) < 1 )
{
{
fprintf ( stderr , " dpi-desync-split-seqovl is not valid \n " ) ;
DLOG_ERR ( " dpi-desync-split-seqovl is not valid \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1338,38 +1373,38 @@ int main(int argc, char **argv)
case 28 : /* dpi-desync-ipfrag-pos-tcp */
case 28 : /* dpi-desync-ipfrag-pos-tcp */
if ( sscanf ( optarg , " %u " , & params . desync_ipfrag_pos_tcp ) < 1 | | params . desync_ipfrag_pos_tcp < 1 | | params . desync_ipfrag_pos_tcp > DPI_DESYNC_MAX_FAKE_LEN )
if ( sscanf ( optarg , " %u " , & params . desync_ipfrag_pos_tcp ) < 1 | | params . desync_ipfrag_pos_tcp < 1 | | params . desync_ipfrag_pos_tcp > DPI_DESYNC_MAX_FAKE_LEN )
{
{
fprintf ( stderr , " dpi-desync-ipfrag-pos-tcp must be within 1..%u range \n " , DPI_DESYNC_MAX_FAKE_LEN ) ;
DLOG_ERR ( " dpi-desync-ipfrag-pos-tcp must be within 1..%u range \n " , DPI_DESYNC_MAX_FAKE_LEN ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( params . desync_ipfrag_pos_tcp & 7 )
if ( params . desync_ipfrag_pos_tcp & 7 )
{
{
fprintf ( stderr , " dpi-desync-ipfrag-pos-tcp must be multiple of 8 \n " ) ;
DLOG_ERR ( " dpi-desync-ipfrag-pos-tcp must be multiple of 8 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 29 : /* dpi-desync-ipfrag-pos-udp */
case 29 : /* dpi-desync-ipfrag-pos-udp */
if ( sscanf ( optarg , " %u " , & params . desync_ipfrag_pos_udp ) < 1 | | params . desync_ipfrag_pos_udp < 1 | | params . desync_ipfrag_pos_udp > DPI_DESYNC_MAX_FAKE_LEN )
if ( sscanf ( optarg , " %u " , & params . desync_ipfrag_pos_udp ) < 1 | | params . desync_ipfrag_pos_udp < 1 | | params . desync_ipfrag_pos_udp > DPI_DESYNC_MAX_FAKE_LEN )
{
{
fprintf ( stderr , " dpi-desync-ipfrag-pos-udp must be within 1..%u range \n " , DPI_DESYNC_MAX_FAKE_LEN ) ;
DLOG_ERR ( " dpi-desync-ipfrag-pos-udp must be within 1..%u range \n " , DPI_DESYNC_MAX_FAKE_LEN ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( params . desync_ipfrag_pos_udp & 7 )
if ( params . desync_ipfrag_pos_udp & 7 )
{
{
fprintf ( stderr , " dpi-desync-ipfrag-pos-udp must be multiple of 8 \n " ) ;
DLOG_ERR ( " dpi-desync-ipfrag-pos-udp must be multiple of 8 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 30 : /* dpi-desync-badseq-increments */
case 30 : /* dpi-desync-badseq-increments */
if ( ! parse_badseq_increment ( optarg , & params . desync_badseq_increment ) )
if ( ! parse_badseq_increment ( optarg , & params . desync_badseq_increment ) )
{
{
fprintf ( stderr , " dpi-desync-badseq-increment should be signed decimal or signed 0xHEX \n " ) ;
DLOG_ERR ( " dpi-desync-badseq-increment should be signed decimal or signed 0xHEX \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 31 : /* dpi-desync-badack-increment */
case 31 : /* dpi-desync-badack-increment */
if ( ! parse_badseq_increment ( optarg , & params . desync_badseq_ack_increment ) )
if ( ! parse_badseq_increment ( optarg , & params . desync_badseq_ack_increment ) )
{
{
fprintf ( stderr , " dpi-desync-badack-increment should be signed decimal or signed 0xHEX \n " ) ;
DLOG_ERR ( " dpi-desync-badack-increment should be signed decimal or signed 0xHEX \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1411,7 +1446,7 @@ int main(int argc, char **argv)
case 41 : /* dpi-desync-udplen-increment */
case 41 : /* dpi-desync-udplen-increment */
if ( sscanf ( optarg , " %d " , & params . udplen_increment ) < 1 | | params . udplen_increment > 0x7FFF | | params . udplen_increment < - 0x8000 )
if ( sscanf ( optarg , " %d " , & params . udplen_increment ) < 1 | | params . udplen_increment > 0x7FFF | | params . udplen_increment < - 0x8000 )
{
{
fprintf ( stderr , " dpi-desync-udplen-increment must be integer within -32768..32767 range \n " ) ;
DLOG_ERR ( " dpi-desync-udplen-increment must be integer within -32768..32767 range \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1426,59 +1461,59 @@ int main(int argc, char **argv)
case 43 : /* desync-cutoff */
case 43 : /* desync-cutoff */
if ( ! parse_cutoff ( optarg , & params . desync_cutoff , & params . desync_cutoff_mode ) )
if ( ! parse_cutoff ( optarg , & params . desync_cutoff , & params . desync_cutoff_mode ) )
{
{
fprintf ( stderr , " invalid desync-cutoff value \n " ) ;
DLOG_ERR ( " invalid desync-cutoff value \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 44 : /* desync-start */
case 44 : /* desync-start */
if ( ! parse_cutoff ( optarg , & params . desync_start , & params . desync_start_mode ) )
if ( ! parse_cutoff ( optarg , & params . desync_start , & params . desync_start_mode ) )
{
{
fprintf ( stderr , " invalid desync-start value \n " ) ;
DLOG_ERR ( " invalid desync-start value \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 45 : /* hostlist */
case 45 : /* hostlist */
if ( ! strlist_add ( & params . hostlist_files , optarg ) )
if ( ! strlist_add ( & params . hostlist_files , optarg ) )
{
{
fprintf ( stderr , " strlist_add failed \n " ) ;
DLOG_ERR ( " strlist_add failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 46 : /* hostlist-exclude */
case 46 : /* hostlist-exclude */
if ( ! strlist_add ( & params . hostlist_exclude_files , optarg ) )
if ( ! strlist_add ( & params . hostlist_exclude_files , optarg ) )
{
{
fprintf ( stderr , " strlist_add failed \n " ) ;
DLOG_ERR ( " strlist_add failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 47 : /* hostlist-auto */
case 47 : /* hostlist-auto */
if ( * params . hostlist_auto_filename )
if ( * params . hostlist_auto_filename )
{
{
fprintf ( stderr , " only one auto hostlist is supported \n " ) ;
DLOG_ERR ( " only one auto hostlist is supported \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
{
{
FILE * F = fopen ( optarg , " a+ t " ) ;
FILE * F = fopen ( optarg , " at " ) ;
if ( ! F )
if ( ! F )
{
{
fprintf ( stderr , " cannot create %s \n " , optarg ) ;
DLOG_ERR ( " cannot create %s \n " , optarg ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
bool bGzip = is_gzip ( F ) ;
bool bGzip = is_gzip ( F ) ;
fclose ( F ) ;
fclose ( F ) ;
if ( bGzip )
if ( bGzip )
{
{
fprintf ( stderr , " gzipped auto hostlists are not supported \n " ) ;
DLOG_ERR ( " gzipped auto hostlists are not supported \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# ifndef __CYGWIN__
# ifndef __CYGWIN__
if ( params . droproot & & chown ( optarg , params . uid , - 1 ) )
if ( params . droproot & & chown ( optarg , params . uid , - 1 ) )
fprintf ( stderr , " could not chown %s. auto hostlist file may not be writable after privilege drop \n " , optarg ) ;
DLOG_ERR ( " could not chown %s. auto hostlist file may not be writable after privilege drop \n " , optarg ) ;
# endif
# endif
}
}
if ( ! strlist_add ( & params . hostlist_files , optarg ) )
if ( ! strlist_add ( & params . hostlist_files , optarg ) )
{
{
fprintf ( stderr , " strlist_add failed \n " ) ;
DLOG_ERR ( " strlist_add failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
strncpy ( params . hostlist_auto_filename , optarg , sizeof ( params . hostlist_auto_filename ) ) ;
strncpy ( params . hostlist_auto_filename , optarg , sizeof ( params . hostlist_auto_filename ) ) ;
@ -1488,7 +1523,7 @@ int main(int argc, char **argv)
params . hostlist_auto_fail_threshold = ( uint8_t ) atoi ( optarg ) ;
params . hostlist_auto_fail_threshold = ( uint8_t ) atoi ( optarg ) ;
if ( params . hostlist_auto_fail_threshold < 1 | | params . hostlist_auto_fail_threshold > 20 )
if ( params . hostlist_auto_fail_threshold < 1 | | params . hostlist_auto_fail_threshold > 20 )
{
{
fprintf ( stderr , " auto hostlist fail threshold must be within 1..20 \n " ) ;
DLOG_ERR ( " auto hostlist fail threshold must be within 1..20 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1496,7 +1531,7 @@ int main(int argc, char **argv)
params . hostlist_auto_fail_time = ( uint8_t ) atoi ( optarg ) ;
params . hostlist_auto_fail_time = ( uint8_t ) atoi ( optarg ) ;
if ( params . hostlist_auto_fail_time < 1 )
if ( params . hostlist_auto_fail_time < 1 )
{
{
fprintf ( stderr , " auto hostlist fail time is not valid \n " ) ;
DLOG_ERR ( " auto hostlist fail time is not valid \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1504,7 +1539,7 @@ int main(int argc, char **argv)
params . hostlist_auto_retrans_threshold = ( uint8_t ) atoi ( optarg ) ;
params . hostlist_auto_retrans_threshold = ( uint8_t ) atoi ( optarg ) ;
if ( params . hostlist_auto_retrans_threshold < 2 | | params . hostlist_auto_retrans_threshold > 10 )
if ( params . hostlist_auto_retrans_threshold < 2 | | params . hostlist_auto_retrans_threshold > 10 )
{
{
fprintf ( stderr , " auto hostlist fail threshold must be within 2..10 \n " ) ;
DLOG_ERR ( " auto hostlist fail threshold must be within 2..10 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1513,13 +1548,13 @@ int main(int argc, char **argv)
FILE * F = fopen ( optarg , " a+t " ) ;
FILE * F = fopen ( optarg , " a+t " ) ;
if ( ! F )
if ( ! F )
{
{
fprintf ( stderr , " cannot create %s \n " , optarg ) ;
DLOG_ERR ( " cannot create %s \n " , optarg ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
fclose ( F ) ;
fclose ( F ) ;
# ifndef __CYGWIN__
# ifndef __CYGWIN__
if ( params . droproot & & chown ( optarg , params . uid , - 1 ) )
if ( params . droproot & & chown ( optarg , params . uid , - 1 ) )
fprintf ( stderr , " could not chown %s. auto hostlist debug log may not be writable after privilege drop \n " , optarg ) ;
DLOG_ERR ( " could not chown %s. auto hostlist debug log may not be writable after privilege drop \n " , optarg ) ;
# endif
# endif
strncpy ( params . hostlist_auto_debuglog , optarg , sizeof ( params . hostlist_auto_debuglog ) ) ;
strncpy ( params . hostlist_auto_debuglog , optarg , sizeof ( params . hostlist_auto_debuglog ) ) ;
params . hostlist_auto_debuglog [ sizeof ( params . hostlist_auto_debuglog ) - 1 ] = ' \0 ' ;
params . hostlist_auto_debuglog [ sizeof ( params . hostlist_auto_debuglog ) - 1 ] = ' \0 ' ;
@ -1536,14 +1571,14 @@ int main(int argc, char **argv)
case 52 : /* wf-iface */
case 52 : /* wf-iface */
if ( ! sscanf ( optarg , " %u.%u " , & IfIdx , & SubIfIdx ) )
if ( ! sscanf ( optarg , " %u.%u " , & IfIdx , & SubIfIdx ) )
{
{
fprintf ( stderr , " bad value for --wf-iface \n " ) ;
DLOG_ERR ( " bad value for --wf-iface \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
case 53 : /* wf-l3 */
case 53 : /* wf-l3 */
if ( ! wf_make_l3 ( optarg , & wf_ipv4 , & wf_ipv6 ) )
if ( ! wf_make_l3 ( optarg , & wf_ipv4 , & wf_ipv6 ) )
{
{
fprintf ( stderr , " bad value for --wf-l3 \n " ) ;
DLOG_ERR ( " bad value for --wf-l3 \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1552,7 +1587,7 @@ int main(int argc, char **argv)
if ( ! wf_make_pf ( optarg , " tcp " , " SrcPort " , wf_pf_tcp_src , sizeof ( wf_pf_tcp_src ) ) | |
if ( ! wf_make_pf ( optarg , " tcp " , " SrcPort " , wf_pf_tcp_src , sizeof ( wf_pf_tcp_src ) ) | |
! wf_make_pf ( optarg , " tcp " , " DstPort " , wf_pf_tcp_dst , sizeof ( wf_pf_tcp_dst ) ) )
! wf_make_pf ( optarg , " tcp " , " DstPort " , wf_pf_tcp_dst , sizeof ( wf_pf_tcp_dst ) ) )
{
{
fprintf ( stderr , " bad value for --wf-tcp \n " ) ;
DLOG_ERR ( " bad value for --wf-tcp \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1561,7 +1596,7 @@ int main(int argc, char **argv)
if ( ! wf_make_pf ( optarg , " udp " , " SrcPort " , wf_pf_udp_src , sizeof ( wf_pf_udp_src ) ) | |
if ( ! wf_make_pf ( optarg , " udp " , " SrcPort " , wf_pf_udp_src , sizeof ( wf_pf_udp_src ) ) | |
! wf_make_pf ( optarg , " udp " , " DstPort " , wf_pf_udp_dst , sizeof ( wf_pf_udp_dst ) ) )
! wf_make_pf ( optarg , " udp " , " DstPort " , wf_pf_udp_dst , sizeof ( wf_pf_udp_dst ) ) )
{
{
fprintf ( stderr , " bad value for --wf-udp \n " ) ;
DLOG_ERR ( " bad value for --wf-udp \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
break ;
break ;
@ -1593,7 +1628,7 @@ int main(int argc, char **argv)
if ( e ) * e + + = 0 ;
if ( e ) * e + + = 0 ;
if ( * p & & ! strlist_add ( & params . ssid_filter , p ) )
if ( * p & & ! strlist_add ( & params . ssid_filter , p ) )
{
{
fprintf ( stderr , " strlist_add failed \n " ) ;
DLOG_ERR ( " strlist_add failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
p = e ;
p = e ;
@ -1611,7 +1646,7 @@ int main(int argc, char **argv)
if ( e ) * e + + = 0 ;
if ( e ) * e + + = 0 ;
if ( * p & & ! strlist_add ( & params . nlm_filter , p ) )
if ( * p & & ! strlist_add ( & params . nlm_filter , p ) )
{
{
fprintf ( stderr , " strlist_add failed \n " ) ;
DLOG_ERR ( " strlist_add failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
p = e ;
p = e ;
@ -1622,7 +1657,7 @@ int main(int argc, char **argv)
case 60 : /* nlm-list */
case 60 : /* nlm-list */
if ( ! nlm_list ( optarg & & ! strcmp ( optarg , " all " ) ) )
if ( ! nlm_list ( optarg & & ! strcmp ( optarg , " all " ) ) )
{
{
fprintf ( stderr , " could not get list of NLM networks \n " ) ;
DLOG_ERR ( " could not get list of NLM networks \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
exit_clean ( 0 ) ;
exit_clean ( 0 ) ;
@ -1631,16 +1666,19 @@ int main(int argc, char **argv)
}
}
}
}
if ( params . debug & & params . debug_target = = LOG_TARGET_SYSLOG )
openlog ( progname , LOG_PID , LOG_USER ) ;
# ifdef __linux__
# ifdef __linux__
if ( params . qnum < 0 )
if ( params . qnum < 0 )
{
{
fprintf ( stderr , " Need queue number (--qnum) \n " ) ;
DLOG_ERR ( " Need queue number (--qnum) \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# elif defined(BSD)
# elif defined(BSD)
if ( ! params . port )
if ( ! params . port )
{
{
fprintf ( stderr , " Need divert port (--port) \n " ) ;
DLOG_ERR ( " Need divert port (--port) \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
# elif defined(__CYGWIN__)
# elif defined(__CYGWIN__)
@ -1648,26 +1686,26 @@ int main(int argc, char **argv)
{
{
if ( ! * wf_pf_tcp_src & & ! * wf_pf_udp_src )
if ( ! * wf_pf_tcp_src & & ! * wf_pf_udp_src )
{
{
fprintf ( stderr , " windivert filter : must specify port filter \n " ) ;
DLOG_ERR ( " windivert filter : must specify port filter \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( ! wf_make_filter ( windivert_filter , sizeof ( windivert_filter ) , IfIdx , SubIfIdx , wf_ipv4 , wf_ipv6 , wf_pf_tcp_src , wf_pf_tcp_dst , wf_pf_udp_src , wf_pf_udp_dst ) )
if ( ! wf_make_filter ( windivert_filter , sizeof ( windivert_filter ) , IfIdx , SubIfIdx , wf_ipv4 , wf_ipv6 , wf_pf_tcp_src , wf_pf_tcp_dst , wf_pf_udp_src , wf_pf_udp_dst ) )
{
{
fprintf ( stderr , " windivert filter : could not make filter \n " ) ;
DLOG_ERR ( " windivert filter : could not make filter \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
}
}
DLOG ( " windivert filter size: %zu \n windivert filter: \n %s \n " , strlen ( windivert_filter ) , windivert_filter )
DLOG ( " windivert filter size: %zu \n windivert filter: \n %s \n " , strlen ( windivert_filter ) , windivert_filter ) ;
if ( * wf_save_file )
if ( * wf_save_file )
{
{
if ( save_file ( wf_save_file , windivert_filter , strlen ( windivert_filter ) ) )
if ( save_file ( wf_save_file , windivert_filter , strlen ( windivert_filter ) ) )
{
{
printf ( " windivert filter: raw filter saved to %s \n " , wf_save_file ) ;
DLOG_ERR ( " windivert filter: raw filter saved to %s \n " , wf_save_file ) ;
exit_clean ( 0 ) ;
exit_clean ( 0 ) ;
}
}
else
else
{
{
fprintf ( stderr , " windivert filter: could not save raw filter to %s \n " , wf_save_file ) ;
DLOG_ERR ( " windivert filter: could not save raw filter to %s \n " , wf_save_file ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
}
}
@ -1680,7 +1718,7 @@ int main(int argc, char **argv)
if ( hMutexArg & & GetLastError ( ) = = ERROR_ALREADY_EXISTS )
if ( hMutexArg & & GetLastError ( ) = = ERROR_ALREADY_EXISTS )
{
{
CloseHandle ( hMutexArg ) ; hMutexArg = NULL ;
CloseHandle ( hMutexArg ) ; hMutexArg = NULL ;
fprintf ( stderr , " A copy of winws is already running with the same filter \n " ) ;
DLOG_ERR ( " A copy of winws is already running with the same filter \n " ) ;
goto exiterr ;
goto exiterr ;
}
}
@ -1691,22 +1729,22 @@ int main(int argc, char **argv)
if ( params . desync_ttl6 = = 0xFF ) params . desync_ttl6 = params . desync_ttl ;
if ( params . desync_ttl6 = = 0xFF ) params . desync_ttl6 = params . desync_ttl ;
if ( ! AUTOTTL_ENABLED ( params . desync_autottl6 ) ) params . desync_autottl6 = params . desync_autottl ;
if ( ! AUTOTTL_ENABLED ( params . desync_autottl6 ) ) params . desync_autottl6 = params . desync_autottl ;
if ( AUTOTTL_ENABLED ( params . desync_autottl ) )
if ( AUTOTTL_ENABLED ( params . desync_autottl ) )
DLOG ( " autottl ipv4 %u:%u-%u \n " , params . desync_autottl . delta , params . desync_autottl . min , params . desync_autottl . max )
DLOG ( " autottl ipv4 %u:%u-%u \n " , params . desync_autottl . delta , params . desync_autottl . min , params . desync_autottl . max ) ;
if ( AUTOTTL_ENABLED ( params . desync_autottl6 ) )
if ( AUTOTTL_ENABLED ( params . desync_autottl6 ) )
DLOG ( " autottl ipv6 %u:%u-%u \n " , params . desync_autottl6 . delta , params . desync_autottl6 . min , params . desync_autottl6 . max )
DLOG ( " autottl ipv6 %u:%u-%u \n " , params . desync_autottl6 . delta , params . desync_autottl6 . min , params . desync_autottl6 . max ) ;
if ( params . desync_split_tls = = tlspos_none & & params . desync_split_pos ) params . desync_split_tls = tlspos_pos ;
if ( params . desync_split_tls = = tlspos_none & & params . desync_split_pos ) params . desync_split_tls = tlspos_pos ;
if ( params . desync_split_http_req = = httpreqpos_none & & params . desync_split_pos ) params . desync_split_http_req = httpreqpos_pos ;
if ( params . desync_split_http_req = = httpreqpos_none & & params . desync_split_pos ) params . desync_split_http_req = httpreqpos_pos ;
if ( ! LoadIncludeHostLists ( ) )
if ( ! LoadIncludeHostLists ( ) )
{
{
fprintf ( stderr , " Include hostlist load failed \n " ) ;
DLOG_ERR ( " Include hostlist load failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
if ( * params . hostlist_auto_filename )
if ( * params . hostlist_auto_filename )
NonEmptyHostlist ( & params . hostlist ) ;
NonEmptyHostlist ( & params . hostlist ) ;
if ( ! LoadExcludeHostLists ( ) )
if ( ! LoadExcludeHostLists ( ) )
{
{
fprintf ( stderr , " Exclude hostlist load failed \n " ) ;
DLOG_ERR ( " Exclude hostlist load failed \n " ) ;
exit_clean ( 1 ) ;
exit_clean ( 1 ) ;
}
}
@ -1714,11 +1752,11 @@ int main(int argc, char **argv)
if ( * pidfile & & ! writepid ( pidfile ) )
if ( * pidfile & & ! writepid ( pidfile ) )
{
{
fprintf ( stderr , " could not write pidfile \n " ) ;
DLOG_ERR ( " could not write pidfile \n " ) ;
goto exiterr ;
goto exiterr ;
}
}
DLOG ( " initializing conntrack with timeouts tcp=%u:%u:%u udp=%u \n " , params . ctrack_t_syn , params . ctrack_t_est , params . ctrack_t_fin , params . ctrack_t_udp )
DLOG ( " initializing conntrack with timeouts tcp=%u:%u:%u udp=%u \n " , params . ctrack_t_syn , params . ctrack_t_est , params . ctrack_t_fin , params . ctrack_t_udp ) ;
ConntrackPoolInit ( & params . conntrack , 10 , params . ctrack_t_syn , params . ctrack_t_est , params . ctrack_t_fin , params . ctrack_t_udp ) ;
ConntrackPoolInit ( & params . conntrack , 10 , params . ctrack_t_syn , params . ctrack_t_est , params . ctrack_t_fin , params . ctrack_t_udp ) ;
# ifdef __linux__
# ifdef __linux__