179 lines
6.1 KiB
C++
179 lines
6.1 KiB
C++
|
|
#include <stdlib.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <netinet/ip.h>
|
||
|
|
#include <netinet/ip6.h>
|
||
|
|
#include <netinet/tcp.h>
|
||
|
|
#include <netinet/ether.h>
|
||
|
|
#include <pcap/sll.h>
|
||
|
|
#include <pcap/pcap.h>
|
||
|
|
#include "gtest/gtest.h"
|
||
|
|
|
||
|
|
#include "stellar/stratum_decoder.h"
|
||
|
|
|
||
|
|
#include <stellar/session.h>
|
||
|
|
|
||
|
|
|
||
|
|
#define LINUX_COOKED_CAPTURE 20
|
||
|
|
|
||
|
|
struct pcap_loop_arg
|
||
|
|
{
|
||
|
|
pcap_t *pcap_handle;
|
||
|
|
void *ctx;
|
||
|
|
};
|
||
|
|
|
||
|
|
extern struct stratum_field *stratum_data_process(struct stratum_decoder_info *stratum_decoder_info, const char *tcpdata, size_t datalen);
|
||
|
|
extern void free_stratum_filed(struct stratum_field *stratum_field);
|
||
|
|
extern "C" void *stratum_decoder_init(struct stellar *st);
|
||
|
|
|
||
|
|
struct stratum_decoder_info *stratum_decoder_info = NULL;
|
||
|
|
|
||
|
|
static void pcap_handle_cb(pcap_loop_arg *userarg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
|
||
|
|
{
|
||
|
|
struct pcap_loop_arg *arg = (struct pcap_loop_arg *)userarg;
|
||
|
|
int payload_len = 0;
|
||
|
|
char *payload = NULL;
|
||
|
|
unsigned short eth_proto_type;
|
||
|
|
unsigned char *ip_header;
|
||
|
|
|
||
|
|
int data_link_type = pcap_datalink(arg->pcap_handle);
|
||
|
|
switch (data_link_type) {
|
||
|
|
case DLT_EN10MB:
|
||
|
|
eth_proto_type = ntohs(*(unsigned short *)(packet + 12));
|
||
|
|
ip_header = (unsigned char *)(packet + sizeof(struct ethhdr));
|
||
|
|
break;
|
||
|
|
case 276://DLT_LINUX_SLL2
|
||
|
|
eth_proto_type = ntohs(*(unsigned short *)packet);
|
||
|
|
ip_header = (unsigned char *)(packet + LINUX_COOKED_CAPTURE);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (eth_proto_type == ETH_P_IP) {
|
||
|
|
int l4_proto = *(unsigned char *)(ip_header + 9);
|
||
|
|
if (l4_proto == IPPROTO_TCP) {
|
||
|
|
int ip_total_len = ntohs(*(unsigned short *)(ip_header + 2));
|
||
|
|
int ip_header_len = (*(unsigned char *)ip_header & 0x0f) * 4;
|
||
|
|
int tcp_header_len = 4 * ((*(unsigned char *)(ip_header + sizeof(iphdr) + 12) & 0xf0) >> 4);
|
||
|
|
payload_len = ip_total_len - ip_header_len - tcp_header_len;
|
||
|
|
payload = (char *)ip_header + ip_header_len + tcp_header_len;
|
||
|
|
} else {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
} else if (eth_proto_type == ETH_P_IPV6) {
|
||
|
|
int l4_proto = *(unsigned char *)(ip_header + 6);
|
||
|
|
if (l4_proto == IPPROTO_TCP) {
|
||
|
|
int tcp_header_len = 4 * ((*(unsigned char *)(ip_header + sizeof(struct ip6_hdr) + 12) & 0xf0) >> 4);
|
||
|
|
payload_len = pkthdr->caplen - (ip_header - packet) - sizeof(struct ip6_hdr) - tcp_header_len;
|
||
|
|
payload = (char *)ip_header + sizeof(struct ip6_hdr) + tcp_header_len;
|
||
|
|
} else {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
struct stratum_field *stratum = stratum_data_process(stratum_decoder_info, payload, payload_len);
|
||
|
|
if (stratum != NULL)
|
||
|
|
{
|
||
|
|
arg->ctx = stratum;
|
||
|
|
pcap_breakloop(arg->pcap_handle);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(stratum_decoder, parse01)
|
||
|
|
{
|
||
|
|
char error[100];
|
||
|
|
struct pcap_loop_arg arg;
|
||
|
|
pcap_t *handle = pcap_open_offline("pcap/01-bch_f2pool_cpuminer_1.pcapng", error);
|
||
|
|
ASSERT_NE(handle, nullptr);
|
||
|
|
|
||
|
|
memset(&arg, 0, sizeof(arg));
|
||
|
|
arg.pcap_handle = handle;
|
||
|
|
pcap_loop(handle, -1, (pcap_handler)pcap_handle_cb, (u_char *)&arg);
|
||
|
|
|
||
|
|
struct stratum_field *stratum = (struct stratum_field *)arg.ctx;
|
||
|
|
EXPECT_EQ(stratum->type, OTHER);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_program.iov_base, "cpuminer/2.5.1");
|
||
|
|
EXPECT_EQ(stratum->mining_pools.iov_len, 0);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_subscribe.iov_base, "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": [\"cpuminer/2.5.1\"]}\n");
|
||
|
|
|
||
|
|
pcap_close(handle);
|
||
|
|
free_stratum_filed(stratum);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(stratum_decoder, parse02)
|
||
|
|
{
|
||
|
|
char error[100];
|
||
|
|
struct pcap_loop_arg arg;
|
||
|
|
pcap_t *handle = pcap_open_offline("pcap/02-eth-antpool.pcapng", error);
|
||
|
|
ASSERT_NE(handle, nullptr);
|
||
|
|
|
||
|
|
memset(&arg, 0, sizeof(arg));
|
||
|
|
arg.pcap_handle = handle;
|
||
|
|
pcap_loop(handle, -1, (pcap_handler)pcap_handle_cb, (u_char *)&arg);
|
||
|
|
|
||
|
|
struct stratum_field *stratum = (struct stratum_field *)arg.ctx;
|
||
|
|
EXPECT_EQ(stratum->type, ETH);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_program.iov_base, "lolMinerWorker");
|
||
|
|
EXPECT_EQ(stratum->mining_pools.iov_len, 0);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_subscribe.iov_base, "{\"id\":1,\"jsonrpc\":\"2.0\",\"method\":\"eth_submitLogin\",\"worker\":\"lolMinerWorker\",\"params\":[\"0xa0279Ad2aA6BDb440f041Aa0947178431d9Bd253.lolMinerWorker\", \"x\"]} \n");
|
||
|
|
|
||
|
|
pcap_close(handle);
|
||
|
|
free_stratum_filed(stratum);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(stratum_decoder, parse03)
|
||
|
|
{
|
||
|
|
char error[100];
|
||
|
|
struct pcap_loop_arg arg;
|
||
|
|
pcap_t *handle = pcap_open_offline("pcap/03-xmr_f2pool_nanominer_1.pcapng", error);
|
||
|
|
ASSERT_NE(handle, nullptr);
|
||
|
|
|
||
|
|
memset(&arg, 0, sizeof(arg));
|
||
|
|
arg.pcap_handle = handle;
|
||
|
|
pcap_loop(handle, -1, (pcap_handler)pcap_handle_cb, (u_char *)&arg);
|
||
|
|
|
||
|
|
struct stratum_field *stratum = (struct stratum_field *)arg.ctx;
|
||
|
|
EXPECT_EQ(stratum->type, OTHER);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_program.iov_base, "nanominer/3.3.5-cuda11");
|
||
|
|
EXPECT_EQ(stratum->mining_pools.iov_len, 0);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_subscribe.iov_base, "{\"id\": 1, \"method\": \"login\", \"params\": { \"login\":\"yhzzhk.001.001\",\"pass\" : \"x\", \"agent\" : \"nanominer/3.3.5-cuda11\"}}\n");
|
||
|
|
|
||
|
|
pcap_close(handle);
|
||
|
|
free_stratum_filed(stratum);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST(stratum_decoder, parse04)
|
||
|
|
{
|
||
|
|
char error[100];
|
||
|
|
struct pcap_loop_arg arg;
|
||
|
|
pcap_t *handle = pcap_open_offline("pcap/04-zec-antpool.pcapng", error);
|
||
|
|
ASSERT_NE(handle, nullptr);
|
||
|
|
|
||
|
|
memset(&arg, 0, sizeof(arg));
|
||
|
|
arg.pcap_handle = handle;
|
||
|
|
pcap_loop(handle, -1, (pcap_handler)pcap_handle_cb, (u_char *)&arg);
|
||
|
|
|
||
|
|
struct stratum_field *stratum = (struct stratum_field *)arg.ctx;
|
||
|
|
EXPECT_EQ(stratum->type, OTHER);
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_program.iov_base, "nheqminer/0.5c");
|
||
|
|
EXPECT_STREQ((const char*)stratum->mining_pools.iov_base, "stratum-zec.antpool.com");
|
||
|
|
EXPECT_STREQ((const char *)stratum->mining_subscribe.iov_base, "{\"id\":1,\"method\":\"mining.subscribe\",\"params\":[\"nheqminer/0.5c\", null,\"stratum-zec.antpool.com\",\"8899\"]}\n");
|
||
|
|
|
||
|
|
pcap_close(handle);
|
||
|
|
free_stratum_filed(stratum);
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int argc, char **argv)
|
||
|
|
{
|
||
|
|
testing::InitGoogleTest(&argc, argv);
|
||
|
|
|
||
|
|
stratum_decoder_info = (struct stratum_decoder_info*)stratum_decoder_init(NULL);
|
||
|
|
|
||
|
|
int result = RUN_ALL_TESTS();
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|