aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/stun.c
diff options
context:
space:
mode:
authorNardi Ivan <nardi.ivan@gmail.com>2023-06-18 11:55:01 +0200
committerIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2023-06-21 10:38:44 +0200
commit570c75d6019872610b0cbde981e25edcda5f6754 (patch)
treeddcd9e0ce2b3d5fa063d1d22e5681f259f15bd7b /src/lib/protocols/stun.c
parent2ac240ce6aafdae26b9b1117127595506074cda1 (diff)
STUN: fix detection over TCP
TCP framing is optional
Diffstat (limited to 'src/lib/protocols/stun.c')
-rw-r--r--src/lib/protocols/stun.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/lib/protocols/stun.c b/src/lib/protocols/stun.c
index 4b822f6c5..e8cdaa699 100644
--- a/src/lib/protocols/stun.c
+++ b/src/lib/protocols/stun.c
@@ -208,7 +208,7 @@ typedef enum {
static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
const u_int8_t * payload,
- const u_int16_t payload_length,
+ u_int16_t payload_length,
u_int16_t *app_proto) {
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
u_int16_t msg_type, msg_len;
@@ -239,6 +239,18 @@ static ndpi_int_stun_t ndpi_int_check_stun(struct ndpi_detection_module_struct *
msg_type = ntohs(*((u_int16_t*)payload));
msg_len = ntohs(*((u_int16_t*)&payload[2]));
+ /* With tcp, we might have multiple msg in the same TCP pkt.
+ Parse only the first one. TODO */
+ if(packet->tcp) {
+ if(msg_len + 20 > payload_length)
+ return(NDPI_IS_NOT_STUN);
+ /* Let's hope that classic-stun is no more used over TCP */
+ if(ntohl(*((u_int32_t *)&payload[4])) != 0x2112A442)
+ return(NDPI_IS_NOT_STUN);
+
+ payload_length = msg_len + 20;
+ }
+
if((msg_type == 0) || ((msg_len+20) != payload_length))
return(NDPI_IS_NOT_STUN);
@@ -508,26 +520,24 @@ static void ndpi_search_stun(struct ndpi_detection_module_struct *ndpi_struct, s
app_proto = NDPI_PROTOCOL_UNKNOWN;
- if(packet->tcp) {
- /* STUN may be encapsulated in TCP packets */
- if((packet->payload_packet_len >= 22)
- && ((ntohs(get_u_int16_t(packet->payload, 0)) + 2) == packet->payload_packet_len)) {
- /* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be
- * improved by checking only the STUN packet of given length */
-
- if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2,
- packet->payload_packet_len - 2, &app_proto) == NDPI_IS_STUN) {
- ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
- return;
- }
+ /* STUN may be encapsulated in TCP packets with a special TCP framing described in RFC 4571 */
+ if(packet->tcp &&
+ packet->payload_packet_len >= 22 &&
+ ((ntohs(get_u_int16_t(packet->payload, 0)) + 2) == packet->payload_packet_len)) {
+ /* TODO there could be several STUN packets in a single TCP packet so maybe the detection could be
+ * improved by checking only the STUN packet of given length */
+
+ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload + 2,
+ packet->payload_packet_len - 2, &app_proto) == NDPI_IS_STUN) {
+ ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
+ return;
+ }
+ } else { /* UDP or TCP without framing */
+ if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload,
+ packet->payload_packet_len, &app_proto) == NDPI_IS_STUN) {
+ ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
+ return;
}
- }
-
- /* UDP */
- if(ndpi_int_check_stun(ndpi_struct, flow, packet->payload,
- packet->payload_packet_len, &app_proto) == NDPI_IS_STUN) {
- ndpi_int_stun_add_connection(ndpi_struct, flow, app_proto);
- return;
}
if(flow->stun.num_pkts >= MAX_NUM_STUN_PKTS ||