/src/ndpi/src/lib/protocols/tinc.c
Line | Count | Source |
1 | | /* |
2 | | * tinc.c |
3 | | * |
4 | | * Copyright (C) 2017 - William Guglielmo <william@deselmo.com> |
5 | | * Copyright (C) 2017-22 - ntop.org |
6 | | * |
7 | | * nDPI is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as published by |
9 | | * the Free Software Foundation, either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * nDPI is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with nDPI. If not, see <http://www.gnu.org/licenses/>. |
19 | | * |
20 | | */ |
21 | | #include "ndpi_protocol_ids.h" |
22 | | |
23 | | #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_TINC |
24 | | |
25 | | #include "ndpi_api.h" |
26 | | #include "ndpi_private.h" |
27 | | #include "libcache.h" |
28 | | |
29 | | PACK_ON struct tinc_cache_entry { |
30 | | u_int32_t src_address; |
31 | | u_int32_t dst_address; |
32 | | u_int16_t dst_port; |
33 | | } PACK_OFF; |
34 | | |
35 | | static void ndpi_check_tinc(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) |
36 | 4.26M | { |
37 | 4.26M | struct ndpi_packet_struct *packet = &ndpi_struct->packet; |
38 | 4.26M | const u_int8_t *packet_payload = packet->payload; |
39 | 4.26M | u_int32_t payload_len = packet->payload_packet_len; |
40 | | |
41 | 4.26M | if(packet->udp != NULL) { |
42 | 934k | if(ndpi_struct->tinc_cache != NULL) { |
43 | 767k | struct tinc_cache_entry tinc_cache_entry1 = { |
44 | 767k | .src_address = packet->iph->saddr, |
45 | 767k | .dst_address = packet->iph->daddr, |
46 | 767k | .dst_port = packet->udp->dest |
47 | 767k | }; |
48 | | |
49 | 767k | struct tinc_cache_entry tinc_cache_entry2 = { |
50 | 767k | .src_address = packet->iph->daddr, |
51 | 767k | .dst_address = packet->iph->saddr, |
52 | 767k | .dst_port = packet->udp->source |
53 | 767k | }; |
54 | | |
55 | 767k | if(cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry1, sizeof(tinc_cache_entry1)) == CACHE_NO_ERROR || |
56 | 767k | cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry2, sizeof(tinc_cache_entry2)) == CACHE_NO_ERROR) { |
57 | | |
58 | 68 | cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry1, sizeof(tinc_cache_entry1)); |
59 | 68 | cache_remove(ndpi_struct->tinc_cache, &tinc_cache_entry2, sizeof(tinc_cache_entry2)); |
60 | | |
61 | | /* cache_free(ndpi_struct->tinc_cache); */ |
62 | | |
63 | 68 | NDPI_LOG_INFO(ndpi_struct, "found tinc udp connection\n"); |
64 | 68 | ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TINC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI_CACHE); |
65 | 68 | } |
66 | 767k | } |
67 | | |
68 | 934k | NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); |
69 | 934k | return; |
70 | 3.33M | } else if(packet->tcp != NULL) { |
71 | | |
72 | 3.33M | switch(flow->tinc_state) { |
73 | 3.32M | case 0: |
74 | 3.33M | case 1: |
75 | 3.33M | if(payload_len > 6 && memcmp(packet_payload, "0 ", 2) == 0 && packet_payload[2] != ' ') { |
76 | 3.27k | u_int32_t i = 3; |
77 | 66.9k | while(i < payload_len && packet_payload[i++] != ' '); |
78 | 3.27k | if(i+3 == payload_len && memcmp((packet_payload+i), "17\n", 3) == 0) { |
79 | 1.98k | flow->tinc_state++; |
80 | 1.98k | return; |
81 | 1.98k | } |
82 | 3.27k | } |
83 | 3.32M | break; |
84 | | |
85 | 3.32M | case 2: |
86 | 938 | case 3: |
87 | 938 | if(payload_len > 11 && memcmp(packet_payload, "1 ", 2) == 0 && packet_payload[2] != ' ') { |
88 | 743 | u_int16_t i = 3; |
89 | 743 | u_int8_t numbers_left = 4; |
90 | 3.34k | while(numbers_left) { |
91 | 17.4k | while(i < payload_len && packet_payload[i] >= '0' && packet_payload[i] <= '9') { |
92 | 14.7k | i++; |
93 | 14.7k | } |
94 | | |
95 | 2.72k | if(i < payload_len && packet_payload[i++] == ' ') { |
96 | 2.60k | numbers_left--; |
97 | 2.60k | } |
98 | 121 | else break; |
99 | 2.72k | } |
100 | | |
101 | 743 | if(numbers_left) break; |
102 | | |
103 | 460k | while(i < payload_len && |
104 | 460k | ((packet_payload[i] >= '0' && packet_payload[i] <= '9') || |
105 | 460k | (packet_payload[i] >= 'A' && packet_payload[i] <= 'Z'))) { |
106 | 460k | i++; |
107 | 460k | } |
108 | | |
109 | 622 | if(i < payload_len && packet_payload[i] == '\n') { |
110 | 407 | if(++flow->tinc_state > 3) { |
111 | 166 | struct tinc_cache_entry tinc_cache_entry = { |
112 | 166 | .src_address = flow->c_address.v4, |
113 | 166 | .dst_address = flow->s_address.v4, |
114 | 166 | .dst_port = flow->s_port, |
115 | 166 | }; |
116 | | |
117 | 166 | if(ndpi_struct->tinc_cache == NULL) |
118 | 12 | ndpi_struct->tinc_cache = cache_new(TINC_CACHE_MAX_SIZE); |
119 | | |
120 | 166 | cache_add(ndpi_struct->tinc_cache, &tinc_cache_entry, sizeof(tinc_cache_entry)); |
121 | 166 | NDPI_LOG_INFO(ndpi_struct, "found tinc tcp connection\n"); |
122 | 166 | ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TINC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); |
123 | 166 | } |
124 | 407 | return; |
125 | 407 | } |
126 | 622 | } |
127 | 410 | break; |
128 | | |
129 | 410 | default: break; |
130 | 3.33M | } |
131 | 3.33M | } |
132 | | |
133 | 3.32M | NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); |
134 | 3.32M | } |
135 | | |
136 | 4.26M | static void ndpi_search_tinc(struct ndpi_detection_module_struct* ndpi_struct, struct ndpi_flow_struct* flow) { |
137 | 4.26M | NDPI_LOG_DBG(ndpi_struct, "tinc detection\n"); |
138 | | |
139 | 4.26M | if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_TINC) { |
140 | 4.26M | ndpi_check_tinc(ndpi_struct, flow); |
141 | 4.26M | } |
142 | 4.26M | } |
143 | | |
144 | | void init_tinc_dissector(struct ndpi_detection_module_struct *ndpi_struct) |
145 | 20.4k | { |
146 | 20.4k | ndpi_register_dissector("TINC", ndpi_struct, |
147 | 20.4k | ndpi_search_tinc, |
148 | 20.4k | NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, /* TODO: IPv6? */ |
149 | 20.4k | 1, NDPI_PROTOCOL_TINC); |
150 | 20.4k | } |
151 | | |