Coverage Report

Created: 2025-10-28 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/protocols/mining.c
Line
Count
Source
1
/*
2
 * mining.c
3
 *
4
 * Copyright (C) 2018-22 - ntop.org
5
 *
6
 * This file is part of nDPI, an open source deep packet inspection
7
 * library based on the OpenDPI and PACE technology by ipoque GmbH
8
 *
9
 * nDPI is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * nDPI is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
#include "ndpi_protocol_ids.h"
24
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_MINING
25
#include "ndpi_api.h"
26
#include "ndpi_private.h"
27
28
29
/* ************************************************************************** */
30
31
0
u_int64_t mining_make_lru_cache_key(struct ndpi_flow_struct *flow) {
32
0
  u_int64_t key;
33
34
  /* network byte order */
35
0
  if(flow->is_ipv6)
36
0
    key = (ndpi_quick_hash64((const char *)flow->c_address.v6, 16) << 32) | (ndpi_quick_hash64((const char *)flow->s_address.v6, 16) & 0xFFFFFFFF);
37
0
  else
38
0
    key = ((u_int64_t)flow->c_address.v4 << 32) | flow->s_address.v4;
39
40
0
  return key;
41
0
}
42
43
/* ************************************************************************** */
44
45
static void cacheMiningHostTwins(struct ndpi_detection_module_struct *ndpi_struct,
46
0
         struct ndpi_flow_struct *flow) {
47
0
  if(ndpi_struct->mining_cache)
48
0
    ndpi_lru_add_to_cache(ndpi_struct->mining_cache, mining_make_lru_cache_key(flow), NDPI_PROTOCOL_MINING, ndpi_get_current_time(flow));
49
0
}
50
51
/* ************************************************************************** */
52
53
static void ndpi_search_mining(struct ndpi_detection_module_struct *ndpi_struct,
54
0
           struct ndpi_flow_struct *flow) {
55
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
56
57
0
  NDPI_LOG_DBG(ndpi_struct, "search MINING\n");
58
59
  /* Quick test: we are looking for only Json format */
60
0
  if(packet->payload[0] != '{') {
61
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
62
0
    return;
63
0
  }
64
65
  /* STRATUMv1 */
66
0
  if(ndpi_strnstr((const char *)packet->payload, "\"mining.subscribe\"", packet->payload_packet_len) ||
67
0
     ndpi_strnstr((const char *)packet->payload, "\"mining.configure\"", packet->payload_packet_len)) {
68
69
    /* Try matching some zcash domains like "eu1-zcash.flypool.org" */
70
0
    if(ndpi_strnstr((const char *)packet->payload, "zcash", packet->payload_packet_len))
71
0
      ndpi_snprintf(flow->protos.mining.currency, sizeof(flow->protos.mining.currency), "%s", "ZCash");
72
0
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
73
0
    cacheMiningHostTwins(ndpi_struct, flow);
74
0
    return;
75
0
  }
76
77
  /* Xmr-stak-cpu is a ZCash/Monero CPU miner */
78
0
  if(ndpi_strnstr((const char *)packet->payload, "\"agent\":\"xmr-stak-cpu", packet->payload_packet_len)) {
79
0
    ndpi_snprintf(flow->protos.mining.currency, sizeof(flow->protos.mining.currency), "%s", "ZCash/Monero");
80
0
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
81
0
    cacheMiningHostTwins(ndpi_struct, flow);
82
0
    return;
83
0
  }
84
  
85
0
  if(ndpi_strnstr((const char *)packet->payload, "\"method\": \"eth_submitLogin", packet->payload_packet_len)) {
86
0
    ndpi_snprintf(flow->protos.mining.currency, sizeof(flow->protos.mining.currency), "%s", "Ethereum");
87
0
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_MINING, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
88
0
    cacheMiningHostTwins(ndpi_struct, flow);
89
0
    return;
90
0
  }
91
92
0
  NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
93
0
}
94
95
/* ************************************************************************** */
96
97
void init_mining_dissector(struct ndpi_detection_module_struct *ndpi_struct)
98
1
{
99
1
  register_dissector("Mining", ndpi_struct,
100
1
                     ndpi_search_mining,
101
1
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
102
1
                      1, NDPI_PROTOCOL_MINING);
103
1
}
104