diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index de0d3f7..a85d351 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index aacf594..bfd076b 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/freebsd-x64/dvtws b/binaries/freebsd-x64/dvtws index c46a5ef..eba1915 100755 Binary files a/binaries/freebsd-x64/dvtws and b/binaries/freebsd-x64/dvtws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index f71d3e6..d74318d 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index c310ceb..1b1b345 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index 347dd10..4d23112 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index dd6994f..6d68372 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 92babcb..7c32ea8 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 7993df3..3eec532 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/desync.c b/nfq/desync.c index 2a790a6..d6c6e93 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -321,40 +321,60 @@ static void reasm_orig_fin(t_ctrack *ctrack) } -static packet_process_result ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, packet_process_result res) +static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, struct ip6_hdr *ip6, uint8_t proto, struct udphdr *udp, struct tcphdr *tcp, size_t *len_pkt) { #ifdef __linux__ // if used in postnat chain, dropping initial packet will cause conntrack connection teardown // so we need to workaround this. - // we can't use low ttl for UDP because TCP/IP stack listens to ttl expired ICMPs and notify socket - // we also can't use TCP fooling because DPI would accept fooled packets - if (ip && ctrack && ctrack->pcounter_orig==1) + // we can't use low ttl because TCP/IP stack listens to ttl expired ICMPs and notify socket + // we also can't use fooling because DPI would accept fooled packets + if (ctrack && ctrack->pcounter_orig==1) { - // routers will drop IP frames with invalid checksum - if (ip->ip_p==IPPROTO_TCP) + DLOG("applying linux postnat conntrack workaround\n") + if (proto==IPPROTO_UDP && udp && len_pkt) { - // linux recalc ip checksum in tcp - // need another limiter - ip->ip_ttl=1; + // make malformed udp packet with zero length and invalid checksum + udp->len = 0; // invalid length. must be >=8 + udp_fix_checksum(udp,sizeof(struct udphdr),ip,ip6); + udp->check ^= htons(0xBEAF); + // truncate packet + *len_pkt = (uint8_t*)udp - (ip ? (uint8_t*)ip : (uint8_t*)ip6) + sizeof(struct udphdr); + if (ip) + { + ip->ip_len = htons((uint16_t)*len_pkt); + ip4_fix_checksum(ip); + } + else if (ip6) + ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = (uint16_t)htons(sizeof(struct udphdr)); } - else - ip->ip_sum ^= htons(0xBEAF); - - return res==frag ? modfrag : modify; + else if (proto==IPPROTO_TCP && tcp) + { + // only SYN here is expected + // make flags invalid and also corrupt checksum + tcp->th_flags = 0; + } + if (ip) ip->ip_sum ^= htons(0xBEAF); + return VERDICT_MODIFY | VERDICT_NOCSUM; } - else #endif - // ipv6 does not have checksum - // consider we are free of NAT in ipv6 case. just drop - // BSDs also do not need this - return drop; + return VERDICT_DROP; +} + +static uint8_t ct_new_postnat_fix_tcp(const t_ctrack *ctrack, struct ip *ip, struct ip6_hdr *ip6, struct tcphdr *tcphdr) +{ + return ct_new_postnat_fix(ctrack,ip,ip6,IPPROTO_TCP,NULL,tcphdr,NULL); +} +static uint8_t ct_new_postnat_fix_udp(const t_ctrack *ctrack, struct ip *ip, struct ip6_hdr *ip6, struct udphdr *udphdr, size_t *len_pkt) +{ + return ct_new_postnat_fix(ctrack,ip,ip6,IPPROTO_UDP,udphdr,NULL,len_pkt); } + // result : true - drop original packet, false = dont drop -packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload) +uint8_t dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload) { - packet_process_result res=pass; + uint8_t res=VERDICT_PASS; t_ctrack *ctrack=NULL; bool bReverse=false; @@ -377,7 +397,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (params.wsize && tcp_synack_segment(tcphdr)) { tcp_rewrite_winsize(tcphdr, params.wsize, params.wscale); - res=modify; + res=VERDICT_MODIFY; } if (bReverse) @@ -450,7 +470,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, { if (params.wssize_cutoff) DLOG("wssize-cutoff not reached (mode %c): %llu/%u\n", params.wssize_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.wssize_cutoff_mode), params.wssize_cutoff); tcp_rewrite_winsize(tcphdr, params.wssize, params.wsscale); - res=modify; + res=VERDICT_MODIFY; } } else @@ -508,7 +528,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; - res = ct_new_postnat_fix(ctrack, ip, drop); + res = ct_new_postnat_fix_tcp(ctrack, ip, ip6hdr, tcphdr); break; } // can do nothing else with SYN packet @@ -663,14 +683,14 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, { 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); - res=modify; + res=VERDICT_MODIFY; } if (params.domcase) { DLOG("mixing domain case\n"); for (p = phost+7; p < (data_payload + len_payload) && *p != '\r' && *p != '\n'; p++) *p = (((size_t)p) & 1) ? tolower(*p) : toupper(*p); - res=modify; + res=VERDICT_MODIFY; } uint8_t *pua; if (params.hostnospace && @@ -688,7 +708,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, memmove(pua + 1, pua, phost - pua + 7); *pua = ' '; } - res=modify; + res=VERDICT_MODIFY; } } @@ -756,7 +776,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; // this mode is final, no other options available - return drop; + return VERDICT_DROP; } desync_mode = params.desync_mode2; } @@ -769,23 +789,23 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, { if (params.desync_retrans) { - DLOG("dropping original packet to force retransmission. len=%zu len_payload=%zu\n", len_pkt, len_payload) + DLOG("dropping original packet to force retransmission. len=%zu len_payload=%zu\n", *len_pkt, len_payload) } else { - 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) #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || ip6hdr) + if ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr) #else // if original packet was tampered earlier it needs checksum fixed - if (res==modify) + if ((res & VERDICT_MASK)==VERDICT_MODIFY) #endif tcp_fix_checksum(tcphdr,len_tcp,ip,ip6hdr); - if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, len_pkt)) + if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, *len_pkt)) return res; } - return drop; + return VERDICT_DROP; } desync_mode = params.desync_mode2; } @@ -845,7 +865,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, return res; } - return drop; + return VERDICT_DROP; } break; case DESYNC_SPLIT: @@ -898,17 +918,17 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, return res; } - return drop; + return VERDICT_DROP; } break; case DESYNC_IPFRAG2: { #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || ip6hdr) + if ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr) #else // if original packet was tampered earlier it needs checksum fixed - if (res==modify) + if ((res & VERDICT_MASK)==VERDICT_MODIFY) #endif tcp_fix_checksum(tcphdr,len_tcp,ip,ip6hdr); @@ -924,14 +944,14 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (ip6hdr && (fooling_orig==FOOL_HOPBYHOP || fooling_orig==FOOL_DESTOPT)) { pkt_orig_len = sizeof(pkt3); - if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, len_pkt, pkt3, &pkt_orig_len)) + if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, *len_pkt, pkt3, &pkt_orig_len)) return res; pkt_orig = pkt3; } else { pkt_orig = data_pkt; - pkt_orig_len = len_pkt; + pkt_orig_len = *len_pkt; } if (!ip_frag(pkt_orig, pkt_orig_len, ipfrag_pos, ident, pkt1, &pkt1_len, pkt2, &pkt2_len)) @@ -947,7 +967,7 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; - return frag; + return VERDICT_DROP; } } @@ -958,9 +978,9 @@ packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, -packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, uint8_t *data_payload, size_t len_payload) +uint8_t dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, uint8_t *data_payload, size_t len_payload) { - packet_process_result res=pass; + uint8_t res=VERDICT_PASS; t_ctrack *ctrack=NULL; bool bReverse=false; @@ -1156,7 +1176,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; // this mode is final, no other options available - return ct_new_postnat_fix(ctrack, ip, drop); + return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt); } desync_mode = params.desync_mode2; break; @@ -1166,18 +1186,18 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, { 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) #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || ip6hdr) + if ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr) #else // if original packet was tampered earlier it needs checksum fixed - if (res==modify) + if ((res & VERDICT_MASK)==VERDICT_MODIFY) #endif udp_fix_checksum(udphdr,sizeof(struct udphdr)+len_payload,ip,ip6hdr); - if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, len_pkt)) + if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , data_pkt, *len_pkt)) return res; - return ct_new_postnat_fix(ctrack, ip, drop); + return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt); } desync_mode = params.desync_mode2; } @@ -1194,7 +1214,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, DLOG("resending original packet with increased by %d length\n", params.udplen_increment); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; - return ct_new_postnat_fix(ctrack, ip, drop); + return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt); case DESYNC_TAMPER: if (IsDhtD1(data_payload,len_payload)) { @@ -1219,7 +1239,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, DLOG("resending tampered DHT\n"); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; - return ct_new_postnat_fix(ctrack, ip, drop); + return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt); } else { @@ -1231,10 +1251,10 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || ip6hdr) + if ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr) #else // if original packet was tampered earlier it needs checksum fixed - if (res==modify) + if ((res & VERDICT_MASK)==VERDICT_MODIFY) #endif udp_fix_checksum(udphdr,sizeof(struct udphdr)+len_payload,ip,ip6hdr); @@ -1252,14 +1272,14 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, if (ip6hdr && (fooling_orig==FOOL_HOPBYHOP || fooling_orig==FOOL_DESTOPT)) { pkt_orig_len = sizeof(pkt3); - if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, len_pkt, pkt3, &pkt_orig_len)) + if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, *len_pkt, pkt3, &pkt_orig_len)) return res; pkt_orig = pkt3; } else { pkt_orig = data_pkt; - pkt_orig_len = len_pkt; + pkt_orig_len = *len_pkt; } if (!ip_frag(pkt_orig, pkt_orig_len, ipfrag_pos, ident, pkt1, &pkt1_len, pkt2, &pkt2_len)) @@ -1275,7 +1295,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; - return ct_new_postnat_fix(ctrack, ip, frag); + return ct_new_postnat_fix_udp(ctrack, ip, ip6hdr, udphdr, len_pkt); } } diff --git a/nfq/desync.h b/nfq/desync.h index e77745d..82dd782 100644 --- a/nfq/desync.h +++ b/nfq/desync.h @@ -51,5 +51,5 @@ bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode); bool desync_valid_second_stage_udp(enum dpi_desync_mode mode); void desync_init(void); -packet_process_result dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload); -packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, uint8_t *data_payload, size_t len_payload); +uint8_t dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload); +uint8_t dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, uint8_t *data_payload, size_t len_payload); diff --git a/nfq/nfqws.c b/nfq/nfqws.c index a92339f..3a90ffb 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -80,15 +80,15 @@ static void onusr2(int sig) -static packet_process_result processPacketData(uint32_t *mark, const char *ifout, uint8_t *data_pkt, size_t len_pkt) +static uint8_t processPacketData(uint32_t *mark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt) { struct ip *ip = NULL; struct ip6_hdr *ip6hdr = NULL; struct tcphdr *tcphdr = NULL; struct udphdr *udphdr = NULL; - size_t len = len_pkt, len_with_th; + size_t len = *len_pkt, len_with_th; uint8_t *data = data_pkt; - packet_process_result res = pass; + uint8_t res = VERDICT_PASS; uint8_t proto; #ifdef __linux__ @@ -146,9 +146,9 @@ static packet_process_result processPacketData(uint32_t *mark, const char *ifout // ipv6 packets were with incorrect checksum #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || res!=frag && res!=modfrag && ip6hdr) + if (!(res & VERDICT_NOCSUM) && ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr && (res & VERDICT_MASK)==VERDICT_PASS)) #else - if (res==modify) + if (!(res & VERDICT_NOCSUM) && (res & VERDICT_MASK)==VERDICT_MODIFY) #endif tcp_fix_checksum(tcphdr,len_with_th,ip,ip6hdr); } @@ -169,9 +169,9 @@ static packet_process_result processPacketData(uint32_t *mark, const char *ifout res = dpi_desync_udp_packet(*mark, ifout, data_pkt, len_pkt, ip, ip6hdr, udphdr, data, len); #ifdef __FreeBSD__ // FreeBSD tend to pass ipv6 frames with wrong checksum - if (res==modify || res!=frag && res!=modfrag && ip6hdr) + if (!(res & VERDICT_NOCSUM) && ((res & VERDICT_MASK)==VERDICT_MODIFY || ip6hdr && (res & VERDICT_MASK)==VERDICT_PASS)) #else - if (res==modify) + if (!(res & VERDICT_NOCSUM) && (res & VERDICT_MASK)==VERDICT_MODIFY) #endif udp_fix_checksum(udphdr,len_with_th,ip,ip6hdr); } @@ -187,8 +187,8 @@ static packet_process_result processPacketData(uint32_t *mark, const char *ifout #ifdef __linux__ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cookie) { - int id; - int len; + int id, ilen; + size_t len; struct nfqnl_msg_packet_hdr *ph; uint8_t *data; uint32_t ifidx; @@ -198,7 +198,7 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da id = ph ? ntohl(ph->packet_id) : 0; uint32_t mark = nfq_get_nfmark(nfa); - len = nfq_get_payload(nfa, &data); + ilen = nfq_get_payload(nfa, &data); *ifout=0; if (params.bind_fix4 || params.bind_fix6) @@ -206,21 +206,21 @@ 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 ifout=%s(%u)\n", id, len, 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\n", id, len) - if (len >= 0) + DLOG("packet: id=%d len=%d mark=%08X\n", id, ilen, mark) + if (ilen >= 0) { - switch (processPacketData(&mark, ifout, data, len)) + len = ilen; + uint8_t res = processPacketData(&mark, ifout, data, &len); + switch(res & VERDICT_MASK) { - case modify: - case modfrag: - DLOG("packet: id=%d pass modified\n", id); - return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, len, data); - case drop: - case frag: + case VERDICT_MODIFY: + DLOG("packet: id=%d pass modified. len=%zu\n", id, len); + return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, (uint32_t)len, data); + case VERDICT_DROP: DLOG("packet: id=%d drop\n", id); return nfq_set_verdict2(qh, id, NF_DROP, mark, 0, NULL); } @@ -343,7 +343,6 @@ static int dvt_main(void) unsigned int id=0; socklen_t socklen; ssize_t rd,wr; - packet_process_result ppr; fd_set fdset; { @@ -439,18 +438,24 @@ static int dvt_main(void) else if (rd>0) { uint32_t mark=0; - DLOG("packet: id=%u len=%zd\n", id, rd) - ppr = processPacketData(&mark, NULL, buf, rd); - switch (ppr) + uint8_t res; + size_t len = rd; + + DLOG("packet: id=%u len=%zu\n", id, len) + res = processPacketData(&mark, NULL, buf, &len); + switch (res & VERDICT_MASK) { - case pass: - case modify: - DLOG(ppr==pass ? "packet: id=%u reinject unmodified\n" : "packet: id=%u reinject modified\n", id); - wr = sendto(fd[i], buf, rd, 0, (struct sockaddr*)&sa_from, socklen); + case VERDICT_PASS: + case VERDICT_MODIFY: + if ((res & VERDICT_MASK)==VERDICT_PASS) + DLOG("packet: id=%u reinject unmodified\n", id) + else + 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"); - else if (wr!=rd) - fprintf(stderr,"reinject sendto: not all data was reinjected. received %zd, sent %zd\n", rd, wr); + else if (wr!=len) + fprintf(stderr,"reinject sendto: not all data was reinjected. received %zu, sent %zd\n", len, wr); break; default: DLOG("packet: id=%u drop\n", id); diff --git a/nfq/nfqws.h b/nfq/nfqws.h index 14de96d..c1c7893 100644 --- a/nfq/nfqws.h +++ b/nfq/nfqws.h @@ -1,7 +1,7 @@ #pragma once -typedef enum -{ - // frag=drop but do not fix checksum - pass = 0, modify, drop, frag, modfrag -} packet_process_result; +#define VERDICT_PASS 0 +#define VERDICT_MODIFY 1 +#define VERDICT_DROP 2 +#define VERDICT_MASK 3 +#define VERDICT_NOCSUM 4