summaryrefslogtreecommitdiff
path: root/test/monitor/gtest_seek_layer.cpp
blob: ca4f38a0727c1cecb7ec014bb5c95618b0082406 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <unistd.h>
#include <stddef.h>
#include <getopt.h>
#include <pcap/pcap.h>
#include <gtest/gtest.h>
#include "stellar/packet.h"
#include "monitor/monitor_private.h"
#include "stellar/packet.h"
#include "packet_manager/packet_parser.h"
#include "packet_manager/packet_internal.h"

/* mock */
int packet_manager_subscribe(UNUSED struct packet_manager *pkt_mgr, UNUSED enum packet_stage stage, UNUSED on_packet_stage_callback *cb, UNUSED void *args)
{
    assert(0);
    return 0;
}

static int check_layer(const struct packet *pkt, const enum layer_proto *layers, int expect_layer_cnt)
{
    int actual_pkt_layer = packet_get_layer_count(pkt);
    if (actual_pkt_layer != expect_layer_cnt)
    {
        return -1;
    }
    for (int i = 0; i < expect_layer_cnt; i++)
    {
        const struct layer *layer = packet_get_layer_by_idx(pkt, i);
        if (layer == NULL)
        {
            return -1;
        }
        if (layer->proto != layers[i])
        {
            return -1;
        }
    }
    return 0;
}

TEST(MONITOR_SEEK_LAYER, ethernet_ipv4_udp_dns)
{
    struct packet pkt = {};
    /* a DNS query packet */
    const unsigned char packet_bytes[] =
        {
            0xe8, 0x1c, 0xba, 0xcc, 0x87, 0x21, 0x7c, 0x2a,
            0x31, 0x9f, 0x98, 0x2c, 0x08, 0x00, 0x45, 0x00,
            0x00, 0x3e, 0x4a, 0x41, 0x00, 0x00, 0x80, 0x11,
            0x26, 0x7a, 0xc0, 0xa8, 0x24, 0x67, 0x72, 0x72,
            0x72, 0x72, 0xd5, 0xbc, 0x00, 0x35, 0x00, 0x2a,
            0xd7, 0x33, 0xdf, 0x96, 0x01, 0x00, 0x00, 0x01,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x66,
            0x75, 0x77, 0x75, 0x04, 0x62, 0x64, 0x70, 0x66,
            0x03, 0x6f, 0x72, 0x67, 0x02, 0x63, 0x6e, 0x00,
            0x00, 0x01, 0x00, 0x01};

    ASSERT_TRUE(packet_parse(&pkt, (char *)packet_bytes, sizeof(packet_bytes)) != NULL);
    int pkt_layer = packet_get_layer_count(&pkt);
    ASSERT_EQ(pkt_layer, 3);
    enum layer_proto layers[3] = {LAYER_PROTO_ETHER, LAYER_PROTO_IPV4, LAYER_PROTO_UDP};
    ASSERT_EQ(0, check_layer(&pkt, layers, 3));
}

TEST(MONITOR_SEEK_LAYER, ethernet_ipv4_gre_ipv4_gre_ipv4_udp_dns)
{
    struct packet pkt = {};
    /* a DNS query packet */
    const unsigned char packet_bytes[] = {
        0x02, 0x00, 0x00, 0x01, 0x02, 0x95, 0x00, 0x00,
        0xc3, 0x51, 0x05, 0x0f, 0x08, 0x00, 0x45, 0x00,
        0x00, 0x7c, 0x46, 0xdb, 0x00, 0x00, 0xfb, 0x2f,
        0xcc, 0x35, 0x73, 0x99, 0x4b, 0xf6, 0x7a, 0x70,
        0x72, 0x42, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00,
        0x03, 0x84, 0x45, 0x00, 0x00, 0x60, 0xc8, 0xd5,
        0x00, 0x00, 0xff, 0x2f, 0xe9, 0x58, 0x0a, 0x96,
        0xfa, 0x0a, 0x0a, 0x96, 0xfa, 0x09, 0x00, 0x00,
        0x08, 0x00, 0x45, 0x00, 0x00, 0x48, 0xb2, 0xc6,
        0x00, 0x00, 0x3f, 0x11, 0x6a, 0x4b, 0x7a, 0x70,
        0x72, 0x49, 0x73, 0xee, 0xfd, 0xeb, 0x51, 0x13,
        0x00, 0x35, 0x00, 0x34, 0x3a, 0xbf, 0xb1, 0xba,
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x08, 0x75, 0x72, 0x77, 0x70, 0x75,
        0x6c, 0x65, 0x70, 0x03, 0x77, 0x77, 0x77, 0x09,
        0x64, 0x65, 0x73, 0x68, 0x65, 0x6e, 0x67, 0x32,
        0x38, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
        0x00, 0x01};

    ASSERT_TRUE(packet_parse(&pkt, (char *)packet_bytes, sizeof(packet_bytes)) != NULL);
    int pkt_layer = packet_get_layer_count(&pkt);
    ASSERT_EQ(pkt_layer, 7);
    enum layer_proto layers[7] = {LAYER_PROTO_ETHER, LAYER_PROTO_IPV4, LAYER_PROTO_GRE, LAYER_PROTO_IPV4, LAYER_PROTO_GRE, LAYER_PROTO_IPV4, LAYER_PROTO_UDP};
    ASSERT_EQ(0, check_layer(&pkt, layers, 7));
}

extern "C" u_int stm_bpf_filter_greedy(const struct bpf_insn *bpf_dlt_raw, struct packet *pkt);
TEST(MONITOR_SEEK_LAYER, ethernet_ipv4_gre_ipv4_gre_ipv4_udp_dns_bpf_filter_greedy)
{
    struct packet pkt = {};
    /* a DNS query packet */
    const unsigned char packet_bytes[] = {
        0x02, 0x00, 0x00, 0x01, 0x02, 0x95, 0x00, 0x00,
        0xc3, 0x51, 0x05, 0x0f, 0x08, 0x00, 0x45, 0x00,
        0x00, 0x7c, 0x46, 0xdb, 0x00, 0x00, 0xfb, 0x2f,
        0xcc, 0x35, 0x73, 0x99, 0x4b, 0xf6, 0x7a, 0x70,
        0x72, 0x42, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00,
        0x03, 0x84, 0x45, 0x00, 0x00, 0x60, 0xc8, 0xd5,
        0x00, 0x00, 0xff, 0x2f, 0xe9, 0x58, 0x0a, 0x96,
        0xfa, 0x0a, 0x0a, 0x96, 0xfa, 0x09, 0x00, 0x00,
        0x08, 0x00, 0x45, 0x00, 0x00, 0x48, 0xb2, 0xc6,
        0x00, 0x00, 0x3f, 0x11, 0x6a, 0x4b, 0x7a, 0x70,
        0x72, 0x49, 0x73, 0xee, 0xfd, 0xeb, 0x51, 0x13,
        0x00, 0x35, 0x00, 0x34, 0x3a, 0xbf, 0xb1, 0xba,
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x08, 0x75, 0x72, 0x77, 0x70, 0x75,
        0x6c, 0x65, 0x70, 0x03, 0x77, 0x77, 0x77, 0x09,
        0x64, 0x65, 0x73, 0x68, 0x65, 0x6e, 0x67, 0x32,
        0x38, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
        0x00, 0x01};

    ASSERT_TRUE(packet_parse(&pkt, (char *)packet_bytes, sizeof(packet_bytes)) != NULL);

    struct bpf_program bpf_bin;
    pcap_compile_nopcap(65535, DLT_RAW, &bpf_bin, "host 115.153.75.246 and host 122.112.114.66", 1, 0); // firset ipv4 layer
    ASSERT_TRUE(0 != stm_bpf_filter_greedy(bpf_bin.bf_insns, &pkt));
    pcap_freecode(&bpf_bin);

    pcap_compile_nopcap(65535, DLT_RAW, &bpf_bin, "host 10.150.250.10 and host 10.150.250.9", 1, 0); // second ipv4 layer
    ASSERT_TRUE(0 != stm_bpf_filter_greedy(bpf_bin.bf_insns, &pkt));
    pcap_freecode(&bpf_bin);

    pcap_compile_nopcap(65535, DLT_RAW, &bpf_bin, "host 122.112.114.73 and host 115.238.253.235", 1, 0); // third ipv4 layer
    ASSERT_TRUE(0 != stm_bpf_filter_greedy(bpf_bin.bf_insns, &pkt));
    pcap_freecode(&bpf_bin);
}

int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    int ret = RUN_ALL_TESTS();
    return ret;
}