Coverage Report

Created: 2025-10-28 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}