/src/ndpi/src/lib/protocols/mikrotik.c
Line | Count | Source |
1 | | /* |
2 | | * mikrotik.c |
3 | | * |
4 | | * Copyright (C) 2012-24 - 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 | | #include "ndpi_protocol_ids.h" |
21 | | |
22 | | #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MIKROTIK |
23 | | |
24 | | #include "ndpi_api.h" |
25 | | #include "ndpi_private.h" |
26 | | |
27 | | /* ********************************* */ |
28 | | |
29 | | static void ndpi_search_mikrotik(struct ndpi_detection_module_struct *ndpi_struct, |
30 | 511 | struct ndpi_flow_struct *flow) { |
31 | 511 | struct ndpi_packet_struct *packet = &ndpi_struct->packet; |
32 | | |
33 | 511 | NDPI_LOG_DBG(ndpi_struct, "search MIKROTIK\n"); |
34 | | |
35 | 511 | if((packet->iph && (packet->iph->daddr== 0xFFFFFFFF)) |
36 | 500 | || (packet->iphv6 && (ntohl(packet->iphv6->ip6_dst.u6_addr.u6_addr32[0]) == 0xFF020000 /* ff02:: */)) |
37 | 511 | ) { |
38 | 11 | if(ntohs(packet->udp->dest) == 5678) { |
39 | 0 | const u_int8_t *payload; |
40 | 0 | u_int16_t offset; |
41 | | |
42 | 0 | if (packet->payload_packet_len < 8) { |
43 | 0 | NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); |
44 | 0 | return; |
45 | 0 | } else { |
46 | 0 | offset = 4; |
47 | 0 | payload = packet->payload; |
48 | 0 | } |
49 | | |
50 | 0 | while((offset+4) < packet->payload_packet_len) { |
51 | 0 | u_int16_t m_type = ((u_int16_t)payload[offset] << 8) + payload[offset+1]; |
52 | 0 | u_int16_t m_len = ((u_int16_t)payload[offset+2] << 8) + payload[offset+3]; |
53 | | |
54 | | // printf("%d\n", m_type); |
55 | |
|
56 | 0 | if((4+m_len+offset) < packet->payload_packet_len) { |
57 | 0 | switch(m_type) { |
58 | 0 | case 1 /* MAC Address */: |
59 | 0 | if(m_len == 6) |
60 | 0 | memcpy(flow->protos.mikrotik.mac_addr, &payload[offset+4], m_len); |
61 | 0 | break; |
62 | 0 | case 5 /* Identity */: |
63 | 0 | snprintf(flow->protos.mikrotik.identity, sizeof(flow->protos.mikrotik.identity), |
64 | 0 | "%.*s", m_len, &payload[offset+4]); |
65 | 0 | break; |
66 | 0 | case 7 /* Version */: |
67 | 0 | snprintf(flow->protos.mikrotik.version, sizeof(flow->protos.mikrotik.version), |
68 | 0 | "%.*s", m_len, &payload[offset+4]); |
69 | 0 | break; |
70 | 0 | case 10: /* Uptime */ |
71 | 0 | if(m_len == 4) |
72 | 0 | flow->protos.mikrotik.uptime = ntohl(*((u_int32_t*)&payload[offset+4])); |
73 | 0 | break; |
74 | 0 | case 11: /* Software-ID */ |
75 | 0 | snprintf(flow->protos.mikrotik.sw_id, sizeof(flow->protos.mikrotik.sw_id), |
76 | 0 | "%.*s", m_len, &payload[offset+4]); |
77 | 0 | break; |
78 | 0 | case 12: /* Board */ |
79 | 0 | snprintf(flow->protos.mikrotik.board, sizeof(flow->protos.mikrotik.board), |
80 | 0 | "%.*s", m_len, &payload[offset+4]); |
81 | 0 | break; |
82 | 0 | case 15: /* IPv6 */ |
83 | 0 | if(m_len == 16) |
84 | 0 | memcpy(&flow->protos.mikrotik.ipv6_addr, &payload[offset+4], m_len); |
85 | 0 | break; |
86 | 0 | case 16: /* Interface Name */ |
87 | 0 | snprintf(flow->protos.mikrotik.iface_name, sizeof(flow->protos.mikrotik.iface_name), |
88 | 0 | "%.*s", m_len, &payload[offset+4]); |
89 | 0 | break; |
90 | 0 | case 14: /* IPv4 */ |
91 | 0 | if(m_len == 4) |
92 | 0 | flow->protos.mikrotik.ipv4_addr = ntohl(*((u_int32_t*)&payload[offset+4])); |
93 | 0 | break; |
94 | 0 | } |
95 | | |
96 | 0 | offset += 4 + m_len; |
97 | 0 | } else |
98 | 0 | break; |
99 | 0 | } /* while */ |
100 | | |
101 | 0 | ndpi_set_detected_protocol(ndpi_struct, flow, |
102 | 0 | NDPI_PROTOCOL_MIKROTIK, |
103 | 0 | NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); |
104 | 0 | } |
105 | 11 | } else |
106 | 500 | NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); |
107 | 511 | } |
108 | | |
109 | | /* ********************************* */ |
110 | | |
111 | 4.29k | void init_mikrotik_dissector(struct ndpi_detection_module_struct *ndpi_struct) { |
112 | 4.29k | register_dissector("MIKROTIK", ndpi_struct, |
113 | 4.29k | ndpi_search_mikrotik, |
114 | 4.29k | NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, |
115 | 4.29k | 1, NDPI_PROTOCOL_MIKROTIK); |
116 | 4.29k | } |