1 /*
2 * capwap.c
3 *
4 * Copyright (C) 2019 - ntop.org
5 *
6 * nDPI is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * nDPI is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21
22 #include "ndpi_protocol_ids.h"
23
24 #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_CAPWAP
25
26 #include "ndpi_api.h"
27
28 #define NDPI_CAPWAP_CONTROL_PORT 5246
29 #define NDPI_CAPWAP_DATA_PORT 5247
30
31
ndpi_int_capwap_add_connection(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)32 static void ndpi_int_capwap_add_connection(struct ndpi_detection_module_struct *ndpi_struct,
33 struct ndpi_flow_struct *flow) {
34 ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CAPWAP, NDPI_PROTOCOL_UNKNOWN);
35 }
36
37 /* ************************************************** */
38
ndpi_search_setup_capwap(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)39 static void ndpi_search_setup_capwap(struct ndpi_detection_module_struct *ndpi_struct,
40 struct ndpi_flow_struct *flow) {
41 struct ndpi_packet_struct *packet = &flow->packet;
42 u_int16_t sport, dport;
43
44 if(!packet->iph) {
45 NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
46 return;
47 }
48
49 sport = ntohs(packet->udp->source), dport = ntohs(packet->udp->dest);
50
51 if((dport == NDPI_CAPWAP_CONTROL_PORT)
52 && (packet->iph->daddr == 0xFFFFFFFF)
53 && (packet->payload_packet_len >= 16)
54 && (packet->payload[0] == 0x0)
55 && (packet->payload[8] == 6 /* Mac len */)
56 )
57 goto capwap_found;
58
59 if(((sport == NDPI_CAPWAP_CONTROL_PORT) || (dport == NDPI_CAPWAP_CONTROL_PORT))
60 && ((packet->payload[0] == 0x0) || (packet->payload[0] == 0x1))
61 ) {
62 u_int16_t msg_len, offset, to_add;
63
64 if(packet->payload[0] == 0x0)
65 offset = 13, to_add = 13;
66 else
67 offset = 15, to_add = 17;
68
69 if (packet->payload_packet_len >= offset + sizeof(u_int16_t)) {
70 msg_len = ntohs(*(u_int16_t*)&packet->payload[offset]);
71
72 if((msg_len+to_add) == packet->payload_packet_len)
73 goto capwap_found;
74 }
75 }
76
77 if(
78 (((dport == NDPI_CAPWAP_DATA_PORT) && (packet->iph->daddr != 0xFFFFFFFF)) || (sport == NDPI_CAPWAP_DATA_PORT))
79 && (packet->payload_packet_len >= 16)
80 && (packet->payload[0] == 0x0)
81 ) {
82 u_int8_t is_80211_data = (packet->payload[9] & 0x0C) >> 2;
83
84
85 if((sport == NDPI_CAPWAP_DATA_PORT) && (is_80211_data == 2 /* IEEE 802.11 Data */))
86 goto capwap_found;
87 else if(dport == NDPI_CAPWAP_DATA_PORT) {
88 u_int16_t msg_len = ntohs(*(u_int16_t*)&packet->payload[13]);
89
90 if((packet->payload[8] == 1 /* Mac len */)
91 || (packet->payload[8] == 6 /* Mac len */)
92 || (packet->payload[8] == 4 /* Wireless len */)
93 || ((msg_len+15) == packet->payload_packet_len))
94 goto capwap_found;
95 }
96 }
97
98 NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
99 return;
100
101 capwap_found:
102 ndpi_int_capwap_add_connection(ndpi_struct, flow);
103 }
104
ndpi_search_capwap(struct ndpi_detection_module_struct * ndpi_struct,struct ndpi_flow_struct * flow)105 void ndpi_search_capwap(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
106 {
107 struct ndpi_packet_struct *packet = &flow->packet;
108
109 if(packet->udp && (packet->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN))
110 ndpi_search_setup_capwap(ndpi_struct, flow);
111 }
112
113
init_capwap_dissector(struct ndpi_detection_module_struct * ndpi_struct,u_int32_t * id,NDPI_PROTOCOL_BITMASK * detection_bitmask)114 void init_capwap_dissector(struct ndpi_detection_module_struct *ndpi_struct,
115 u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
116 {
117 ndpi_set_bitmask_protocol_detection("CAPWAP", ndpi_struct, detection_bitmask, *id,
118 NDPI_PROTOCOL_CAPWAP,
119 ndpi_search_capwap,
120 NDPI_SELECTION_BITMASK_PROTOCOL_UDP_WITH_PAYLOAD,
121 SAVE_DETECTION_BITMASK_AS_UNKNOWN,
122 ADD_TO_DETECTION_BITMASK);
123
124 *id += 1;
125 }
126