Coverage Report

Created: 2025-08-28 06:46

/src/ndpi/src/lib/protocols/socks45.c
Line
Count
Source
1
/*
2
 * socks4.c
3
 *
4
 * Copyright (C) 2016-22 - ntop.org
5
 * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk>
6
 *
7
 * The signature is based on the Libprotoident library.
8
 *
9
 * This file is part of nDPI, an open source deep packet inspection
10
 * library based on the OpenDPI and PACE technology by ipoque GmbH
11
 *
12
 * nDPI is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Lesser General Public License as published by
14
 * the Free Software Foundation, either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * nDPI is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Lesser General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Lesser General Public License
23
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
#include "ndpi_protocol_ids.h"
27
28
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_SOCKS
29
30
#include "ndpi_api.h"
31
#include "ndpi_private.h"
32
33
static void ndpi_int_socks_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
34
117
{
35
117
  ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
36
117
}
37
38
static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
39
3.47M
{
40
3.47M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
41
3.47M
  u_int32_t payload_len = packet->payload_packet_len;
42
43
  /* Check if we so far detected the protocol in the request or not. */
44
3.47M
  if(flow->l4.tcp.socks4_stage == 0) {
45
3.47M
    NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage 0: \n");
46
    
47
3.47M
    if(payload_len >= 9 && packet->payload[0] == 0x04 && 
48
3.47M
      (packet->payload[1] == 0x01 || packet->payload[1] == 0x02) &&
49
3.47M
      packet->payload[payload_len - 1] == 0x00)  {
50
1.45k
      NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS4 request detected, we will look further for the response\n");
51
      /* TODO: check port and ip address is valid */
52
      /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
53
1.45k
      flow->l4.tcp.socks4_stage = packet->packet_direction + 1;
54
1.45k
    }
55
3.47M
  } else {
56
1.72k
    NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage %u: \n", flow->l4.tcp.socks4_stage);
57
58
    /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
59
1.72k
    if((flow->l4.tcp.socks4_stage - packet->packet_direction) == 1) {
60
1.44k
      return;
61
1.44k
    }
62
    /* This is a packet in another direction. Check if we find the proper response. */
63
283
    if(payload_len == 8 && packet->payload[0] == 0x00 && packet->payload[1] >= 0x5a && packet->payload[1] <= 0x5d) {
64
47
      NDPI_LOG_INFO(ndpi_struct, "found SOCKS4\n");
65
47
      ndpi_int_socks_add_connection(ndpi_struct, flow);
66
236
    } else {
67
236
      NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS4, resetting the stage to 0\n");
68
236
      flow->l4.tcp.socks4_stage = 0;
69
236
    }
70
283
  }
71
3.47M
}
72
73
static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
74
3.47M
{
75
3.47M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
76
3.47M
  u_int32_t payload_len = packet->payload_packet_len;
77
78
  /* Check if we so far detected the protocol in the request or not. */
79
3.47M
  if(flow->l4.tcp.socks5_stage == 0) {
80
3.47M
    NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage 0: \n");
81
82
3.47M
    if(((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) ||
83
3.47M
       ((payload_len == 4) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x02) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x01))) {
84
799
      NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS5 request detected, we will look further for the response\n");
85
86
      /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */
87
799
      flow->l4.tcp.socks5_stage = packet->packet_direction + 1;
88
799
    }
89
90
3.47M
  } else {
91
1.01k
    NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage %u: \n", flow->l4.tcp.socks5_stage);
92
93
    /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */
94
1.01k
    if((flow->l4.tcp.socks5_stage - packet->packet_direction) == 1) {
95
729
      return;
96
729
    }
97
98
    /* This is a packet in another direction. Check if we find the proper response. */
99
288
    if((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) {
100
70
      NDPI_LOG_INFO(ndpi_struct, "found SOCKS5\n");
101
70
      ndpi_int_socks_add_connection(ndpi_struct, flow);
102
218
    } else {
103
218
      NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS5, resetting the stage to 0\n");
104
218
      flow->l4.tcp.socks5_stage = 0;
105
218
    }
106
107
288
  }
108
3.47M
}
109
110
static void ndpi_search_socks(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
111
3.49M
{
112
3.49M
  NDPI_LOG_DBG(ndpi_struct, "search SOCKS\n");
113
114
3.49M
  if(flow->packet_counter >= 10) {
115
24.9k
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
116
24.9k
    return;
117
24.9k
  }
118
119
3.47M
  ndpi_check_socks4(ndpi_struct, flow);
120
121
3.47M
  if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS)
122
3.47M
    ndpi_check_socks5(ndpi_struct, flow);
123
3.47M
}
124
125
void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct)
126
15.4k
{
127
15.4k
  register_dissector("SOCKS", ndpi_struct,
128
15.4k
                     ndpi_search_socks,
129
15.4k
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
130
15.4k
                     1, NDPI_PROTOCOL_SOCKS);
131
15.4k
}
132