From 3046dd80138fab53ea79165ad91d13eac1c0848a Mon Sep 17 00:00:00 2001 From: bol-van Date: Thu, 5 Feb 2026 12:19:31 +0300 Subject: [PATCH] nfqws2: bt and utp_bt protocol detectors --- nfq2/desync.c | 11 +++++++---- nfq2/protocol.c | 17 +++++++++++++++-- nfq2/protocol.h | 7 ++++++- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/nfq2/desync.c b/nfq2/desync.c index 8153ae4..baab3b4 100644 --- a/nfq2/desync.c +++ b/nfq2/desync.c @@ -1452,7 +1452,8 @@ static uint8_t dpi_desync_tcp_packet_play( {L7P_HTTP_REPLY,L7_HTTP,IsHttpReply,false}, {L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false}, {L7P_XMPP_PROCEED,L7_XMPP,IsXMPPProceedTLS,false}, - {L7P_XMPP_FEATURES,L7_XMPP,IsXMPPFeatures,false} + {L7P_XMPP_FEATURES,L7_XMPP,IsXMPPFeatures,false}, + {L7P_BT_HANDSHAKE,L7_BT,IsBTHandshake,false} }; protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ps.ctrack, &ps.l7proto, &ps.l7payload); @@ -1532,10 +1533,11 @@ static uint8_t dpi_desync_tcp_packet_play( if (!ps.ctrack_replay || ReasmIsEmpty(&ps.ctrack_replay->reasm_client)) { t_protocol_probe testers[] = { - {L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial}, + {L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial,false}, {L7P_HTTP_REQ,L7_HTTP,IsHttp,false}, {L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false}, - {L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false} + {L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false}, + {L7P_BT_HANDSHAKE,L7_BT,IsBTHandshake,false} }; protocol_probe(testers, sizeof(testers) / sizeof(*testers), rdata_payload, rlen_payload, ps.ctrack_replay, &ps.l7proto, &ps.l7payload); @@ -1545,7 +1547,7 @@ static uint8_t dpi_desync_tcp_packet_play( if (ps.tpos && (ps.tpos->client.seq_last - ps.tpos->client.seq0)==1) { t_protocol_probe testers[] = { - {L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto} + {L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto,false} }; protocol_probe(testers, sizeof(testers) / sizeof(*testers), rdata_payload, rlen_payload, ps.ctrack_replay, &ps.l7proto, &ps.l7payload); } @@ -1628,6 +1630,7 @@ static void udp_standard_protocol_probe(const uint8_t *data_payload, size_t len_ {L7P_DHT,L7_DHT,IsDht,false}, {L7P_DTLS_CLIENT_HELLO,L7_DTLS,IsDTLSClientHello,false}, {L7P_DTLS_SERVER_HELLO,L7_DTLS,IsDTLSServerHello,false}, + {L7P_UTP_BT_HANDSHAKE,L7_UTP_BT,IsUTP_BTHandshake,false}, {L7P_WIREGUARD_INITIATION,L7_WIREGUARD,IsWireguardHandshakeInitiation,false}, {L7P_WIREGUARD_RESPONSE,L7_WIREGUARD,IsWireguardHandshakeResponse,false}, {L7P_WIREGUARD_COOKIE,L7_WIREGUARD,IsWireguardHandshakeCookie,false}, diff --git a/nfq2/protocol.c b/nfq2/protocol.c index 046fe71..9485fe7 100644 --- a/nfq2/protocol.c +++ b/nfq2/protocol.c @@ -30,7 +30,7 @@ static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t ** } static const char *l7proto_name[] = { -"all","unknown","known","http","tls","dtls","quic","wireguard","dht","discord","stun","xmpp","dns","mtproto" +"all","unknown","known","http","tls","dtls","quic","wireguard","dht","discord","stun","xmpp","dns","mtproto","bt","utp_bt" }; const char *l7proto_str(t_l7proto l7) { @@ -58,7 +58,9 @@ static const char *l7payload_name[] = { "dht","discord_ip_discovery","stun", "xmpp_stream", "xmpp_starttls", "xmpp_proceed", "xmpp_features", "dns_query", "dns_response", - "mtproto_initial"}; + "mtproto_initial", + "bt_handshake", "utp_bt_handshake" +}; t_l7payload l7payload_from_name(const char *name) { int idx = str_index(l7payload_name,sizeof(l7payload_name)/sizeof(*l7payload_name),name); @@ -1485,3 +1487,14 @@ bool IsDTLSServerHello(const uint8_t *data, size_t len) { return IsDTLS(data,len) && data[0]==0x16 && data[13]==2; } + +bool IsBTHandshake(const uint8_t *data, size_t len) +{ + // len, pstrlen, reserved, sha1, peer id + return len>=(1+19+8+20+20) && !memcmp(data,"\x13" "BitTorrent protocol",20); +} +bool IsUTP_BTHandshake(const uint8_t *data, size_t len) +{ + // len, pstrlen, reserved, sha1, peer id + return len>=(20+1+19+8+20+20) && data[0]==0x01 && !memcmp(data+20,"\x13" "BitTorrent protocol",20);; +} diff --git a/nfq2/protocol.h b/nfq2/protocol.h index 74510e7..94b0438 100644 --- a/nfq2/protocol.h +++ b/nfq2/protocol.h @@ -20,6 +20,8 @@ typedef enum { L7_XMPP, L7_DNS, L7_MTPROTO, + L7_BT, + L7_UTP_BT, L7_LAST, L7_INVALID=L7_LAST, L7_NONE=L7_LAST } t_l7proto; const char *l7proto_str(t_l7proto l7); @@ -56,6 +58,8 @@ typedef enum { L7P_DNS_QUERY, L7P_DNS_RESPONSE, L7P_MTPROTO_INITIAL, + L7P_BT_HANDSHAKE, + L7P_UTP_BT_HANDSHAKE, L7P_LAST, L7P_INVALID=L7P_LAST, L7P_NONE=L7P_LAST } t_l7payload; t_l7payload l7payload_from_name(const char *name); @@ -160,7 +164,8 @@ bool IsMTProto(const uint8_t *data, size_t len); bool IsDTLS(const uint8_t *data, size_t len); bool IsDTLSClientHello(const uint8_t *data, size_t len); bool IsDTLSServerHello(const uint8_t *data, size_t len); - +bool IsBTHandshake(const uint8_t *data, size_t len); +bool IsUTP_BTHandshake(const uint8_t *data, size_t len); #define QUIC_MAX_CID_LENGTH 20 typedef struct quic_cid {