diff --git a/nfq/darkmagic.c b/nfq/darkmagic.c index a92a367..a15de0a 100644 --- a/nfq/darkmagic.c +++ b/nfq/darkmagic.c @@ -699,7 +699,7 @@ static void str_srcdst_ip(char *s, size_t s_len, const void *saddr,const void *d inet_ntop(AF_INET, daddr, d_ip, sizeof(d_ip)); snprintf(s,s_len,"%s => %s",s_ip,d_ip); } -static void str_ip(char *s, size_t s_len, const struct ip *ip) +void str_ip(char *s, size_t s_len, const struct ip *ip) { char ss[35],s_proto[16]; str_srcdst_ip(ss,sizeof(ss),&ip->ip_src,&ip->ip_dst); @@ -712,7 +712,7 @@ void print_ip(const struct ip *ip) str_ip(s,sizeof(s),ip); printf("%s",s); } -static void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr) +void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr) { char s_ip[40],d_ip[40]; *s_ip=*d_ip=0; @@ -720,7 +720,7 @@ static void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void * inet_ntop(AF_INET6, daddr, d_ip, sizeof(d_ip)); snprintf(s,s_len,"%s => %s",s_ip,d_ip); } -static void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint8_t proto) +void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint8_t proto) { char ss[83],s_proto[16]; str_srcdst_ip6(ss,sizeof(ss),&ip6hdr->ip6_src,&ip6hdr->ip6_dst); @@ -733,7 +733,7 @@ void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto) str_ip6hdr(s,sizeof(s),ip6hdr,proto); printf("%s",s); } -static void str_tcphdr(char *s, size_t s_len, const struct tcphdr *tcphdr) +void str_tcphdr(char *s, size_t s_len, const struct tcphdr *tcphdr) { char flags[7],*f=flags; if (tcphdr->th_flags & TH_SYN) *f++='S'; @@ -751,7 +751,7 @@ void print_tcphdr(const struct tcphdr *tcphdr) str_tcphdr(s,sizeof(s),tcphdr); printf("%s",s); } -static void str_udphdr(char *s, size_t s_len, const struct udphdr *udphdr) +void str_udphdr(char *s, size_t s_len, const struct udphdr *udphdr) { snprintf(s,s_len,"sport=%u dport=%u",htons(udphdr->uh_sport),htons(udphdr->uh_dport)); } @@ -937,11 +937,11 @@ void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor) scale_factor_old=scale[2]; // do not allow increasing scale factor if (scale_factor>=scale_factor_old) - DLOG("Scale factor %u unchanged\n", scale_factor_old) + DLOG("Scale factor %u unchanged\n", scale_factor_old); else { scale[2]=scale_factor; - DLOG("Scale factor change %u => %u\n", scale_factor_old, scale_factor) + DLOG("Scale factor change %u => %u\n", scale_factor_old, scale_factor); } } } @@ -953,7 +953,7 @@ void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_fac winsize_old = htons(tcp->th_win); // << scale_factor; tcp->th_win = htons(winsize); - DLOG("Window size change %u => %u\n", winsize_old, winsize) + DLOG("Window size change %u => %u\n", winsize_old, winsize); tcp_rewrite_wscale(tcp, scale_factor); } @@ -1342,10 +1342,10 @@ static HANDLE windivert_init_filter(const char *filter, UINT64 flags) FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, w_win32_error, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPSTR)&errormessage, 0, NULL); - fprintf(stderr, "windivert: error opening filter: %s", errormessage); + DLOG_ERR("windivert: error opening filter: %s", errormessage); LocalFree(errormessage); if (w_win32_error == ERROR_INVALID_IMAGE_HASH) - fprintf(stderr,"windivert: try to disable secure boot and install OS patches\n"); + DLOG_ERR("windivert: try to disable secure boot and install OS patches\n"); return NULL; } @@ -1592,14 +1592,14 @@ static bool set_socket_fwmark(int sock, uint32_t fwmark) #ifdef SO_USER_COOKIE if (setsockopt(sock, SOL_SOCKET, SO_USER_COOKIE, &fwmark, sizeof(fwmark)) == -1) { - perror("rawsend: setsockopt(SO_USER_COOKIE)"); + DLOG_PERROR("rawsend: setsockopt(SO_USER_COOKIE)"); return false; } #endif #elif defined(__linux__) if (setsockopt(sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1) { - perror("rawsend: setsockopt(SO_MARK)"); + DLOG_PERROR("rawsend: setsockopt(SO_MARK)"); return false; } @@ -1631,28 +1631,28 @@ static int rawsend_socket(sa_family_t family) #endif if (*sock==-1) { - perror("rawsend: socket()"); + DLOG_PERROR("rawsend: socket()"); return -1; } #ifdef __linux__ if (setsockopt(*sock, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) == -1) { - perror("rawsend: setsockopt(SO_PRIORITY)"); + DLOG_PERROR("rawsend: setsockopt(SO_PRIORITY)"); goto exiterr; } if (family==AF_INET && setsockopt(*sock, IPPROTO_IP, IP_NODEFRAG, &yes, sizeof(yes)) == -1) { - perror("rawsend: setsockopt(IP_NODEFRAG)"); + DLOG_PERROR("rawsend: setsockopt(IP_NODEFRAG)"); goto exiterr; } if (family==AF_INET && setsockopt(*sock, IPPROTO_IP, IP_FREEBIND, &yes, sizeof(yes)) == -1) { - perror("rawsend: setsockopt(IP_FREEBIND)"); + DLOG_PERROR("rawsend: setsockopt(IP_FREEBIND)"); goto exiterr; } if (family==AF_INET6 && setsockopt(*sock, SOL_IPV6, IPV6_FREEBIND, &yes, sizeof(yes)) == -1) { - //perror("rawsend: setsockopt(IPV6_FREEBIND)"); + //DLOG_PERROR("rawsend: setsockopt(IPV6_FREEBIND)"); // dont error because it's supported only from kernel 4.15 } #endif @@ -1686,7 +1686,7 @@ bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifout,const bytes = rawsend_sendto_divert(dst->sa_family,sock,data,len); if (bytes==-1) { - perror("rawsend: sendto_divert"); + DLOG_PERROR("rawsend: sendto_divert"); return false; } return true; @@ -1711,19 +1711,19 @@ bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifout,const //printf("family %u dev %s bind : ", dst->sa_family, ifout); print_sockaddr((struct sockaddr *)&sa_src); printf("\n"); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifout, ifout ? strlen(ifout)+1 : 0) == -1) { - perror("rawsend: setsockopt(SO_BINDTODEVICE)"); + DLOG_PERROR("rawsend: setsockopt(SO_BINDTODEVICE)"); return false; } if (bind(sock, (const struct sockaddr*)&sa_src, dst->sa_family==AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))) { - perror("rawsend: bind (ignoring)"); + DLOG_PERROR("rawsend: bind (ignoring)"); // do not fail. this can happen regardless of IP_FREEBIND // rebind to any address memset(&sa_src,0,sizeof(sa_src)); sa_src.ss_family = dst->sa_family; if (bind(sock, (const struct sockaddr*)&sa_src, dst->sa_family==AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))) { - perror("rawsend: bind to any"); + DLOG_PERROR("rawsend: bind to any"); return false; } } @@ -1734,7 +1734,7 @@ nofix: bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen); if (bytes==-1) { - perror("rawsend: sendto"); + DLOG_PERROR("rawsend: sendto"); return false; } return true; diff --git a/nfq/darkmagic.h b/nfq/darkmagic.h index 7a9a0b4..f824c75 100644 --- a/nfq/darkmagic.h +++ b/nfq/darkmagic.h @@ -187,6 +187,11 @@ void print_ip(const struct ip *ip); void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto); void print_tcphdr(const struct tcphdr *tcphdr); void print_udphdr(const struct udphdr *udphdr); +void str_ip(char *s, size_t s_len, const struct ip *ip); +void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint8_t proto); +void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr); +void str_tcphdr(char *s, size_t s_len, const struct tcphdr *tcphdr); +void str_udphdr(char *s, size_t s_len, const struct udphdr *udphdr); bool proto_check_ipv4(const uint8_t *data, size_t len); void proto_skip_ipv4(uint8_t **data, size_t *len); diff --git a/nfq/desync.c b/nfq/desync.c index 761254f..7381818 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -253,7 +253,7 @@ static void auto_hostlist_failed(const char *hostname) } if (!append_to_list_file(params.hostlist_auto_filename, hostname)) { - perror("write to auto hostlist:"); + DLOG_PERROR("write to auto hostlist:"); return; } params.hostlist_auto_mod_time = file_mod_time(params.hostlist_auto_filename); @@ -279,7 +279,7 @@ static bool send_delayed(t_ctrack *ctrack) { if (!rawpacket_queue_empty(&ctrack->delayed)) { - DLOG("SENDING %u delayed packets\n", rawpacket_queue_count(&ctrack->delayed)) + DLOG("SENDING %u delayed packets\n", rawpacket_queue_count(&ctrack->delayed)); return rawsend_queue(&ctrack->delayed); } return true; @@ -316,13 +316,13 @@ static bool reasm_feed(t_ctrack *ctrack, t_reassemble *reasm, uint8_t proto, con uint32_t seq = (proto==IPPROTO_TCP) ? ctrack->seq_last : (uint32_t)reasm->size_present; if (ReasmFeed(reasm, seq, data_payload, len_payload)) { - DLOG("reassemble : feeding data payload size=%zu. now we have %zu/%zu\n", len_payload,reasm->size_present,reasm->size) + DLOG("reassemble : feeding data payload size=%zu. now we have %zu/%zu\n", len_payload,reasm->size_present,reasm->size); return true; } else { ReasmClear(reasm); - DLOG("reassemble session failed\n") + DLOG("reassemble session failed\n"); send_delayed(ctrack); } } @@ -363,7 +363,7 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, struct // we also can't use fooling because DPI would accept fooled packets if (ctrack && ctrack->pcounter_orig==1) { - DLOG("applying linux postnat conntrack workaround\n") + DLOG("applying linux postnat conntrack workaround\n"); if (proto==IPPROTO_UDP && udp && len_pkt) { // make malformed udp packet with zero length and invalid checksum @@ -462,13 +462,13 @@ static size_t pos_normalize(size_t split_pos, size_t reasm_offset, size_t len_pa if (rsplit_pos) { if (split_pos==rsplit_pos) - DLOG("split pos %zu\n",split_pos) + DLOG("split pos %zu\n",split_pos); else { if (split_pos) - DLOG("split pos was normalized to packet data offset : %zu -> %zu\n",rsplit_pos,split_pos) + DLOG("split pos was normalized to packet data offset : %zu -> %zu\n",rsplit_pos,split_pos); else - DLOG("split pos %zu is outside of this packet %zu-%zu\n",rsplit_pos,reasm_offset,reasm_offset+len_payload) + DLOG("split pos %zu is outside of this packet %zu-%zu\n",rsplit_pos,reasm_offset,reasm_offset+len_payload); } } return split_pos; @@ -530,9 +530,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { ctrack->autottl = autottl_guess(ttl_orig, attl); if (ctrack->autottl) - DLOG("autottl: guessed %u\n",ctrack->autottl) + DLOG("autottl: guessed %u\n",ctrack->autottl); else - DLOG("autottl: could not guess\n") + DLOG("autottl: could not guess\n"); } } @@ -556,11 +556,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint bFail = HttpReplyLooksLikeDPIRedirect(data_payload, len_payload, ctrack->hostname); if (bFail) { - DLOG("redirect to another domain detected. possibly DPI redirect.\n") + DLOG("redirect to another domain detected. possibly DPI redirect.\n"); HOSTLIST_DEBUGLOG_APPEND("%s : redirect to another domain", ctrack->hostname); } else - DLOG("local or in-domain redirect detected. it's not a DPI redirect.\n") + DLOG("local or in-domain redirect detected. it's not a DPI redirect.\n"); } else { @@ -647,7 +647,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint return verdict; } DLOG("sending SYN with fake data : "); - hexdump_limited_dlog(params.fake_syndata,params.fake_syndata_size,PKTDATA_MAXDUMP); DLOG("\n") + hexdump_limited_dlog(params.fake_syndata,params.fake_syndata_size,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; verdict = ct_new_postnat_fix_tcp(ctrack, ip, ip6hdr, tcphdr); @@ -693,7 +693,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if ((bIsHttp = IsHttp(rdata_payload,rlen_payload))) { - DLOG("packet contains HTTP request\n") + DLOG("packet contains HTTP request\n"); if (ctrack && !ctrack->l7proto) ctrack->l7proto = HTTP; // we do not reassemble http @@ -707,7 +707,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint bHaveHost=HttpExtractHost(rdata_payload,rlen_payload,host,sizeof(host)); if (!bHaveHost) { - DLOG("not applying tampering to HTTP without Host:\n") + DLOG("not applying tampering to HTTP without Host:\n"); return verdict; } } @@ -728,7 +728,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint else if (IsTLSClientHello(rdata_payload,rlen_payload,TLS_PARTIALS_ENABLE)) { bool bReqFull = IsTLSRecordFull(rdata_payload,rlen_payload); - DLOG(bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n") + DLOG(bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n"); bHaveHost=TLSHelloExtractHost(rdata_payload,rlen_payload,host,sizeof(host),TLS_PARTIALS_ENABLE); @@ -787,7 +787,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (params.desync_skip_nosni && !bHaveHost) { - DLOG("not applying tampering to TLS ClientHello without hostname in the SNI\n") + DLOG("not applying tampering to TLS ClientHello without hostname in the SNI\n"); reasm_orig_cancel(ctrack); return verdict; } @@ -812,7 +812,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost) { - DLOG("hostname: %s\n",host) + DLOG("hostname: %s\n",host); if (params.hostlist || params.hostlist_exclude) { bool bBypass; @@ -830,7 +830,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint else ctrack_stop_retrans_counter(ctrack_replay); } - DLOG("not applying tampering to this request\n") + DLOG("not applying tampering to this request\n"); return verdict; } } @@ -839,7 +839,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (!bKnownProtocol) { if (!params.desync_any_proto) return verdict; - DLOG("applying tampering to unknown protocol\n") + DLOG("applying tampering to unknown protocol\n"); fake = params.fake_unknown; fake_size = params.fake_unknown_size; } @@ -848,7 +848,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { if (params.hostcase) { - DLOG("modifying Host: => %c%c%c%c:\n", params.hostspell[0], params.hostspell[1], params.hostspell[2], params.hostspell[3]) + DLOG("modifying Host: => %c%c%c%c:\n", params.hostspell[0], params.hostspell[1], params.hostspell[2], params.hostspell[3]); memcpy(phost + 2, params.hostspell, 4); verdict=VERDICT_MODIFY; } @@ -864,7 +864,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint (pua = (uint8_t*)memmem(data_payload, len_payload, "\r\nUser-Agent: ", 14)) && (pua = (uint8_t*)memmem(pua + 1, len_payload - (pua - data_payload) - 1, "\r\n", 2))) { - DLOG("removing space after Host: and adding it to User-Agent:\n") + DLOG("removing space after Host: and adding it to User-Agent:\n"); if (pua > phost) { memmove(phost + 7, phost + 8, pua - phost - 8); @@ -883,11 +883,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (params.debug) { - printf("dpi desync src="); - print_sockaddr((struct sockaddr *)&src); - printf(" dst="); - print_sockaddr((struct sockaddr *)&dst); - printf("\n"); + char s1[48],s2[48]; + ntop46_port((struct sockaddr *)&src, s1, sizeof(s1)); + ntop46_port((struct sockaddr *)&dst, s2, sizeof(s2)); + DLOG("dpi desync src=%s dst=%s\n",s1,s2); } if (!split_pos || split_pos>rlen_payload) split_pos=1; @@ -922,7 +921,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint return verdict; } DLOG("sending fake request : "); - hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n") + hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n"); b = true; break; case DESYNC_RST: @@ -968,7 +967,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint return verdict; if (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_tcp(params.desync_mode2)) { - DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", *len_pkt, len_payload) + DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", *len_pkt, len_payload); verdict_tcp_csum_fix(verdict, tcphdr, transport_len, ip, ip6hdr); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, *len_pkt)) return verdict; @@ -989,7 +988,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (params.desync_seqovl>=split_pos) { - DLOG("seqovl>=split_pos. desync is not possible.\n") + DLOG("seqovl>=split_pos. desync is not possible.\n"); return verdict; } @@ -1000,7 +999,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint seg_len = len_payload-split_pos+params.desync_seqovl; if (seg_len>sizeof(fakeseg)) { - DLOG("seqovl is too large\n") + DLOG("seqovl is too large\n"); return verdict; } fill_pattern(fakeseg,params.desync_seqovl,params.seqovl_pattern,sizeof(params.seqovl_pattern)); @@ -1017,8 +1016,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment, seg, seg_len, pkt1, &pkt1_len)) return verdict; - DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu seqovl=%u : ",split_pos,len_payload-1, len_payload-split_pos, params.desync_seqovl) - hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu seqovl=%u : ",split_pos,len_payload-1, len_payload-split_pos, params.desync_seqovl); + hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; } @@ -1031,8 +1030,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_fake,params.desync_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment, zeropkt, split_pos, fakeseg, &seg_len)) return verdict; - DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos) - hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len)) return verdict; } @@ -1042,15 +1041,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment, data_payload, split_pos, pkt1, &pkt1_len)) return verdict; - DLOG("sending 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos) - hexdump_limited_dlog(data_payload,split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(data_payload,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; if (desync_mode==DESYNC_DISORDER) { - DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos) - hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len)) return verdict; } @@ -1072,8 +1071,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_fake,params.desync_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment, zeropkt, split_pos, fakeseg, &fakeseg_len)) return verdict; - DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos) - hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) return verdict; } @@ -1083,7 +1082,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint seg_len = split_pos+params.desync_seqovl; if (seg_len>sizeof(ovlseg)) { - DLOG("seqovl is too large") + DLOG("seqovl is too large"); return verdict; } fill_pattern(ovlseg,params.desync_seqovl,params.seqovl_pattern,sizeof(params.seqovl_pattern)); @@ -1100,15 +1099,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment, seg, seg_len, pkt1, &pkt1_len)) return verdict; - DLOG("sending 1st tcp segment 0-%zu len=%zu seqovl=%u : ",split_pos-1, split_pos, params.desync_seqovl) - hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending 1st tcp segment 0-%zu len=%zu seqovl=%u : ",split_pos-1, split_pos, params.desync_seqovl); + hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; if (desync_mode==DESYNC_SPLIT) { - DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos) - hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) return verdict; } @@ -1119,8 +1118,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment, data_payload+split_pos, len_payload-split_pos, pkt1, &pkt1_len)) return verdict; - DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,len_payload-1, len_payload-split_pos) - hexdump_limited_dlog(data_payload+split_pos,len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n") + DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,len_payload-1, len_payload-split_pos); + hexdump_limited_dlog(data_payload+split_pos,len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; } @@ -1158,13 +1157,13 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (!ip_frag(pkt_orig, pkt_orig_len, ipfrag_pos, ident, pkt1, &pkt1_len, pkt2, &pkt2_len)) return verdict; - DLOG("sending 1st ip fragment 0-%zu ip_payload_len=%zu : ", ipfrag_pos-1, ipfrag_pos) - hexdump_limited_dlog(pkt1,pkt1_len,IP_MAXDUMP); DLOG("\n") + DLOG("sending 1st ip fragment 0-%zu ip_payload_len=%zu : ", ipfrag_pos-1, ipfrag_pos); + hexdump_limited_dlog(pkt1,pkt1_len,IP_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; - DLOG("sending 2nd ip fragment %zu-%zu ip_payload_len=%zu : ", ipfrag_pos, transport_len-1, transport_len-ipfrag_pos) - hexdump_limited_dlog(pkt2,pkt2_len,IP_MAXDUMP); DLOG("\n") + DLOG("sending 2nd ip fragment %zu-%zu ip_payload_len=%zu : ", ipfrag_pos, transport_len-1, transport_len-ipfrag_pos); + hexdump_limited_dlog(pkt2,pkt2_len,IP_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt2, pkt2_len)) return verdict; @@ -1185,12 +1184,12 @@ static bool quic_reasm_cancel(t_ctrack *ctrack, const char *reason) reasm_orig_cancel(ctrack); if (params.desync_any_proto) { - DLOG("%s. applying tampering because desync_any_proto is set\n",reason) + DLOG("%s. applying tampering because desync_any_proto is set\n",reason); return true; } else { - DLOG("%s. not applying tampering because desync_any_proto is not set\n",reason) + DLOG("%s. not applying tampering because desync_any_proto is not set\n",reason); return false; } } @@ -1259,7 +1258,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (IsQUICInitial(data_payload,len_payload)) { - DLOG("packet contains QUIC initial\n") + DLOG("packet contains QUIC initial\n"); if (ctrack && !ctrack->l7proto) ctrack->l7proto = QUIC; uint8_t clean[16384], *pclean; @@ -1300,7 +1299,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint bool bIsHello = IsQUICCryptoHello(defrag, defrag_len, &hello_offset, &hello_len); bool bReqFull = bIsHello ? IsTLSHandshakeFull(defrag+hello_offset,hello_len) : false; - DLOG(bIsHello ? bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n" : "packet does not contain TLS ClientHello\n") + DLOG(bIsHello ? bReqFull ? "packet contains full TLS ClientHello\n" : "packet contains partial TLS ClientHello\n" : "packet does not contain TLS ClientHello\n"); if (ctrack) { @@ -1341,7 +1340,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (!bHaveHost && params.desync_skip_nosni) { reasm_orig_cancel(ctrack); - DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n") + DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n"); return verdict; } } @@ -1375,7 +1374,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (IsWireguardHandshakeInitiation(data_payload,len_payload)) { - DLOG("packet contains wireguard handshake initiation\n") + DLOG("packet contains wireguard handshake initiation\n"); if (ctrack && !ctrack->l7proto) ctrack->l7proto = WIREGUARD; fake = params.fake_wg; fake_size = params.fake_wg_size; @@ -1383,7 +1382,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint } else if (IsDhtD1(data_payload,len_payload)) { - DLOG("packet contains DHT d1...e\n") + DLOG("packet contains DHT d1...e\n"); if (ctrack && !ctrack->l7proto) ctrack->l7proto = DHT; fake = params.fake_dht; fake_size = params.fake_dht_size; @@ -1392,7 +1391,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint else { if (!params.desync_any_proto) return verdict; - DLOG("applying tampering to unknown protocol\n") + DLOG("applying tampering to unknown protocol\n"); fake = params.fake_unknown_udp; fake_size = params.fake_unknown_udp_size; } @@ -1400,7 +1399,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (bHaveHost) { - DLOG("hostname: %s\n",host) + DLOG("hostname: %s\n",host); if (params.hostlist || params.hostlist_exclude) { bool bBypass; @@ -1418,7 +1417,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint ctrack_replay->hostname=strdup(host); } } - DLOG("not applying tampering to this request\n") + DLOG("not applying tampering to this request\n"); return verdict; } } @@ -1429,11 +1428,10 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (params.debug) { - printf("dpi desync src="); - print_sockaddr((struct sockaddr *)&src); - printf(" dst="); - print_sockaddr((struct sockaddr *)&dst); - printf("\n"); + char s1[48],s2[48]; + ntop46_port((struct sockaddr *)&src, s1, sizeof(s1)); + ntop46_port((struct sockaddr *)&dst, s2, sizeof(s2)); + DLOG("dpi desync src=%s dst=%s\n",s1,s2); } pkt1_len = sizeof(pkt1); @@ -1451,7 +1449,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, params.desync_fooling_mode, NULL, 0, 0, fake, fake_size, pkt1, &pkt1_len)) return verdict; DLOG("sending fake request : "); - hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n") + hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; b = true; @@ -1485,7 +1483,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint { if (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(params.desync_mode2)) { - DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", *len_pkt, len_payload) + DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", *len_pkt, len_payload); verdict_udp_csum_fix(verdict, udphdr, transport_len, ip, ip6hdr); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, *len_pkt)) return verdict; @@ -1568,13 +1566,13 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (!ip_frag(pkt_orig, pkt_orig_len, ipfrag_pos, ident, pkt1, &pkt1_len, pkt2, &pkt2_len)) return verdict; - DLOG("sending 1st ip fragment 0-%zu ip_payload_len=%zu : ", ipfrag_pos-1, ipfrag_pos) - hexdump_limited_dlog(pkt1,pkt1_len,IP_MAXDUMP); DLOG("\n") + DLOG("sending 1st ip fragment 0-%zu ip_payload_len=%zu : ", ipfrag_pos-1, ipfrag_pos); + hexdump_limited_dlog(pkt1,pkt1_len,IP_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return verdict; - DLOG("sending 2nd ip fragment %zu-%zu ip_payload_len=%zu : ", ipfrag_pos, transport_len-1, transport_len-ipfrag_pos) - hexdump_limited_dlog(pkt2,pkt2_len,IP_MAXDUMP); DLOG("\n") + DLOG("sending 2nd ip fragment %zu-%zu ip_payload_len=%zu : ", ipfrag_pos, transport_len-1, transport_len-ipfrag_pos); + hexdump_limited_dlog(pkt2,pkt2_len,IP_MAXDUMP); DLOG("\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt2, pkt2_len)) return verdict; @@ -1594,34 +1592,36 @@ static void packet_debug(bool replay, uint8_t proto, const struct ip *ip, const { if (params.debug) { - if (replay) printf("REPLAY "); + if (replay) DLOG("REPLAY "); if (ip) { - printf("IP4: "); - print_ip(ip); + char s[66]; + str_ip(s,sizeof(s),ip); + DLOG("IP4: %s",s); } else if (ip6hdr) { - printf("IP6: "); - print_ip6hdr(ip6hdr, proto); + char s[128]; + str_ip6hdr(s,sizeof(s),ip6hdr, proto); + DLOG("IP6: %s",s); } if (tcphdr) { - printf(" "); - print_tcphdr(tcphdr); - printf("\n"); - if (len_payload) { printf("TCP: "); hexdump_limited_dlog(data_payload, len_payload, 32); printf("\n"); } + char s[80]; + str_tcphdr(s,sizeof(s),tcphdr); + DLOG(" %s\n",s); + if (len_payload) { DLOG("TCP: "); hexdump_limited_dlog(data_payload, len_payload, 32); DLOG("\n"); } } else if (udphdr) { - printf(" "); - print_udphdr(udphdr); - printf("\n"); - if (len_payload) { printf("UDP: "); hexdump_limited_dlog(data_payload, len_payload, 32); printf("\n"); } + char s[30]; + str_udphdr(s,sizeof(s),udphdr); + DLOG(" %s\n",s); + if (len_payload) { DLOG("UDP: "); hexdump_limited_dlog(data_payload, len_payload, 32); DLOG("\n"); } } else - printf("\n"); + DLOG("\n"); } } @@ -1676,20 +1676,20 @@ static bool replay_queue(struct rawpacket_tailhead *q) bool b = true; for (i=1,offset=0 ; (rp=rawpacket_dequeue(q)) ; offset+=rp->len_payload, rawpacket_free(rp), i++) { - DLOG("REPLAYING delayed packet #%u offset %zu\n",i,offset) + DLOG("REPLAYING delayed packet #%u offset %zu\n",i,offset); uint8_t verdict = dpi_desync_packet_play(true, offset, rp->fwmark, rp->ifout, rp->packet, &rp->len); switch(verdict & VERDICT_MASK) { case VERDICT_MODIFY: - DLOG("SENDING delayed packet #%u modified\n", i) + DLOG("SENDING delayed packet #%u modified\n", i); b &= rawsend_rp(rp); break; case VERDICT_PASS: - DLOG("SENDING delayed packet #%u unmodified\n", i) + DLOG("SENDING delayed packet #%u unmodified\n", i); b &= rawsend_rp(rp); break; case VERDICT_DROP: - DLOG("DROPPING delayed packet #%u\n", i) + DLOG("DROPPING delayed packet #%u\n", i); break; } } diff --git a/nfq/helpers.c b/nfq/helpers.c index 60a32be..1440b49 100644 --- a/nfq/helpers.c +++ b/nfq/helpers.c @@ -189,24 +189,24 @@ void dbgprint_socket_buffers(int fd) socklen_t sz; sz = sizeof(int); if (!getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &v, &sz)) - DLOG("fd=%d SO_RCVBUF=%d\n", fd, v) + DLOG("fd=%d SO_RCVBUF=%d\n", fd, v); sz = sizeof(int); if (!getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &v, &sz)) - DLOG("fd=%d SO_SNDBUF=%d\n", fd, v) + DLOG("fd=%d SO_SNDBUF=%d\n", fd, v); } } bool set_socket_buffers(int fd, int rcvbuf, int sndbuf) { - DLOG("set_socket_buffers fd=%d rcvbuf=%d sndbuf=%d\n", fd, rcvbuf, sndbuf) + DLOG("set_socket_buffers fd=%d rcvbuf=%d sndbuf=%d\n", fd, rcvbuf, sndbuf); if (rcvbuf && setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(int)) < 0) { - perror("setsockopt (SO_RCVBUF)"); + DLOG_PERROR("setsockopt (SO_RCVBUF)"); close(fd); return false; } if (sndbuf && setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(int)) < 0) { - perror("setsockopt (SO_SNDBUF)"); + DLOG_PERROR("setsockopt (SO_SNDBUF)"); close(fd); return false; } diff --git a/nfq/hostlist.c b/nfq/hostlist.c index 85d463f..d1a03b2 100644 --- a/nfq/hostlist.c +++ b/nfq/hostlist.c @@ -31,11 +31,11 @@ bool AppendHostList(strpool **hostlist, char *filename) FILE *F; int r; - printf("Loading hostlist %s\n",filename); + DLOG_CONDUP("Loading hostlist %s\n",filename); if (!(F = fopen(filename, "rb"))) { - fprintf(stderr, "Could not open %s\n", filename); + DLOG_ERR("Could not open %s\n", filename); return false; } @@ -45,7 +45,7 @@ bool AppendHostList(strpool **hostlist, char *filename) fclose(F); if (r==Z_OK) { - printf("zlib compression detected. uncompressed size : %zu\n", zsize); + DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize); p = zbuf; e = zbuf + zsize; @@ -54,7 +54,7 @@ bool AppendHostList(strpool **hostlist, char *filename) if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue; if (!addpool(hostlist,&p,e)) { - fprintf(stderr, "Not enough memory to store host list : %s\n", filename); + DLOG_ERR("Not enough memory to store host list : %s\n", filename); free(zbuf); return false; } @@ -64,13 +64,13 @@ bool AppendHostList(strpool **hostlist, char *filename) } else { - fprintf(stderr, "zlib decompression failed : result %d\n",r); + DLOG_ERR("zlib decompression failed : result %d\n",r); return false; } } else { - printf("loading plain text list\n"); + DLOG_CONDUP("loading plain text list\n"); while (fgets(s, 256, F)) { @@ -78,7 +78,7 @@ bool AppendHostList(strpool **hostlist, char *filename) if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue; if (!addpool(hostlist,&p,p+strlen(p))) { - fprintf(stderr, "Not enough memory to store host list : %s\n", filename); + DLOG_ERR("Not enough memory to store host list : %s\n", filename); fclose(F); return false; } @@ -87,7 +87,7 @@ bool AppendHostList(strpool **hostlist, char *filename) fclose(F); } - printf("Loaded %d hosts from %s\n", ct, filename); + DLOG_CONDUP("Loaded %d hosts from %s\n", ct, filename); return true; } @@ -124,7 +124,7 @@ bool SearchHostList(strpool *hostlist, const char *host) while (p) { bInHostList = StrPoolCheckStr(hostlist, p); - if (params.debug) printf("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); + DLOG("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); if (bInHostList) return true; p = strchr(p, '.'); if (p) p++; @@ -139,7 +139,7 @@ static bool HostlistCheck_(strpool *hostlist, strpool *hostlist_exclude, const c if (excluded) *excluded = false; if (hostlist_exclude) { - if (params.debug) printf("Checking exclude hostlist\n"); + DLOG("Checking exclude hostlist\n"); if (SearchHostList(hostlist_exclude, host)) { if (excluded) *excluded = true; @@ -148,7 +148,7 @@ static bool HostlistCheck_(strpool *hostlist, strpool *hostlist_exclude, const c } if (hostlist) { - if (params.debug) printf("Checking include hostlist\n"); + DLOG("Checking include hostlist\n"); return SearchHostList(hostlist, host); } return true; @@ -162,7 +162,7 @@ bool HostlistCheck(const char *host, bool *excluded) time_t t = file_mod_time(params.hostlist_auto_filename); if (t!=params.hostlist_auto_mod_time) { - printf("Autohostlist was modified by another process. Reloading include hostslist.\n"); + DLOG_CONDUP("Autohostlist was modified by another process. Reloading include hostslist.\n"); if (!LoadIncludeHostLists()) { // what will we do without hostlist ?? sure, gonna die diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 565c951..d067aea 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef __CYGWIN__ #include "win.h" @@ -99,7 +100,7 @@ static uint8_t processPacketData(uint32_t *mark, const char *ifout, uint8_t *dat #ifdef __linux__ if (*mark & params.desync_fwmark) { - DLOG("ignoring generated packet\n") + DLOG("ignoring generated packet\n"); return VERDICT_PASS; } #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); 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 // 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) { len = ilen; @@ -158,49 +159,49 @@ static int nfq_main(void) int fd,rv; uint8_t buf[16384] __attribute__((aligned)); - printf("opening library handle\n"); + DLOG_CONDUP("opening library handle\n"); h = nfq_open(); if (!h) { - perror("nfq_open()"); + DLOG_PERROR("nfq_open()"); 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) { - perror("nfq_unbind_pf()"); + DLOG_PERROR("nfq_unbind_pf()"); 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) { - perror("nfq_bind_pf()"); + DLOG_PERROR("nfq_bind_pf()"); 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, ¶ms); if (!qh) { - perror("nfq_create_queue()"); + DLOG_PERROR("nfq_create_queue()"); 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) { - perror("can't set packet_copy mode"); + DLOG_PERROR("can't set packet_copy mode"); goto exiterr; } if (nfq_set_queue_maxlen(qh, Q_MAXLEN) < 0) { - perror("can't set queue maxlen"); + DLOG_PERROR("can't set queue maxlen"); goto exiterr; } // accept packets if they cant be handled 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 } - 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)) goto exiterr; @@ -227,24 +228,24 @@ static int nfq_main(void) { dohup(); 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); - perror("recv"); + DLOG_ERR("recv: errno %d\n",errno); + DLOG_PERROR("recv"); // do not fail on 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); #ifdef INSANE /* normally, applications SHOULD NOT issue this command, since * 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); #endif - printf("closing library handle\n"); + DLOG_CONDUP("closing library handle\n"); nfq_close(h); return 0; @@ -273,16 +274,16 @@ static int dvt_main(void) bp4.sin_port = htons(params.port); bp4.sin_addr.s_addr = INADDR_ANY; - printf("creating divert4 socket\n"); + DLOG_CONDUP("creating divert4 socket\n"); fd[0] = socket_divert(AF_INET); if (fd[0] == -1) { - perror("socket (DIVERT4)"); + DLOG_PERROR("socket (DIVERT4)"); goto exiterr; } - printf("binding divert4 socket\n"); + DLOG_CONDUP("binding divert4 socket\n"); if (bind(fd[0], (struct sockaddr*)&bp4, sizeof(bp4)) < 0) { - perror("bind (DIVERT4)"); + DLOG_PERROR("bind (DIVERT4)"); goto exiterr; } 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_port = htons(params.port); - printf("creating divert6 socket\n"); + DLOG_CONDUP("creating divert6 socket\n"); fd[1] = socket_divert(AF_INET6); if (fd[1] == -1) { - perror("socket (DIVERT6)"); + DLOG_PERROR("socket (DIVERT6)"); goto exiterr; } - printf("binding divert6 socket\n"); + DLOG_CONDUP("binding divert6 socket\n"); if (bind(fd[1], (struct sockaddr*)&bp6, sizeof(bp6)) < 0) { - perror("bind (DIVERT6)"); + DLOG_PERROR("bind (DIVERT6)"); goto exiterr; } fdct++; @@ -317,7 +318,7 @@ static int dvt_main(void) #endif 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)) goto exiterr; @@ -340,7 +341,7 @@ static int dvt_main(void) dohup(); continue; } - perror("select"); + DLOG_PERROR("select"); goto exiterr; } for(i=0;i0) @@ -360,21 +361,21 @@ static int dvt_main(void) uint8_t verdict; 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); switch (verdict & VERDICT_MASK) { case VERDICT_PASS: case VERDICT_MODIFY: if ((verdict & VERDICT_MASK)==VERDICT_PASS) - DLOG("packet: id=%u reinject unmodified\n", id) + DLOG("packet: id=%u reinject unmodified\n", id); 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); if (wr<0) - perror("reinject sendto"); + DLOG_PERROR("reinject sendto"); 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; default: DLOG("packet: id=%u drop\n", id); @@ -383,7 +384,7 @@ static int dvt_main(void) } 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(¶ms.ssid_filter, ¶ms.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; } @@ -422,20 +423,20 @@ static int win_main(const char *windivert_filter) { 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); do { if (bQuit) { - DLOG("QUIT requested\n") + DLOG("QUIT requested\n"); win_dark_deinit(); return 0; } usleep(500000); } while (!logical_net_filter_match()); - printf("logical network now present\n"); + DLOG_CONDUP("logical network now present\n"); fflush(stdout); } @@ -445,7 +446,7 @@ static int win_main(const char *windivert_filter) 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 fflush(stdout); @@ -458,36 +459,36 @@ static int win_main(const char *windivert_filter) { if (errno==ENOBUFS) { - DLOG("windivert: ignoring too large packet\n") + DLOG("windivert: ignoring too large packet\n"); continue; // too large packet } else if (errno==ENODEV) { - printf("logical network disappeared. deinitializing windivert.\n"); + DLOG_CONDUP("logical network disappeared. deinitializing windivert.\n"); rawsend_cleanup(); break; } else if (errno==EINTR) { - DLOG("QUIT requested\n") + DLOG("QUIT requested\n"); win_dark_deinit(); return 0; } - fprintf(stderr, "windivert: recv failed. errno %d\n", errno); + DLOG_ERR("windivert: recv failed. errno %d\n", errno); win_dark_deinit(); return w_win32_error; } *ifout=0; 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) { - DLOG("windivert: passing impostor packet\n") + DLOG("windivert: passing impostor packet\n"); verdict = VERDICT_PASS; } else if (wa.Loopback) { - DLOG("windivert: passing loopback packet\n") + DLOG("windivert: passing loopback packet\n"); verdict = VERDICT_PASS; } else @@ -501,11 +502,11 @@ static int win_main(const char *windivert_filter) case VERDICT_PASS: case VERDICT_MODIFY: if ((verdict & VERDICT_MASK)==VERDICT_PASS) - DLOG("packet: id=%u reinject unmodified\n", id) + DLOG("packet: id=%u reinject unmodified\n", id); 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)) - fprintf(stderr,"windivert: reinject of packet id=%u failed\n", id); + DLOG_ERR("windivert: reinject of packet id=%u failed\n", id); break; default: 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); if (v < 0 || v>65535) { - fprintf(stderr, "bad wsize\n"); + DLOG_ERR("bad wsize\n"); return false; } *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); if (v < 0 || v>255) { - fprintf(stderr, "bad wscale\n"); + DLOG_ERR("bad wscale\n"); return false; } *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) { - fprintf(stderr, "invalid hex string: %s\n",filename+2); + DLOG_ERR("invalid hex string: %s\n",filename+2); exit_clean(1); } - DLOG("read %zu bytes from hex string\n",*size) + DLOG("read %zu bytes from hex string\n",*size); } else { 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); } - 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) { printf( - " --debug=0|1\n" + " --debug=0|1|syslog|@\n" #ifdef __linux__ " --qnum=\n" #elif defined(BSD) @@ -1078,7 +1079,41 @@ int main(int argc, char **argv) switch (option_index) { 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; #ifndef __CYGWIN__ case 1: /* qnum or port */ @@ -1086,7 +1121,7 @@ int main(int argc, char **argv) params.qnum = atoi(optarg); if (params.qnum < 0 || params.qnum>65535) { - fprintf(stderr, "bad qnum\n"); + DLOG_ERR("bad qnum\n"); exit_clean(1); } #elif defined(BSD) @@ -1094,7 +1129,7 @@ int main(int argc, char **argv) int i = atoi(optarg); if (i <= 0 || i > 65535) { - fprintf(stderr, "bad port number\n"); + DLOG_ERR("bad port number\n"); exit_clean(1); } params.port = (uint16_t)i; @@ -1115,7 +1150,7 @@ int main(int argc, char **argv) struct passwd *pwd = getpwnam(optarg); if (!pwd) { - fprintf(stderr, "non-existent username supplied\n"); + DLOG_ERR("non-existent username supplied\n"); exit_clean(1); } params.uid = pwd->pw_uid; @@ -1128,7 +1163,7 @@ int main(int argc, char **argv) params.droproot = true; if (sscanf(optarg, "%u:%u", ¶ms.uid, ¶ms.gid)<1) { - fprintf(stderr, "--uid should be : uid[:gid]\n"); + DLOG_ERR("--uid should be : uid[:gid]\n"); exit_clean(1); } break; @@ -1144,14 +1179,14 @@ int main(int argc, char **argv) case 8: /* wssize-cutoff */ if (!parse_cutoff(optarg, ¶ms.wssize_cutoff, ¶ms.wssize_cutoff_mode)) { - fprintf(stderr, "invalid wssize-cutoff value\n"); + DLOG_ERR("invalid wssize-cutoff value\n"); exit_clean(1); } break; case 9: /* ctrack-timeouts */ if (sscanf(optarg, "%u:%u:%u:%u", ¶ms.ctrack_t_syn, ¶ms.ctrack_t_est, ¶ms.ctrack_t_fin, ¶ms.ctrack_t_udp)<3) { - fprintf(stderr, "invalid ctrack-timeouts value\n"); + DLOG_ERR("invalid ctrack-timeouts value\n"); exit_clean(1); } break; @@ -1161,7 +1196,7 @@ int main(int argc, char **argv) case 11: /* hostspell */ 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); } params.hostcase = true; @@ -1196,23 +1231,23 @@ int main(int argc, char **argv) params.desync_mode2 = desync_mode_from_string(mode2); 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); } 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); } 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); } #if defined(__OpenBSD__) 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); } #endif @@ -1225,11 +1260,11 @@ int main(int argc, char **argv) if (sscanf(optarg, "0x%X", ¶ms.desync_fwmark)<=0) sscanf(optarg, "%u", ¶ms.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); } #else - fprintf(stderr, "fmwark/sockarg not supported in this OS\n"); + DLOG_ERR("fmwark/sockarg not supported in this OS\n"); exit_clean(1); #endif break; @@ -1243,14 +1278,14 @@ int main(int argc, char **argv) case 18: /* dpi-desync-autottl */ if (!parse_autottl(optarg, ¶ms.desync_autottl)) { - fprintf(stderr, "dpi-desync-autottl value error\n"); + DLOG_ERR("dpi-desync-autottl value error\n"); exit_clean(1); } break; case 19: /* dpi-desync-autottl6 */ if (!parse_autottl(optarg, ¶ms.desync_autottl6)) { - fprintf(stderr, "dpi-desync-autottl6 value error\n"); + DLOG_ERR("dpi-desync-autottl6 value error\n"); exit_clean(1); } break; @@ -1268,7 +1303,7 @@ int main(int argc, char **argv) else if (!strcmp(p,"badsum")) { #ifdef __OpenBSD__ - printf("\nWARNING !!! OpenBSD may forcibly recompute tcp/udp checksums !!! In this case badsum fooling will not work.\nYou should check tcp checksum correctness in tcpdump manually before using badsum.\n\n"); + DLOG_CONDUP("\nWARNING !!! OpenBSD may forcibly recompute tcp/udp checksums !!! In this case badsum fooling will not work.\nYou should check tcp checksum correctness in tcpdump manually before using badsum.\n\n"); #endif params.desync_fooling_mode |= FOOL_BADSUM; } @@ -1282,7 +1317,7 @@ int main(int argc, char **argv) params.desync_fooling_mode |= FOOL_HOPBYHOP2; 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); } p = e; @@ -1292,7 +1327,7 @@ int main(int argc, char **argv) case 21: /* dpi-desync-repeats */ if (sscanf(optarg,"%u",¶ms.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); } break; @@ -1302,28 +1337,28 @@ int main(int argc, char **argv) case 23: /* dpi-desync-split-pos */ if (sscanf(optarg,"%u",¶ms.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); } break; case 24: /* dpi-desync-split-http-req */ if (!parse_httpreqpos(optarg, ¶ms.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); } break; case 25: /* dpi-desync-split-tls */ if (!parse_tlspos(optarg, ¶ms.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); } break; case 26: /* dpi-desync-split-seqovl */ if (sscanf(optarg,"%u",¶ms.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); } break; @@ -1338,38 +1373,38 @@ int main(int argc, char **argv) case 28: /* dpi-desync-ipfrag-pos-tcp */ if (sscanf(optarg,"%u",¶ms.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); } 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); } break; case 29: /* dpi-desync-ipfrag-pos-udp */ if (sscanf(optarg,"%u",¶ms.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); } 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); } break; case 30: /* dpi-desync-badseq-increments */ if (!parse_badseq_increment(optarg,¶ms.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); } break; case 31: /* dpi-desync-badack-increment */ if (!parse_badseq_increment(optarg,¶ms.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); } break; @@ -1411,7 +1446,7 @@ int main(int argc, char **argv) case 41: /* dpi-desync-udplen-increment */ if (sscanf(optarg,"%d",¶ms.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); } break; @@ -1426,59 +1461,59 @@ int main(int argc, char **argv) case 43: /* desync-cutoff */ if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode)) { - fprintf(stderr, "invalid desync-cutoff value\n"); + DLOG_ERR("invalid desync-cutoff value\n"); exit_clean(1); } break; case 44: /* desync-start */ if (!parse_cutoff(optarg, ¶ms.desync_start, ¶ms.desync_start_mode)) { - fprintf(stderr, "invalid desync-start value\n"); + DLOG_ERR("invalid desync-start value\n"); exit_clean(1); } break; case 45: /* hostlist */ if (!strlist_add(¶ms.hostlist_files, optarg)) { - fprintf(stderr, "strlist_add failed\n"); + DLOG_ERR("strlist_add failed\n"); exit_clean(1); } break; case 46: /* hostlist-exclude */ if (!strlist_add(¶ms.hostlist_exclude_files, optarg)) { - fprintf(stderr, "strlist_add failed\n"); + DLOG_ERR("strlist_add failed\n"); exit_clean(1); } break; case 47: /* hostlist-auto */ 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); } { - FILE *F = fopen(optarg,"a+t"); + FILE *F = fopen(optarg,"at"); if (!F) { - fprintf(stderr, "cannot create %s\n", optarg); + DLOG_ERR("cannot create %s\n", optarg); exit_clean(1); } bool bGzip = is_gzip(F); fclose(F); if (bGzip) { - fprintf(stderr, "gzipped auto hostlists are not supported\n"); + DLOG_ERR("gzipped auto hostlists are not supported\n"); exit_clean(1); } #ifndef __CYGWIN__ 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 } if (!strlist_add(¶ms.hostlist_files, optarg)) { - fprintf(stderr, "strlist_add failed\n"); + DLOG_ERR("strlist_add failed\n"); exit_clean(1); } 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); 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); } break; @@ -1496,7 +1531,7 @@ int main(int argc, char **argv) params.hostlist_auto_fail_time = (uint8_t)atoi(optarg); 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); } break; @@ -1504,7 +1539,7 @@ int main(int argc, char **argv) params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); 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); } break; @@ -1513,13 +1548,13 @@ int main(int argc, char **argv) FILE *F = fopen(optarg,"a+t"); if (!F) { - fprintf(stderr, "cannot create %s\n", optarg); + DLOG_ERR("cannot create %s\n", optarg); exit_clean(1); } fclose(F); #ifndef __CYGWIN__ 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 strncpy(params.hostlist_auto_debuglog, optarg, sizeof(params.hostlist_auto_debuglog)); 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 */ 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); } break; case 53: /* wf-l3 */ 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); } 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)) || !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); } 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)) || !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); } break; @@ -1593,7 +1628,7 @@ int main(int argc, char **argv) if (e) *e++=0; if (*p && !strlist_add(¶ms.ssid_filter, p)) { - fprintf(stderr, "strlist_add failed\n"); + DLOG_ERR("strlist_add failed\n"); exit_clean(1); } p = e; @@ -1611,7 +1646,7 @@ int main(int argc, char **argv) if (e) *e++=0; if (*p && !strlist_add(¶ms.nlm_filter, p)) { - fprintf(stderr, "strlist_add failed\n"); + DLOG_ERR("strlist_add failed\n"); exit_clean(1); } p = e; @@ -1622,7 +1657,7 @@ int main(int argc, char **argv) case 60: /* nlm-list */ 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(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__ if (params.qnum<0) { - fprintf(stderr, "Need queue number (--qnum)\n"); + DLOG_ERR("Need queue number (--qnum)\n"); exit_clean(1); } #elif defined(BSD) if (!params.port) { - fprintf(stderr, "Need divert port (--port)\n"); + DLOG_ERR("Need divert port (--port)\n"); exit_clean(1); } #elif defined(__CYGWIN__) @@ -1648,26 +1686,26 @@ int main(int argc, char **argv) { 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); } 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); } } - DLOG("windivert filter size: %zu\nwindivert filter:\n%s\n",strlen(windivert_filter),windivert_filter) + DLOG("windivert filter size: %zu\nwindivert filter:\n%s\n",strlen(windivert_filter),windivert_filter); if (*wf_save_file) { 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); } 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); } } @@ -1680,7 +1718,7 @@ int main(int argc, char **argv) if (hMutexArg && GetLastError()==ERROR_ALREADY_EXISTS) { 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; } @@ -1691,22 +1729,22 @@ int main(int argc, char **argv) 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_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)) - 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_http_req==httpreqpos_none && params.desync_split_pos) params.desync_split_http_req=httpreqpos_pos; if (!LoadIncludeHostLists()) { - fprintf(stderr, "Include hostlist load failed\n"); + DLOG_ERR("Include hostlist load failed\n"); exit_clean(1); } if (*params.hostlist_auto_filename) NonEmptyHostlist(¶ms.hostlist); if (!LoadExcludeHostLists()) { - fprintf(stderr, "Exclude hostlist load failed\n"); + DLOG_ERR("Exclude hostlist load failed\n"); exit_clean(1); } @@ -1714,11 +1752,11 @@ int main(int argc, char **argv) if (*pidfile && !writepid(pidfile)) { - fprintf(stderr, "could not write pidfile\n"); + DLOG_ERR("could not write pidfile\n"); 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(¶ms.conntrack, 10, params.ctrack_t_syn, params.ctrack_t_est, params.ctrack_t_fin, params.ctrack_t_udp); #ifdef __linux__ diff --git a/nfq/params.c b/nfq/params.c new file mode 100644 index 0000000..5e29a92 --- /dev/null +++ b/nfq/params.c @@ -0,0 +1,151 @@ +#include "params.h" +#include +#include +#include + +#ifdef BSD +const char *progname = "dvtws"; +#elif defined(__CYGWIN__) +const char *progname = "winws"; +#elif defined(__linux__) +const char *progname = "nfqws"; +#else +#error UNKNOWN_SYSTEM_TIME +#endif + + +int DLOG_FILE(FILE *F, const char *format, va_list args) +{ + return vfprintf(F, format, args); +} +int DLOG_CON(const char *format, int syslog_priority, va_list args) +{ + return DLOG_FILE(syslog_priority==LOG_ERR ? stderr : stdout, format, args); +} +int DLOG_FILENAME(const char *filename, const char *format, va_list args) +{ + int r; + FILE *F = fopen(filename,"at"); + if (F) + { + r = DLOG_FILE(F, format, args); + fclose(F); + } + else + r=-1; + return r; +} + +static char syslog_buf[1024]; +static size_t syslog_buf_sz=0; +static void syslog_buffered(int priority, const char *format, va_list args) +{ + if (vsnprintf(syslog_buf+syslog_buf_sz,sizeof(syslog_buf)-syslog_buf_sz,format,args)>0) + { + syslog_buf_sz=strlen(syslog_buf); + // log when buffer is full or buffer ends with \n + if (syslog_buf_sz>=(sizeof(syslog_buf)-1) || (syslog_buf_sz && syslog_buf[syslog_buf_sz-1]=='\n')) + { + syslog(priority,"%s",syslog_buf); + syslog_buf_sz = 0; + } + } +} + +static int DLOG_VA(const char *format, int syslog_priority, bool condup, va_list args) +{ + int r=0; + va_list args2; + + if (condup && !(params.debug && params.debug_target==LOG_TARGET_CONSOLE)) + { + va_copy(args2,args); + DLOG_CON(format,syslog_priority,args2); + } + if (params.debug) + { + switch(params.debug_target) + { + case LOG_TARGET_CONSOLE: + r = DLOG_CON(format,syslog_priority,args); + break; + case LOG_TARGET_FILE: + r = DLOG_FILENAME(params.debug_logfile,format,args); + break; + case LOG_TARGET_SYSLOG: + // skip newlines + syslog_buffered(syslog_priority,format,args); + r = 1; + break; + default: + break; + } + } + return r; +} + +int DLOG(const char *format, ...) +{ + int r; + va_list args; + va_start(args, format); + r = DLOG_VA(format, LOG_DEBUG, false, args); + va_end(args); + return r; +} +int DLOG_CONDUP(const char *format, ...) +{ + int r; + va_list args; + va_start(args, format); + r = DLOG_VA(format, LOG_DEBUG, true, args); + va_end(args); + return r; +} +int DLOG_ERR(const char *format, ...) +{ + int r; + va_list args; + va_start(args, format); + r = DLOG_VA(format, LOG_ERR, true, args); + va_end(args); + return r; +} +int DLOG_PERROR(const char *s) +{ + return DLOG_ERR("%s: %s\n", s, strerror(errno)); +} + + +int LOG_APPEND(const char *filename, const char *format, va_list args) +{ + int r; + FILE *F = fopen(filename,"at"); + if (F) + { + fprint_localtime(F); + fprintf(F, " : "); + r = vfprintf(F, format, args); + fprintf(F, "\n"); + fclose(F); + } + else + r=-1; + return r; +} + +int HOSTLIST_DEBUGLOG_APPEND(const char *format, ...) +{ + if (*params.hostlist_auto_debuglog) + { + int r; + va_list args; + + va_start(args, format); + r = LOG_APPEND(params.hostlist_auto_debuglog, format, args); + va_end(args); + return r; + } + else + return 0; +} diff --git a/nfq/params.h b/nfq/params.h index 773eb19..70ed34e 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -33,9 +33,14 @@ #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 #define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3 +enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG }; + struct params_s { + enum log_target debug_target; + char debug_logfile[PATH_MAX]; bool debug; + uint16_t wsize,wssize; uint8_t wscale,wsscale; char wssize_cutoff_mode; // n - packets, d - data packets, s - relative sequence @@ -85,17 +90,10 @@ struct params_s }; extern struct params_s params; +extern const char *progname; -#define DLOG(format, ...) {if (params.debug) printf(format, ##__VA_ARGS__);} - -#define LOG_APPEND(filename, format, ...) \ -{ \ - FILE *F = fopen(filename,"at"); \ - if (F) \ - { \ - fprint_localtime(F); \ - fprintf(F, " : " format "\n", ##__VA_ARGS__); \ - fclose(F); \ - } \ -} -#define HOSTLIST_DEBUGLOG_APPEND(format, ...) if (*params.hostlist_auto_debuglog) LOG_APPEND(params.hostlist_auto_debuglog, format, ##__VA_ARGS__) +int DLOG(const char *format, ...); +int DLOG_ERR(const char *format, ...); +int DLOG_PERROR(const char *s); +int DLOG_CONDUP(const char *format, ...); +int HOSTLIST_DEBUGLOG_APPEND(const char *format, ...); diff --git a/nfq/sec.c b/nfq/sec.c index c8b95df..05efc97 100644 --- a/nfq/sec.c +++ b/nfq/sec.c @@ -7,6 +7,8 @@ #include #include +#include "params.h" + #ifdef __linux__ #include @@ -194,14 +196,14 @@ bool sec_harden(void) { if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - perror("PR_SET_NO_NEW_PRIVS(prctl)"); + DLOG_PERROR("PR_SET_NO_NEW_PRIVS(prctl)"); return false; } #if ARCH_NR!=0 if (!set_seccomp()) { - perror("seccomp"); - if (errno==EINVAL) fprintf(stderr,"seccomp: this can be safely ignored if kernel does not support seccomp\n"); + DLOG_PERROR("seccomp"); + if (errno==EINVAL) DLOG_ERR("seccomp: this can be safely ignored if kernel does not support seccomp\n"); return false; } #endif @@ -257,15 +259,15 @@ bool dropcaps(void) { if (prctl(PR_CAPBSET_DROP, cap)<0) { - fprintf(stderr, "could not drop bound cap %d\n", cap); - perror("cap_drop_bound"); + DLOG_ERR("could not drop bound cap %d\n", cap); + DLOG_PERROR("cap_drop_bound"); } } } // now without CAP_SETPCAP if (!setpcap(caps)) { - perror("setpcap"); + DLOG_PERROR("setpcap"); return checkpcap(caps); } return true; @@ -299,24 +301,24 @@ bool droproot(uid_t uid, gid_t gid) #ifdef __linux__ if (prctl(PR_SET_KEEPCAPS, 1L)) { - perror("prctl(PR_SET_KEEPCAPS)"); + DLOG_PERROR("prctl(PR_SET_KEEPCAPS)"); return false; } #endif // drop all SGIDs if (setgroups(0,NULL)) { - perror("setgroups"); + DLOG_PERROR("setgroups"); return false; } if (setgid(gid)) { - perror("setgid"); + DLOG_PERROR("setgid"); return false; } if (setuid(uid)) { - perror("setuid"); + DLOG_PERROR("setuid"); return false; } #ifdef __linux__ @@ -331,16 +333,16 @@ void print_id(void) int i,N; gid_t g[128]; - printf("Running as UID=%u GID=",getuid()); + DLOG_CONDUP("Running as UID=%u GID=",getuid()); N=getgroups(sizeof(g)/sizeof(*g),g); if (N>0) { for(i=0;i