diff --git a/nfq/conntrack.c b/nfq/conntrack.c index 1f1fd7c..22b82dd 100644 --- a/nfq/conntrack.c +++ b/nfq/conntrack.c @@ -12,29 +12,6 @@ static void ut_oom_recover(void *elem) oom = true; } -const char *l7proto_str(t_l7proto l7) -{ - switch(l7) - { - case HTTP: return "http"; - case TLS: return "tls"; - case QUIC: return "quic"; - case WIREGUARD: return "wireguard"; - case DHT: return "dht"; - default: return "unknown"; - } -} -bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7) -{ - return (l7proto==UNKNOWN && (filter_l7 & L7_PROTO_UNKNOWN)) || - (l7proto==HTTP && (filter_l7 & L7_PROTO_HTTP)) || - (l7proto==TLS && (filter_l7 & L7_PROTO_TLS)) || - (l7proto==QUIC && (filter_l7 & L7_PROTO_QUIC)) || - (l7proto==WIREGUARD && (filter_l7 & L7_PROTO_WIREGUARD)) || - (l7proto==DHT && (filter_l7 & L7_PROTO_DHT)); -} - - static const char *connstate_s[]={"SYN","ESTABLISHED","FIN"}; static void connswap(const t_conn *c, t_conn *c2) diff --git a/nfq/conntrack.h b/nfq/conntrack.h index 415c533..ffe5270 100644 --- a/nfq/conntrack.h +++ b/nfq/conntrack.h @@ -4,8 +4,6 @@ // this conntrack is not bullet-proof // its designed to satisfy dpi desync needs only -#include "packet_queue.h" - #include #include #include @@ -19,6 +17,8 @@ #include #include +#include "packet_queue.h" +#include "protocol.h" //#define HASH_BLOOM 20 #define HASH_NONFATAL_OOM 1 @@ -53,16 +53,6 @@ typedef struct { // FIN - FIN or RST received typedef enum {SYN=0, ESTABLISHED, FIN} t_connstate; -typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT} t_l7proto; -#define L7_PROTO_HTTP 0x00000001 -#define L7_PROTO_TLS 0x00000002 -#define L7_PROTO_QUIC 0x00000004 -#define L7_PROTO_WIREGUARD 0x00000008 -#define L7_PROTO_DHT 0x00000010 -#define L7_PROTO_UNKNOWN 0x80000000 -const char *l7proto_str(t_l7proto l7); -bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7); - typedef struct { bool bCheckDone, bCheckResult, bCheckExcluded; // hostlist check result cache diff --git a/nfq/desync.c b/nfq/desync.c index 729ca29..2391b42 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -607,31 +607,6 @@ static void autottl_discover(t_ctrack *ctrack, bool bIpv6) } } -static size_t resolve_split(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct split_pos *sp) -{ - switch(l7proto) - { - case HTTP: - return HttpPos(sp->marker, sp->pos, data, sz); - case TLS: - return TLSPos(sp->marker, sp->pos, data, sz); - default: - return AnyProtoPos(sp->marker, sp->pos, data, sz); - } -} -static void resolve_multisplit(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct desync_profile *dp, size_t *pos, int *pos_count) -{ - int i,j; - for(i=j=0;isplit_count;i++) - { - pos[j] = resolve_split(data,sz,l7proto,dp->splits+i); - if (pos[j]) j++; - } - qsort_size_t(pos, j); - j=unique_size_t(pos, j); - *pos_count=j; -} - static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis) { uint8_t verdict=VERDICT_PASS; @@ -1157,7 +1132,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode==DESYNC_MULTIDISORDER || dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER) { split_pos=0; - resolve_multisplit(rdata_payload, rlen_payload, l7proto, dp, multisplit_pos, &multisplit_count); + ResolveMultiPos(rdata_payload, rlen_payload, l7proto, dp->splits, dp->split_count, multisplit_pos, &multisplit_count); if (params.debug) { if (multisplit_count) @@ -1174,7 +1149,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint dp->desync_mode2==DESYNC_SPLIT || dp->desync_mode2==DESYNC_SPLIT2 || dp->desync_mode2==DESYNC_DISORDER || dp->desync_mode2==DESYNC_DISORDER2) { multisplit_count=0; - split_pos = resolve_split(rdata_payload, rlen_payload, l7proto, spos); + split_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, spos); DLOG("regular split pos: %zu\n",split_pos); } else diff --git a/nfq/nfqws.c b/nfq/nfqws.c index c9f18ed..317a5ad 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -2048,6 +2048,13 @@ int main(int argc, char **argv) LIST_FOREACH(dpl, ¶ms.desync_profiles, next) { dp = &dpl->dp; + + if (!dp->split_count && (dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode==DESYNC_MULTIDISORDER || dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER)) + { + DLOG_ERR("multisplit requires explicit split pos\n"); + exit_clean(1); + } + // not specified - use desync_ttl value instead if (dp->desync_ttl6 == 0xFF) dp->desync_ttl6=dp->desync_ttl; if (!AUTOTTL_ENABLED(dp->desync_autottl6)) dp->desync_autottl6 = dp->desync_autottl; diff --git a/nfq/params.h b/nfq/params.h index 4fff9dc..a224ae0 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -38,16 +38,10 @@ #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 split_pos -{ - int16_t pos; - uint8_t marker; -}; -#define SPLIT_POS_EMPTY(sp) ((sp)->marker==PM_ABS && (sp)->pos==0) #define MAX_SPLITS 64 +enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG }; + struct desync_profile { int n; // number of the profile diff --git a/nfq/protocol.c b/nfq/protocol.c index 1283e2c..67a0ff9 100644 --- a/nfq/protocol.c +++ b/nfq/protocol.c @@ -24,6 +24,27 @@ static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t ** return true; } +const char *l7proto_str(t_l7proto l7) +{ + switch(l7) + { + case HTTP: return "http"; + case TLS: return "tls"; + case QUIC: return "quic"; + case WIREGUARD: return "wireguard"; + case DHT: return "dht"; + default: return "unknown"; + } +} +bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7) +{ + return (l7proto==UNKNOWN && (filter_l7 & L7_PROTO_UNKNOWN)) || + (l7proto==HTTP && (filter_l7 & L7_PROTO_HTTP)) || + (l7proto==TLS && (filter_l7 & L7_PROTO_TLS)) || + (l7proto==QUIC && (filter_l7 & L7_PROTO_QUIC)) || + (l7proto==WIREGUARD && (filter_l7 & L7_PROTO_WIREGUARD)) || + (l7proto==DHT && (filter_l7 & L7_PROTO_DHT)); +} #define PM_ABS 0 #define PM_HOST 1 @@ -104,6 +125,30 @@ static size_t HostPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_ } return CheckPos(sz,offset); } +size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct split_pos *sp) +{ + switch(l7proto) + { + case HTTP: + return HttpPos(sp->marker, sp->pos, data, sz); + case TLS: + return TLSPos(sp->marker, sp->pos, data, sz); + default: + return AnyProtoPos(sp->marker, sp->pos, data, sz); + } +} +void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct split_pos *splits, int split_count, size_t *pos, int *pos_count) +{ + int i,j; + for(i=j=0;imarker==PM_ABS && (sp)->pos==0) bool IsHostMarker(uint8_t posmarker); const char *posmarker_name(uint8_t posmarker); size_t AnyProtoPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); +size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct split_pos *sp); +void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct split_pos *splits, int split_count, size_t *pos, int *pos_count); extern const char *http_methods[9]; const char *HttpMethod(const uint8_t *data, size_t len);