/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 | | |