mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2: proper conntrack position of replay pieces
This commit is contained in:
106
nfq2/conntrack.c
106
nfq2/conntrack.c
@@ -102,8 +102,8 @@ static void ConntrackInitTrack(t_ctrack *t)
|
||||
{
|
||||
memset(t, 0, sizeof(*t));
|
||||
t->l7proto = L7_UNKNOWN;
|
||||
t->scale_orig = t->scale_reply = SCALE_NONE;
|
||||
time(&t->t_start);
|
||||
t->pos.scale_orig = t->pos.scale_reply = SCALE_NONE;
|
||||
time(&t->pos.t_start);
|
||||
rawpacket_queue_init(&t->delayed);
|
||||
lua_newtable(params.L);
|
||||
t->lua_state = luaL_ref(params.L, LUA_REGISTRYINDEX);
|
||||
@@ -136,86 +136,86 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
||||
|
||||
if (bReverse)
|
||||
{
|
||||
t->pcounter_reply++;
|
||||
t->pdcounter_reply += !!len_payload;
|
||||
t->pbcounter_reply += len_payload;
|
||||
t->pos.pcounter_reply++;
|
||||
t->pos.pdcounter_reply += !!len_payload;
|
||||
t->pos.pbcounter_reply += len_payload;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
t->pcounter_orig++;
|
||||
t->pdcounter_orig += !!len_payload;
|
||||
t->pbcounter_orig += len_payload;
|
||||
t->pos.pcounter_orig++;
|
||||
t->pos.pdcounter_orig += !!len_payload;
|
||||
t->pos.pbcounter_orig += len_payload;
|
||||
}
|
||||
|
||||
if (tcphdr)
|
||||
{
|
||||
if (tcp_syn_segment(tcphdr))
|
||||
{
|
||||
if (t->state != SYN) ConntrackReInitTrack(t); // erase current entry
|
||||
t->seq0 = ntohl(tcphdr->th_seq);
|
||||
if (t->pos.state != SYN) ConntrackReInitTrack(t); // erase current entry
|
||||
t->pos.seq0 = ntohl(tcphdr->th_seq);
|
||||
}
|
||||
else if (tcp_synack_segment(tcphdr))
|
||||
{
|
||||
// ignore SA dups
|
||||
uint32_t seq0 = ntohl(tcphdr->th_ack) - 1;
|
||||
if (t->state != SYN && t->seq0 != seq0)
|
||||
if (t->pos.state != SYN && t->pos.seq0 != seq0)
|
||||
ConntrackReInitTrack(t); // erase current entry
|
||||
if (!t->seq0) t->seq0 = seq0;
|
||||
t->ack0 = ntohl(tcphdr->th_seq);
|
||||
if (!t->pos.seq0) t->pos.seq0 = seq0;
|
||||
t->pos.ack0 = ntohl(tcphdr->th_seq);
|
||||
}
|
||||
else if (tcphdr->th_flags & (TH_FIN | TH_RST))
|
||||
{
|
||||
t->state = FIN;
|
||||
t->pos.state = FIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t->state == SYN)
|
||||
if (t->pos.state == SYN)
|
||||
{
|
||||
t->state = ESTABLISHED;
|
||||
if (!bReverse && !t->ack0) t->ack0 = ntohl(tcphdr->th_ack) - 1;
|
||||
t->pos.state = ESTABLISHED;
|
||||
if (!bReverse && !t->pos.ack0) t->pos.ack0 = ntohl(tcphdr->th_ack) - 1;
|
||||
}
|
||||
}
|
||||
scale = tcp_find_scale_factor(tcphdr);
|
||||
mss = ntohs(tcp_find_mss(tcphdr));
|
||||
if (bReverse)
|
||||
{
|
||||
t->pos_orig = t->seq_last = ntohl(tcphdr->th_ack);
|
||||
t->ack_last = ntohl(tcphdr->th_seq);
|
||||
t->pos_reply = t->ack_last + len_payload;
|
||||
t->winsize_reply = ntohs(tcphdr->th_win);
|
||||
t->winsize_reply_calc = t->winsize_reply;
|
||||
if (t->scale_reply != SCALE_NONE) t->winsize_reply_calc <<= t->scale_reply;
|
||||
if (mss && !t->mss_reply) t->mss_reply = mss;
|
||||
if (scale != SCALE_NONE) t->scale_reply = scale;
|
||||
t->pos.pos_orig = t->pos.seq_last = ntohl(tcphdr->th_ack);
|
||||
t->pos.ack_last = ntohl(tcphdr->th_seq);
|
||||
t->pos.pos_reply = t->pos.ack_last + len_payload;
|
||||
t->pos.winsize_reply = ntohs(tcphdr->th_win);
|
||||
t->pos.winsize_reply_calc = t->pos.winsize_reply;
|
||||
if (t->pos.scale_reply != SCALE_NONE) t->pos.winsize_reply_calc <<= t->pos.scale_reply;
|
||||
if (mss && !t->pos.mss_reply) t->pos.mss_reply = mss;
|
||||
if (scale != SCALE_NONE) t->pos.scale_reply = scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->seq_last = ntohl(tcphdr->th_seq);
|
||||
t->pos_orig = t->seq_last + len_payload;
|
||||
t->pos_reply = t->ack_last = ntohl(tcphdr->th_ack);
|
||||
t->winsize_orig = ntohs(tcphdr->th_win);
|
||||
t->winsize_orig_calc = t->winsize_orig;
|
||||
if (t->scale_orig != SCALE_NONE) t->winsize_orig_calc <<= t->scale_orig;
|
||||
if (mss && !t->mss_reply) t->mss_orig = mss;
|
||||
if (scale != SCALE_NONE) t->scale_orig = scale;
|
||||
t->pos.seq_last = ntohl(tcphdr->th_seq);
|
||||
t->pos.pos_orig = t->pos.seq_last + len_payload;
|
||||
t->pos.pos_reply = t->pos.ack_last = ntohl(tcphdr->th_ack);
|
||||
t->pos.winsize_orig = ntohs(tcphdr->th_win);
|
||||
t->pos.winsize_orig_calc = t->pos.winsize_orig;
|
||||
if (t->pos.scale_orig != SCALE_NONE) t->pos.winsize_orig_calc <<= t->pos.scale_orig;
|
||||
if (mss && !t->pos.mss_reply) t->pos.mss_orig = mss;
|
||||
if (scale != SCALE_NONE) t->pos.scale_orig = scale;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bReverse)
|
||||
{
|
||||
t->ack_last = t->pos_reply;
|
||||
t->pos_reply += len_payload;
|
||||
t->pos.ack_last = t->pos.pos_reply;
|
||||
t->pos.pos_reply += len_payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
t->seq_last = t->pos_orig;
|
||||
t->pos_orig += len_payload;
|
||||
t->pos.seq_last = t->pos.pos_orig;
|
||||
t->pos.pos_orig += len_payload;
|
||||
}
|
||||
}
|
||||
|
||||
time(&t->t_last);
|
||||
time(&t->pos.t_last);
|
||||
}
|
||||
|
||||
static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse)
|
||||
@@ -317,12 +317,12 @@ void ConntrackPoolPurge(t_conntrack *p)
|
||||
if ((tnow - p->t_last_purge) >= p->t_purge_interval)
|
||||
{
|
||||
HASH_ITER(hh, p->pool, t, tmp) {
|
||||
tidle = tnow - t->track.t_last;
|
||||
tidle = tnow - t->track.pos.t_last;
|
||||
if (t->track.b_cutoff ||
|
||||
(t->conn.l4proto == IPPROTO_TCP && (
|
||||
(t->track.state == SYN && tidle >= p->timeout_syn) ||
|
||||
(t->track.state == ESTABLISHED && tidle >= p->timeout_established) ||
|
||||
(t->track.state == FIN && tidle >= p->timeout_fin))
|
||||
(t->track.pos.state == SYN && tidle >= p->timeout_syn) ||
|
||||
(t->track.pos.state == ESTABLISHED && tidle >= p->timeout_established) ||
|
||||
(t->track.pos.state == FIN && tidle >= p->timeout_fin))
|
||||
) || (t->conn.l4proto == IPPROTO_UDP && tidle >= p->timeout_udp)
|
||||
)
|
||||
{
|
||||
@@ -349,21 +349,21 @@ void ConntrackPoolDump(const t_conntrack *p)
|
||||
printf("%s [%s]:%u => [%s]:%u : %s : t0=%llu last=t0+%llu now=last+%llu orig=d%llu/n%llu/b%llu reply=d%llu/n%llu/b%lld ",
|
||||
proto_name(t->conn.l4proto),
|
||||
sa1, t->conn.sport, sa2, t->conn.dport,
|
||||
t->conn.l4proto == IPPROTO_TCP ? connstate_s[t->track.state] : "-",
|
||||
(unsigned long long)t->track.t_start, (unsigned long long)(t->track.t_last - t->track.t_start), (unsigned long long)(tnow - t->track.t_last),
|
||||
(unsigned long long)t->track.pdcounter_orig, (unsigned long long)t->track.pcounter_orig, (unsigned long long)t->track.pbcounter_orig,
|
||||
(unsigned long long)t->track.pdcounter_reply, (unsigned long long)t->track.pcounter_reply, (unsigned long long)t->track.pbcounter_reply);
|
||||
t->conn.l4proto == IPPROTO_TCP ? connstate_s[t->track.pos.state] : "-",
|
||||
(unsigned long long)t->track.pos.t_start, (unsigned long long)(t->track.pos.t_last - t->track.pos.t_start), (unsigned long long)(tnow - t->track.pos.t_last),
|
||||
(unsigned long long)t->track.pos.pdcounter_orig, (unsigned long long)t->track.pos.pcounter_orig, (unsigned long long)t->track.pos.pbcounter_orig,
|
||||
(unsigned long long)t->track.pos.pdcounter_reply, (unsigned long long)t->track.pos.pcounter_reply, (unsigned long long)t->track.pos.pbcounter_reply);
|
||||
if (t->conn.l4proto == IPPROTO_TCP)
|
||||
printf("seq0=%u rseq=%u pos_orig=%u ack0=%u rack=%u pos_reply=%u mss_orig=%u mss_reply=%u wsize_orig=%u:%d wsize_reply=%u:%d",
|
||||
t->track.seq0, t->track.seq_last - t->track.seq0, t->track.pos_orig - t->track.seq0,
|
||||
t->track.ack0, t->track.ack_last - t->track.ack0, t->track.pos_reply - t->track.ack0,
|
||||
t->track.mss_orig, t->track.mss_reply,
|
||||
t->track.winsize_orig, t->track.scale_orig == SCALE_NONE ? -1 : t->track.scale_orig,
|
||||
t->track.winsize_reply, t->track.scale_reply == SCALE_NONE ? -1 : t->track.scale_reply);
|
||||
t->track.pos.seq0, t->track.pos.seq_last - t->track.pos.seq0, t->track.pos.pos_orig - t->track.pos.seq0,
|
||||
t->track.pos.ack0, t->track.pos.ack_last - t->track.pos.ack0, t->track.pos.pos_reply - t->track.pos.ack0,
|
||||
t->track.pos.mss_orig, t->track.pos.mss_reply,
|
||||
t->track.pos.winsize_orig, t->track.pos.scale_orig == SCALE_NONE ? -1 : t->track.pos.scale_orig,
|
||||
t->track.pos.winsize_reply, t->track.pos.scale_reply == SCALE_NONE ? -1 : t->track.pos.scale_reply);
|
||||
else
|
||||
printf("rseq=%u pos_orig=%u rack=%u pos_reply=%u",
|
||||
t->track.seq_last, t->track.pos_orig,
|
||||
t->track.ack_last, t->track.pos_reply);
|
||||
t->track.pos.seq_last, t->track.pos.pos_orig,
|
||||
t->track.pos.ack_last, t->track.pos.pos_reply);
|
||||
printf(" req_retrans=%u cutoff=%u lua_in_cutoff=%u lua_out_cutoff=%u hostname=%s l7proto=%s\n",
|
||||
t->track.req_retrans_counter, t->track.b_cutoff, t->track.b_lua_in_cutoff, t->track.b_lua_out_cutoff, t->track.hostname, l7proto_str(t->track.l7proto));
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
#include "conntrack_base.h"
|
||||
#include "packet_queue.h"
|
||||
#include "protocol.h"
|
||||
|
||||
@@ -48,35 +49,18 @@ typedef struct {
|
||||
size_t size_present; // how many bytes already stored in 'packet'
|
||||
} t_reassemble;
|
||||
|
||||
// SYN - SYN or SYN/ACK received
|
||||
// ESTABLISHED - any except SYN or SYN/ACK received
|
||||
// FIN - FIN or RST received
|
||||
typedef enum {SYN=0, ESTABLISHED, FIN} t_connstate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool bCheckDone, bCheckResult, bCheckExcluded; // hostlist check result cache
|
||||
uint8_t ipproto;
|
||||
|
||||
// this block of data can change between delayed (queued) packets. need to remeber this data for each packet for further replay
|
||||
t_ctrack_position pos;
|
||||
|
||||
struct desync_profile *dp; // desync profile cache
|
||||
bool dp_search_complete;
|
||||
|
||||
// common state
|
||||
time_t t_start, t_last;
|
||||
uint64_t pcounter_orig, pcounter_reply; // packet counter
|
||||
uint64_t pdcounter_orig, pdcounter_reply; // data packet counter (with payload)
|
||||
uint64_t pbcounter_orig, pbcounter_reply; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
|
||||
uint32_t pos_orig, pos_reply; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current
|
||||
uint32_t seq_last, ack_last; // TCP: last seen seq and ack UDP: sum of all seen payload lenghts NOT including current
|
||||
|
||||
// tcp only state, not used in udp
|
||||
t_connstate state;
|
||||
uint32_t seq0, ack0; // starting seq and ack
|
||||
uint16_t winsize_orig, winsize_reply; // last seen window size
|
||||
uint8_t scale_orig, scale_reply; // last seen window scale factor. SCALE_NONE if none
|
||||
uint32_t winsize_orig_calc, winsize_reply_calc; // calculated window size
|
||||
uint16_t mss_orig, mss_reply;
|
||||
|
||||
uint8_t req_retrans_counter; // number of request retransmissions
|
||||
bool req_seq_present,req_seq_finalized,req_seq_abandoned;
|
||||
uint32_t req_seq_start,req_seq_end; // sequence interval of the request (to track retransmissions)
|
||||
|
||||
25
nfq2/conntrack_base.h
Normal file
25
nfq2/conntrack_base.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
// SYN - SYN or SYN/ACK received
|
||||
// ESTABLISHED - any except SYN or SYN/ACK received
|
||||
// FIN - FIN or RST received
|
||||
typedef enum {SYN=0, ESTABLISHED, FIN} t_connstate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t t_last, t_start;
|
||||
|
||||
uint64_t pcounter_orig, pcounter_reply; // packet counter
|
||||
uint64_t pdcounter_orig, pdcounter_reply; // data packet counter (with payload)
|
||||
uint64_t pbcounter_orig, pbcounter_reply; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
|
||||
uint32_t pos_orig, pos_reply; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current
|
||||
uint32_t seq_last, ack_last; // TCP: last seen seq and ack UDP: sum of all seen payload lenghts NOT including current
|
||||
|
||||
// tcp only state, not used in udp
|
||||
t_connstate state;
|
||||
uint32_t seq0, ack0; // starting seq and ack
|
||||
uint16_t winsize_orig, winsize_reply; // last seen window size
|
||||
uint8_t scale_orig, scale_reply; // last seen window scale factor. SCALE_NONE if none
|
||||
uint32_t winsize_orig_calc, winsize_reply_calc; // calculated window size
|
||||
uint16_t mss_orig, mss_reply;
|
||||
} t_ctrack_position;
|
||||
136
nfq2/desync.c
136
nfq2/desync.c
@@ -249,9 +249,9 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho
|
||||
{
|
||||
if (!ctrack->req_seq_finalized || ctrack->req_seq_abandoned)
|
||||
return false;
|
||||
if (!seq_within(ctrack->seq_last, ctrack->req_seq_start, ctrack->req_seq_end))
|
||||
if (!seq_within(ctrack->pos.seq_last, ctrack->req_seq_start, ctrack->req_seq_end))
|
||||
{
|
||||
DLOG("req retrans : tcp seq %u not within the req range %u-%u. stop tracking.\n", ctrack->seq_last, ctrack->req_seq_start, ctrack->req_seq_end);
|
||||
DLOG("req retrans : tcp seq %u not within the req range %u-%u. stop tracking.\n", ctrack->pos.seq_last, ctrack->req_seq_start, ctrack->req_seq_end);
|
||||
ctrack_stop_retrans_counter(ctrack);
|
||||
auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname, client_ip_port, l7proto);
|
||||
return false;
|
||||
@@ -344,14 +344,14 @@ static bool send_delayed(t_ctrack *ctrack)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rawpacket_queue_csum_fix(struct rawpacket_tailhead *q, const struct dissect *dis, const struct sockaddr_storage* dst, uint32_t fwmark, uint32_t desync_fwmark, const char *ifin, const char *ifout)
|
||||
static bool rawpacket_queue_csum_fix(struct rawpacket_tailhead *q, const struct dissect *dis, const t_ctrack_position *pos, const struct sockaddr_storage* dst, uint32_t fwmark, uint32_t desync_fwmark, const char *ifin, const char *ifout)
|
||||
{
|
||||
// this breaks const pointer to l4 header
|
||||
if (dis->tcp)
|
||||
verdict_tcp_csum_fix(VERDICT_PASS, (struct tcphdr *)dis->tcp, dis->transport_len, dis->ip, dis->ip6);
|
||||
else if (dis->udp)
|
||||
verdict_udp_csum_fix(VERDICT_PASS, (struct udphdr *)dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||
return rawpacket_queue(q, dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload);
|
||||
return rawpacket_queue(q, dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ static bool reasm_start(t_ctrack *ctrack, t_reassemble *reasm, uint8_t proto, si
|
||||
ReasmClear(reasm);
|
||||
if (sz <= szMax)
|
||||
{
|
||||
uint32_t seq = (proto == IPPROTO_TCP) ? ctrack->seq_last : 0;
|
||||
uint32_t seq = (proto == IPPROTO_TCP) ? ctrack->pos.seq_last : 0;
|
||||
if (ReasmInit(reasm, sz, seq))
|
||||
{
|
||||
ReasmFeed(reasm, seq, data_payload, len_payload);
|
||||
@@ -382,7 +382,7 @@ static bool reasm_feed(t_ctrack *ctrack, t_reassemble *reasm, uint8_t proto, con
|
||||
{
|
||||
if (ctrack && !ReasmIsEmpty(reasm))
|
||||
{
|
||||
uint32_t seq = (proto == IPPROTO_TCP) ? ctrack->seq_last : (uint32_t)reasm->size_present;
|
||||
uint32_t seq = (proto == IPPROTO_TCP) ? ctrack->pos.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);
|
||||
@@ -429,7 +429,7 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
|
||||
// if used in postnat chain, dropping initial packet will cause conntrack connection teardown
|
||||
// so we need to workaround this.
|
||||
// SYN and SYN,ACK checks are for conntrack-less mode
|
||||
if (ctrack && (params.server ? ctrack->pcounter_reply : ctrack->pcounter_orig) == 1 || dis->tcp && (tcp_syn_segment(dis->tcp) || tcp_synack_segment(dis->tcp)))
|
||||
if (ctrack && (params.server ? ctrack->pos.pcounter_reply : ctrack->pos.pcounter_orig) == 1 || dis->tcp && (tcp_syn_segment(dis->tcp) || tcp_synack_segment(dis->tcp)))
|
||||
{
|
||||
if (dis->len_pkt > *len_mod_pkt)
|
||||
DLOG_ERR("linux postnat conntrack workaround cannot be applied\n");
|
||||
@@ -458,60 +458,60 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
|
||||
}
|
||||
|
||||
|
||||
static uint64_t pos_get(const t_ctrack *ctrack, char mode, bool bReply)
|
||||
static uint64_t pos_get(const t_ctrack_position *pos, char mode, bool bReply)
|
||||
{
|
||||
if (ctrack)
|
||||
if (pos)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case 'n': return bReply ? ctrack->pcounter_reply : ctrack->pcounter_orig;
|
||||
case 'd': return bReply ? ctrack->pdcounter_reply : ctrack->pdcounter_orig;
|
||||
case 's': return bReply ? (ctrack->ack_last - ctrack->ack0) : (ctrack->seq_last - ctrack->seq0);
|
||||
case 'b': return bReply ? ctrack->pbcounter_reply : ctrack->pbcounter_orig;
|
||||
case 'n': return bReply ? pos->pcounter_reply : pos->pcounter_orig;
|
||||
case 'd': return bReply ? pos->pdcounter_reply : pos->pdcounter_orig;
|
||||
case 's': return bReply ? (pos->ack_last - pos->ack0) : (pos->seq_last - pos->seq0);
|
||||
case 'b': return bReply ? pos->pbcounter_reply : pos->pbcounter_orig;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static bool check_pos_from(const t_ctrack *ctrack, bool bReply, const struct packet_range *range)
|
||||
static bool check_pos_from(const t_ctrack_position *pos, bool bReply, const struct packet_range *range)
|
||||
{
|
||||
uint64_t pos;
|
||||
uint64_t ps;
|
||||
if (range->from.mode == 'x') return false;
|
||||
if (range->from.mode != 'a')
|
||||
{
|
||||
if (ctrack)
|
||||
if (pos)
|
||||
{
|
||||
pos = pos_get(ctrack, range->from.mode, bReply);
|
||||
return pos >= range->from.pos;
|
||||
ps = pos_get(pos, range->from.mode, bReply);
|
||||
return ps >= range->from.pos;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool check_pos_to(const t_ctrack *ctrack, bool bReply, const struct packet_range *range)
|
||||
static bool check_pos_to(const t_ctrack_position *pos, bool bReply, const struct packet_range *range)
|
||||
{
|
||||
uint64_t pos;
|
||||
uint64_t ps;
|
||||
if (range->to.mode == 'x') return false;
|
||||
if (range->to.mode != 'a')
|
||||
{
|
||||
if (ctrack)
|
||||
if (pos)
|
||||
{
|
||||
pos = pos_get(ctrack, range->to.mode, bReply);
|
||||
return (pos < range->to.pos) || !range->upper_cutoff && (pos == range->to.pos);
|
||||
ps = pos_get(pos, range->to.mode, bReply);
|
||||
return (ps < range->to.pos) || !range->upper_cutoff && (ps == range->to.pos);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool check_pos_cutoff(const t_ctrack *ctrack, bool bReply, const struct packet_range *range)
|
||||
static bool check_pos_cutoff(const t_ctrack_position *pos, bool bReply, const struct packet_range *range)
|
||||
{
|
||||
bool bto = check_pos_to(ctrack, bReply, range);
|
||||
return ctrack ? !bto : (!bto || !check_pos_from(ctrack, bReply, range));
|
||||
bool bto = check_pos_to(pos, bReply, range);
|
||||
return pos ? !bto : (!bto || !check_pos_from(pos, bReply, range));
|
||||
}
|
||||
static bool check_pos_range(const t_ctrack *ctrack, bool bReply, const struct packet_range *range)
|
||||
static bool check_pos_range(const t_ctrack_position *pos, bool bReply, const struct packet_range *range)
|
||||
{
|
||||
return check_pos_from(ctrack, bReply, range) && check_pos_to(ctrack, bReply, range);
|
||||
return check_pos_from(pos, bReply, range) && check_pos_to(pos, bReply, range);
|
||||
}
|
||||
|
||||
|
||||
@@ -645,6 +645,7 @@ static uint8_t desync(
|
||||
const char *ifout,
|
||||
bool bIncoming,
|
||||
t_ctrack *ctrack,
|
||||
const t_ctrack_position *pos,
|
||||
t_l7payload l7payload,
|
||||
const struct dissect *dis,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt,
|
||||
@@ -674,6 +675,7 @@ static uint8_t desync(
|
||||
DLOG("lua out cutoff\n");
|
||||
return verdict;
|
||||
}
|
||||
if (!pos) pos = &ctrack->pos;
|
||||
}
|
||||
if (LIST_FIRST(&dp->lua_desync))
|
||||
{
|
||||
@@ -693,12 +695,12 @@ static uint8_t desync(
|
||||
{
|
||||
if (lua_instance_cutoff_check(&ctx, bIncoming))
|
||||
DLOG("* lua '%s' : voluntary cutoff\n", instance);
|
||||
else if (check_pos_cutoff(ctrack, bIncoming, range))
|
||||
else if (check_pos_cutoff(pos, bIncoming, range))
|
||||
{
|
||||
DLOG("* lua '%s' : %s pos %c%llu %c%llu is beyond range %c%u%c%c%u (ctrack %s)\n",
|
||||
instance, sDirection,
|
||||
range->from.mode, pos_get(ctrack, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(ctrack, range->to.mode, bIncoming),
|
||||
range->from.mode, pos_get(pos, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(pos, range->to.mode, bIncoming),
|
||||
range->from.mode, range->from.pos,
|
||||
range->upper_cutoff ? '<' : '-',
|
||||
range->to.mode, range->to.pos,
|
||||
@@ -721,7 +723,7 @@ static uint8_t desync(
|
||||
// create arg table that persists across multiple desync function calls
|
||||
lua_createtable(params.L, 0, 12 + !!dp->name + !!ctrack + !!dis->tcp + 3*!!replay_piece_count);
|
||||
lua_pushf_dissect(dis);
|
||||
lua_pushf_ctrack(ctrack);
|
||||
lua_pushf_ctrack(ctrack, pos);
|
||||
lua_pushf_int("profile_n", dp->n);
|
||||
if (dp->name) lua_pushf_str("profile_name", dp->name);
|
||||
lua_pushf_bool("outgoing", !bIncoming);
|
||||
@@ -743,8 +745,8 @@ static uint8_t desync(
|
||||
if (dis->tcp)
|
||||
{
|
||||
// recommended mss value for generated packets
|
||||
if (ctrack && ctrack->mss_orig)
|
||||
lua_pushf_int("tcp_mss", ctrack->mss_orig);
|
||||
if (pos && pos->mss_orig)
|
||||
lua_pushf_int("tcp_mss", pos->mss_orig);
|
||||
else
|
||||
lua_pushf_global("tcp_mss", "DEFAULT_MSS");
|
||||
}
|
||||
@@ -760,12 +762,12 @@ static uint8_t desync(
|
||||
if (!lua_instance_cutoff_check(&ctx, bIncoming))
|
||||
{
|
||||
range = bIncoming ? &func->range_in : &func->range_out;
|
||||
if (check_pos_range(ctrack, bIncoming, range))
|
||||
if (check_pos_range(pos, bIncoming, range))
|
||||
{
|
||||
DLOG("* lua '%s' : %s pos %c%llu %c%llu in range %c%u%c%c%u\n",
|
||||
instance, sDirection,
|
||||
range->from.mode, pos_get(ctrack, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(ctrack, range->to.mode, bIncoming),
|
||||
range->from.mode, pos_get(pos, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(pos, range->to.mode, bIncoming),
|
||||
range->from.mode, range->from.pos,
|
||||
range->upper_cutoff ? '<' : '-',
|
||||
range->to.mode, range->to.pos);
|
||||
@@ -810,8 +812,8 @@ static uint8_t desync(
|
||||
else
|
||||
DLOG("* lua '%s' : %s pos %c%llu %c%llu out of range %c%u%c%c%u\n",
|
||||
instance, sDirection,
|
||||
range->from.mode, pos_get(ctrack, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(ctrack, range->to.mode, bIncoming),
|
||||
range->from.mode, pos_get(pos, range->from.mode, bIncoming),
|
||||
range->to.mode, pos_get(pos, range->to.mode, bIncoming),
|
||||
range->from.mode, range->from.pos,
|
||||
range->upper_cutoff ? '<' : '-',
|
||||
range->to.mode, range->to.pos);
|
||||
@@ -905,7 +907,13 @@ static void setup_direction(
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout, const struct dissect *dis, uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
static uint8_t dpi_desync_tcp_packet_play(
|
||||
unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset,
|
||||
uint32_t fwmark,
|
||||
const char *ifin, const char *ifout,
|
||||
const t_ctrack_position *pos,
|
||||
const struct dissect *dis,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
uint8_t verdict = VERDICT_PASS;
|
||||
|
||||
@@ -972,7 +980,6 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
// in absence of conntrack guess direction by presence of interface names. won't work on BSD
|
||||
bReverseFixed = ctrack ? (bReverse ^ params.server) : (bReverse = ifin && ifin && (!ifout || !*ifout));
|
||||
setup_direction(dis, bReverseFixed, &src, &dst, &sdip4, &sdip6, &sdport);
|
||||
|
||||
ifname = bReverse ? ifin : ifout;
|
||||
#ifdef HAS_FILTER_SSID
|
||||
ssid = wlan_ssid_search_ifname(ifname);
|
||||
@@ -992,7 +999,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
if (!hostname && !bReverse)
|
||||
{
|
||||
if (ipcache_get_hostname(sdip4, sdip6, host, sizeof(host), &hostname_is_ip) && *host)
|
||||
if (!(hostname = ctrack_replay->hostname = strdup(host)))
|
||||
if (!(hostname = ctrack->hostname = strdup(host)))
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
}
|
||||
@@ -1061,7 +1068,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
// process reply packets for auto hostlist mode
|
||||
// by looking at RSTs or HTTP replies we decide whether original request looks like DPI blocked
|
||||
// we only process first-sequence replies. do not react to subsequent redirects or RSTs
|
||||
if (!params.server && ctrack && ctrack->hostname && ctrack->hostname_ah_check && (ctrack->ack_last - ctrack->ack0) == 1)
|
||||
if (!params.server && ctrack && ctrack->hostname && ctrack->hostname_ah_check && (ctrack->pos.ack_last - ctrack->pos.ack0) == 1)
|
||||
{
|
||||
bool bFail = false;
|
||||
|
||||
@@ -1151,8 +1158,8 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
// we do not reassemble http
|
||||
if (!ctrack->req_seq_present)
|
||||
{
|
||||
ctrack->req_seq_start = ctrack->seq_last;
|
||||
ctrack->req_seq_end = ctrack->pos_orig - 1;
|
||||
ctrack->req_seq_start = ctrack->pos.seq_last;
|
||||
ctrack->req_seq_end = ctrack->pos.pos_orig - 1;
|
||||
ctrack->req_seq_present = ctrack->req_seq_finalized = true;
|
||||
DLOG("req retrans : tcp seq interval %u-%u\n", ctrack->req_seq_start, ctrack->req_seq_end);
|
||||
}
|
||||
@@ -1176,7 +1183,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
{
|
||||
// do not reasm retransmissions
|
||||
if (!bReqFull && ReasmIsEmpty(&ctrack->reasm_orig) && !ctrack->req_seq_abandoned &&
|
||||
!(ctrack->req_seq_finalized && seq_within(ctrack->seq_last, ctrack->req_seq_start, ctrack->req_seq_end)))
|
||||
!(ctrack->req_seq_finalized && seq_within(ctrack->pos.seq_last, ctrack->req_seq_start, ctrack->req_seq_end)))
|
||||
{
|
||||
// do not reconstruct unexpected large payload (they are feeding garbage ?)
|
||||
if (!reasm_orig_start(ctrack, IPPROTO_TCP, TLSRecordLen(dis->data_payload), TCP_MAX_REASM, dis->data_payload, dis->len_payload))
|
||||
@@ -1187,19 +1194,19 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
if (!ctrack->req_seq_present)
|
||||
{
|
||||
// lower bound of request seq interval
|
||||
ctrack->req_seq_start = ctrack->seq_last;
|
||||
ctrack->req_seq_start = ctrack->pos.seq_last;
|
||||
ctrack->req_seq_present = true;
|
||||
}
|
||||
// upper bound of request seq interval
|
||||
// it can grow on every packet until request is complete. then interval is finalized and never touched again.
|
||||
ctrack->req_seq_end = ctrack->pos_orig - 1;
|
||||
ctrack->req_seq_end = ctrack->pos.pos_orig - 1;
|
||||
DLOG("req retrans : seq interval %u-%u\n", ctrack->req_seq_start, ctrack->req_seq_end);
|
||||
ctrack->req_seq_finalized |= bReqFull;
|
||||
}
|
||||
|
||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||
{
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &ctrack->pos, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
{
|
||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
}
|
||||
@@ -1217,7 +1224,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctrack && (ctrack->seq_last - ctrack->seq0)==1 && IsMTProto(dis->data_payload, dis->len_payload))
|
||||
else if (ctrack && (ctrack->pos.seq_last - ctrack->pos.seq0)==1 && IsMTProto(dis->data_payload, dis->len_payload))
|
||||
{
|
||||
DLOG("packet contains telegram mtproto2 initial\n");
|
||||
// mtproto detection requires aes. react only on the first tcp data packet. do not detect if ctrack unavailable.
|
||||
@@ -1238,7 +1245,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
}
|
||||
if (ctrack && ctrack->req_seq_finalized)
|
||||
{
|
||||
uint32_t dseq = ctrack->seq_last - ctrack->req_seq_end;
|
||||
uint32_t dseq = ctrack->pos.seq_last - ctrack->req_seq_end;
|
||||
// do not react to 32-bit overflowed sequence numbers. allow 16 Mb grace window then cutoff.
|
||||
if (dseq >= 0x1000000 && !(dseq & 0x80000000)) ctrack->req_seq_abandoned = true;
|
||||
}
|
||||
@@ -1344,7 +1351,7 @@ static uint8_t dpi_desync_tcp_packet_play(unsigned int replay_piece, unsigned in
|
||||
ntop46_port((struct sockaddr *)&dst, s2, sizeof(s2));
|
||||
DLOG("dpi desync src=%s dst=%s track_direction=%s fixed_direction=%s connection_proto=%s payload_type=%s\n", s1, s2, bReverse ? "in" : "out", bReverseFixed ? "in" : "out", l7proto_str(l7proto), l7payload_str(l7payload));
|
||||
}
|
||||
verdict = desync(dp, fwmark, ifin, ifout, bReverseFixed, ctrack_replay, l7payload, dis, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, rdata_payload, rlen_payload, NULL, 0);
|
||||
verdict = desync(dp, fwmark, ifin, ifout, bReverseFixed, ctrack_replay, pos, l7payload, dis, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, rdata_payload, rlen_payload, NULL, 0);
|
||||
|
||||
pass:
|
||||
return (!bReverseFixed && (verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ctrack, dis, mod_pkt, len_mod_pkt) : verdict;
|
||||
@@ -1361,7 +1368,13 @@ static void quic_reasm_cancel(t_ctrack *ctrack, const char *reason)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t dpi_desync_udp_packet_play(unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout, const struct dissect *dis, uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
static uint8_t dpi_desync_udp_packet_play(
|
||||
unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset,
|
||||
uint32_t fwmark,
|
||||
const char *ifin, const char *ifout,
|
||||
const t_ctrack_position *pos,
|
||||
const struct dissect *dis,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
uint8_t verdict = VERDICT_PASS;
|
||||
|
||||
@@ -1465,7 +1478,7 @@ static uint8_t dpi_desync_udp_packet_play(unsigned int replay_piece, unsigned in
|
||||
if (!hostname && !bReverse)
|
||||
{
|
||||
if (ipcache_get_hostname(sdip4, sdip6, host, sizeof(host), &hostname_is_ip) && *host)
|
||||
if (!(hostname = ctrack_replay->hostname = strdup(host)))
|
||||
if (!(hostname = ctrack->hostname = strdup(host)))
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
}
|
||||
@@ -1594,7 +1607,7 @@ static uint8_t dpi_desync_udp_packet_play(unsigned int replay_piece, unsigned in
|
||||
}
|
||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||
{
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &ctrack->pos, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
{
|
||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
}
|
||||
@@ -1634,7 +1647,7 @@ static uint8_t dpi_desync_udp_packet_play(unsigned int replay_piece, unsigned in
|
||||
if (!reasm_orig_start(ctrack, IPPROTO_UDP, UDP_MAX_REASM, UDP_MAX_REASM, clean, clean_len))
|
||||
goto pass_reasm_cancel;
|
||||
}
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
if (rawpacket_queue_csum_fix(&ctrack->delayed, dis, &ctrack->pos, &dst, fwmark, desync_fwmark, ifin, ifout))
|
||||
{
|
||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
}
|
||||
@@ -1793,7 +1806,7 @@ static uint8_t dpi_desync_udp_packet_play(unsigned int replay_piece, unsigned in
|
||||
ntop46_port((struct sockaddr *)&dst, s2, sizeof(s2));
|
||||
DLOG("dpi desync src=%s dst=%s track_direction=%s fixed_direction=%s connection_proto=%s payload_type=%s\n", s1, s2, bReverse ? "in" : "out", bReverseFixed ? "in" : "out", l7proto_str(l7proto), l7payload_str(l7payload));
|
||||
}
|
||||
verdict = desync(dp, fwmark, ifin, ifout, bReverseFixed, ctrack_replay, l7payload, dis, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, NULL, 0, data_decrypt, len_decrypt);
|
||||
verdict = desync(dp, fwmark, ifin, ifout, bReverseFixed, ctrack_replay, pos, l7payload, dis, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, NULL, 0, data_decrypt, len_decrypt);
|
||||
|
||||
pass:
|
||||
return (!bReverse && (verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ctrack, dis, mod_pkt, len_mod_pkt) : verdict;
|
||||
@@ -1842,6 +1855,7 @@ static void packet_debug(bool replay, const struct dissect *dis)
|
||||
|
||||
static uint8_t dpi_desync_packet_play(
|
||||
unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout,
|
||||
const t_ctrack_position *pos,
|
||||
const uint8_t *data_pkt, size_t len_pkt,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
@@ -1857,7 +1871,7 @@ static uint8_t dpi_desync_packet_play(
|
||||
case IPPROTO_TCP:
|
||||
if (dis.tcp)
|
||||
{
|
||||
verdict = dpi_desync_tcp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, &dis, mod_pkt, len_mod_pkt);
|
||||
verdict = dpi_desync_tcp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, pos, &dis, mod_pkt, len_mod_pkt);
|
||||
// we fix csum before pushing to replay queue
|
||||
if (!replay_piece_count) verdict_tcp_csum_fix(verdict, (struct tcphdr *)dis.tcp, dis.transport_len, dis.ip, dis.ip6);
|
||||
}
|
||||
@@ -1865,7 +1879,7 @@ static uint8_t dpi_desync_packet_play(
|
||||
case IPPROTO_UDP:
|
||||
if (dis.udp)
|
||||
{
|
||||
verdict = dpi_desync_udp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, &dis, mod_pkt, len_mod_pkt);
|
||||
verdict = dpi_desync_udp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, pos, &dis, mod_pkt, len_mod_pkt);
|
||||
// we fix csum before pushing to replay queue
|
||||
if (!replay_piece_count) verdict_udp_csum_fix(verdict, (struct udphdr *)dis.udp, dis.transport_len, dis.ip, dis.ip6);
|
||||
}
|
||||
@@ -1877,7 +1891,7 @@ static uint8_t dpi_desync_packet_play(
|
||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, const uint8_t *data_pkt, size_t len_pkt, uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
ipcachePurgeRateLimited(¶ms.ipcache, params.ipcache_lifetime);
|
||||
return dpi_desync_packet_play(0, 0, 0, fwmark, ifin, ifout, data_pkt, len_pkt, mod_pkt, len_mod_pkt);
|
||||
return dpi_desync_packet_play(0, 0, 0, fwmark, ifin, ifout, NULL, data_pkt, len_pkt, mod_pkt, len_mod_pkt);
|
||||
}
|
||||
|
||||
|
||||
@@ -1895,7 +1909,7 @@ static bool replay_queue(struct rawpacket_tailhead *q)
|
||||
{
|
||||
DLOG("REPLAYING delayed packet #%u offset %zu\n", i+1, offset);
|
||||
modlen = sizeof(mod);
|
||||
uint8_t verdict = dpi_desync_packet_play(i, count, offset, rp->fwmark_orig, rp->ifin, rp->ifout, rp->packet, rp->len, mod, &modlen);
|
||||
uint8_t verdict = dpi_desync_packet_play(i, count, offset, rp->fwmark_orig, rp->ifin, rp->ifout, rp->pos_present ? &rp->pos : NULL, rp->packet, rp->len, mod, &modlen);
|
||||
switch (verdict & VERDICT_MASK)
|
||||
{
|
||||
case VERDICT_MODIFY:
|
||||
|
||||
44
nfq2/lua.c
44
nfq2/lua.c
@@ -1167,21 +1167,23 @@ void lua_pushf_dissect(const struct dissect *dis)
|
||||
lua_rawset(params.L,-3);
|
||||
}
|
||||
|
||||
void lua_pushf_ctrack(const t_ctrack *ctrack)
|
||||
void lua_pushf_ctrack(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
||||
{
|
||||
LUA_STACK_GUARD_ENTER(params.L)
|
||||
|
||||
if (!pos) pos = &ctrack->pos;
|
||||
|
||||
lua_pushliteral(params.L, "track");
|
||||
if (ctrack)
|
||||
{
|
||||
lua_createtable(params.L, 0, 13 + (ctrack->ipproto == IPPROTO_TCP));
|
||||
|
||||
lua_pushf_int("pcounter_orig", ctrack->pcounter_orig);
|
||||
lua_pushf_int("pdcounter_orig", ctrack->pdcounter_orig);
|
||||
lua_pushf_int("pbcounter_orig", ctrack->pbcounter_orig);
|
||||
lua_pushf_int("pcounter_reply", ctrack->pcounter_reply);
|
||||
lua_pushf_int("pdcounter_reply", ctrack->pdcounter_reply);
|
||||
lua_pushf_int("pbcounter_reply", ctrack->pbcounter_reply);
|
||||
lua_pushf_int("pcounter_orig", pos->pcounter_orig);
|
||||
lua_pushf_int("pdcounter_orig", pos->pdcounter_orig);
|
||||
lua_pushf_int("pbcounter_orig", pos->pbcounter_orig);
|
||||
lua_pushf_int("pcounter_reply", pos->pcounter_reply);
|
||||
lua_pushf_int("pdcounter_reply", pos->pdcounter_reply);
|
||||
lua_pushf_int("pbcounter_reply", pos->pbcounter_reply);
|
||||
if (ctrack->incoming_ttl)
|
||||
lua_pushf_int("incoming_ttl", ctrack->incoming_ttl);
|
||||
else
|
||||
@@ -1197,20 +1199,20 @@ void lua_pushf_ctrack(const t_ctrack *ctrack)
|
||||
{
|
||||
lua_pushliteral(params.L, "tcp");
|
||||
lua_createtable(params.L, 0, 14);
|
||||
lua_pushf_int("seq0", ctrack->seq0);
|
||||
lua_pushf_int("seq", ctrack->seq_last);
|
||||
lua_pushf_int("ack0", ctrack->ack0);
|
||||
lua_pushf_int("ack", ctrack->ack_last);
|
||||
lua_pushf_int("pos_orig", ctrack->pos_orig - ctrack->seq0);
|
||||
lua_pushf_int("winsize_orig", ctrack->winsize_orig);
|
||||
lua_pushf_int("winsize_orig_calc", ctrack->winsize_orig_calc);
|
||||
lua_pushf_int("scale_orig", ctrack->scale_orig);
|
||||
lua_pushf_int("mss_orig", ctrack->mss_orig);
|
||||
lua_pushf_int("pos_reply", ctrack->pos_reply - ctrack->ack0);
|
||||
lua_pushf_int("winsize_reply", ctrack->winsize_reply);
|
||||
lua_pushf_int("winsize_reply_calc", ctrack->winsize_reply_calc);
|
||||
lua_pushf_int("scale_reply", ctrack->scale_reply);
|
||||
lua_pushf_int("mss_reply", ctrack->mss_reply);
|
||||
lua_pushf_int("seq0", pos->seq0);
|
||||
lua_pushf_int("seq", pos->seq_last);
|
||||
lua_pushf_int("ack0", pos->ack0);
|
||||
lua_pushf_int("ack", pos->ack_last);
|
||||
lua_pushf_int("pos_orig", pos->pos_orig - pos->seq0);
|
||||
lua_pushf_int("winsize_orig", pos->winsize_orig);
|
||||
lua_pushf_int("winsize_orig_calc", pos->winsize_orig_calc);
|
||||
lua_pushf_int("scale_orig", pos->scale_orig);
|
||||
lua_pushf_int("mss_orig", pos->mss_orig);
|
||||
lua_pushf_int("pos_reply", pos->pos_reply - pos->ack0);
|
||||
lua_pushf_int("winsize_reply", pos->winsize_reply);
|
||||
lua_pushf_int("winsize_reply_calc", pos->winsize_reply_calc);
|
||||
lua_pushf_int("scale_reply", pos->scale_reply);
|
||||
lua_pushf_int("mss_reply", pos->mss_reply);
|
||||
lua_rawset(params.L,-3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ void lua_pushf_iphdr(const struct ip *ip, size_t len);
|
||||
void lua_pushf_ip6hdr(const struct ip6_hdr *ip6, size_t len);
|
||||
void lua_push_dissect(const struct dissect *dis);
|
||||
void lua_pushf_dissect(const struct dissect *dis);
|
||||
void lua_pushf_ctrack(const t_ctrack *ctrack);
|
||||
void lua_pushf_ctrack(const t_ctrack *ctrack, const t_ctrack_position *pos);
|
||||
void lua_pushf_args(const struct ptr_list_head *args, int idx_desync);
|
||||
void lua_pushf_pos(const char *name, const struct packet_pos *pos);
|
||||
void lua_pushf_range(const char *name, const struct packet_range *range);
|
||||
|
||||
@@ -26,7 +26,7 @@ void rawpacket_queue_destroy(struct rawpacket_tailhead *q)
|
||||
while((rp = rawpacket_dequeue(q))) rawpacket_free(rp);
|
||||
}
|
||||
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload)
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_position *pos)
|
||||
{
|
||||
struct rawpacket *rp = malloc(sizeof(struct rawpacket));
|
||||
if (!rp) return NULL;
|
||||
@@ -52,6 +52,15 @@ struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sock
|
||||
memcpy(rp->packet,data,len);
|
||||
rp->len=len;
|
||||
rp->len_payload=len_payload;
|
||||
|
||||
// make a copy for replay
|
||||
if (pos)
|
||||
{
|
||||
rp->pos = *pos;
|
||||
rp->pos_present = true;
|
||||
}
|
||||
else
|
||||
rp->pos_present = false;
|
||||
|
||||
TAILQ_INSERT_TAIL(q, rp, next);
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <net/if.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "conntrack_base.h"
|
||||
|
||||
struct rawpacket
|
||||
{
|
||||
struct sockaddr_storage dst;
|
||||
@@ -14,6 +16,8 @@ struct rawpacket
|
||||
uint32_t fwmark;
|
||||
size_t len, len_payload;
|
||||
uint8_t *packet;
|
||||
t_ctrack_position pos;
|
||||
bool pos_present;
|
||||
TAILQ_ENTRY(rawpacket) next;
|
||||
};
|
||||
TAILQ_HEAD(rawpacket_tailhead, rawpacket);
|
||||
@@ -22,6 +26,6 @@ void rawpacket_queue_init(struct rawpacket_tailhead *q);
|
||||
void rawpacket_queue_destroy(struct rawpacket_tailhead *q);
|
||||
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q);
|
||||
unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q);
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload);
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_position *pos);
|
||||
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q);
|
||||
void rawpacket_free(struct rawpacket *rp);
|
||||
|
||||
Reference in New Issue
Block a user