Browse Source

nfqws: improve postnat workaround

pull/181/head
bol-van 1 year ago
parent
commit
d1389f2527
  1. BIN
      binaries/aarch64/nfqws
  2. BIN
      binaries/arm/nfqws
  3. BIN
      binaries/freebsd-x64/dvtws
  4. BIN
      binaries/mips32r1-lsb/nfqws
  5. BIN
      binaries/mips32r1-msb/nfqws
  6. BIN
      binaries/mips64r2-msb/nfqws
  7. BIN
      binaries/ppc/nfqws
  8. BIN
      binaries/x86/nfqws
  9. BIN
      binaries/x86_64/nfqws
  10. 130
      nfq/desync.c
  11. 4
      nfq/desync.h
  12. 65
      nfq/nfqws.c
  13. 10
      nfq/nfqws.h

BIN
binaries/aarch64/nfqws

Binary file not shown.

BIN
binaries/arm/nfqws

Binary file not shown.

BIN
binaries/freebsd-x64/dvtws

Binary file not shown.

BIN
binaries/mips32r1-lsb/nfqws

Binary file not shown.

BIN
binaries/mips32r1-msb/nfqws

Binary file not shown.

BIN
binaries/mips64r2-msb/nfqws

Binary file not shown.

BIN
binaries/ppc/nfqws

Binary file not shown.

BIN
binaries/x86/nfqws

Binary file not shown.

BIN
binaries/x86_64/nfqws

Binary file not shown.

130
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);
}
}

4
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);

65
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);

10
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

Loading…
Cancel
Save