summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/unittests/mDNSCoreReceiveTest.c
blob: 856eb4eec1f33dd5b7e377cca0ebb3dd18e943a9 (plain) (blame)
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
#include "mDNSCoreReceiveTest.h"
#include "unittest_common.h"

int InitmDNSCoreReceiveTest(void);
int ValidQueryReqTest(void);
int NullDstQueryReqTest(void);
void InitmDNSStorage(mDNS *const m);

// This DNS message was gleaned from a uDNS query request packet that was captured with Wireshark.
uint8_t udns_query_request_message[28] = {			// contains 1 question for www.f5.com
	0x31, 0xca, // transaction id
	0x01, 0x00,	// flags
	0x00, 0x01,	// 1 question
	0x00, 0x00,	// no anwsers
	0x00, 0x00,	// no authoritative answers
	0x00, 0x00, // no additionals
	0x03, 0x77, 0x77, 0x77, 0x02, 0x66, 0x35, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
};

// This DNS message was gleaned from a uDNS query request packet that was captured with Wireshark.
// Then the header id (more specifically, the msg->h.id) was deliberately cleared to force code
// path to traverse regression case, <rdar://problem/28556513>.
uint8_t udns_query_request_message_with_invalid_id[28] = {  // contains 1 question for www.f5.com, msg->h.id = 0
	0x00, 0x00,	// transaction id
	0x01, 0x00, // flags
	0x00, 0x01, // 1 question
	0x00, 0x00, // no anwsers
	0x00, 0x00, // no authoritative answers
	0x00, 0x00, // no additionals
	0x03, 0x77, 0x77, 0x77, 0x02, 0x66, 0x35, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01
};

uint8_t arp_request_packet[28] = {  // contains 1 question for www.f5.com, msg->h.id = 0
    0x00, 0x01, // hardware type: enet
    0x08, 0x00, // protocol type: IP
    0x06, // hardware size
    0x04, // Protcol size
    0x00, 0x01, // opcode request
    0x24, 0x01, 0xc7, 0x24, 0x35, 0x00, // Sender mac addr
    0x11, 0xe2, 0x14, 0x01,	// Sender ip addr
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	// target mac addr
    0x11, 0xe2, 0x17, 0xbe	// target ip addr
};
UNITTEST_HEADER(mDNSCoreReceiveTest)
    UNITTEST_TEST(InitmDNSCoreReceiveTest)
    UNITTEST_TEST(ValidQueryReqTest)
    UNITTEST_TEST(NullDstQueryReqTest)
UNITTEST_FOOTER

UNITTEST_HEADER(InitmDNSCoreReceiveTest)
	mDNSPlatformTimeInit();
	init_logging_ut();
	mDNS_LoggingEnabled = 0;
	mDNS_PacketLoggingEnabled = 0;
UNITTEST_FOOTER

UNITTEST_HEADER(ValidQueryReqTest)
	mDNS *const m = &mDNSStorage;
	mDNSAddr srcaddr, dstaddr;
	mDNSIPPort srcport, dstport;
	DNSMessage * msg;
	const mDNSu8 * end;

    // Init unit test environment and verify no error occurred.
    mStatus result = init_mdns_environment(mDNStrue);
    UNITTEST_ASSERT(result == mStatus_NoError);

	// Used random values for srcaddr and srcport
	srcaddr.type	   = mDNSAddrType_IPv4;
	srcaddr.ip.v4.b[0] = 192;
	srcaddr.ip.v4.b[1] = 168;
	srcaddr.ip.v4.b[2] = 1;
	srcaddr.ip.v4.b[3] = 10;
	srcport.NotAnInteger = swap16((mDNSu16)53);

	// Used random values for dstaddr and dstport
	dstaddr.type	   = mDNSAddrType_IPv4;
	dstaddr.ip.v4.b[0] = 192;
	dstaddr.ip.v4.b[1] = 168;
	dstaddr.ip.v4.b[2] = 1;
	dstaddr.ip.v4.b[3] = 20;
	dstport.NotAnInteger = swap16((mDNSu16)49339);

	// Set message to a DNS message (copied from a WireShark packet)
	msg = (DNSMessage *)udns_query_request_message;
	end = udns_query_request_message + sizeof(udns_query_request_message);

	// Execute mDNSCoreReceive using a valid DNS message
	mDNSCoreReceive(m, msg, end, &srcaddr, srcport, &dstaddr, dstport, if_nametoindex("en0"));

	// Verify that mDNSCoreReceiveQuery traversed the normal code path
	UNITTEST_ASSERT(m->mDNSStats.NormalQueries == 1);

UNITTEST_FOOTER

UNITTEST_HEADER(NullDstQueryReqTest)

	mDNS *const m = &mDNSStorage;
	mDNSAddr srcaddr;
	mDNSIPPort srcport, dstport;
	DNSMessage * msg;
	const mDNSu8 * end;

	// This test case does not require setup of interfaces, the record's cache, or pending questions
	// so m is initialized to all zeros.
	InitmDNSStorage(m);

	// Used random values for srcaddr and srcport
	srcaddr.type	   = mDNSAddrType_IPv4;
	srcaddr.ip.v4.b[0] = 192;
	srcaddr.ip.v4.b[1] = 168;
	srcaddr.ip.v4.b[2] = 1;
	srcaddr.ip.v4.b[3] = 10;
	srcport.NotAnInteger = swap16((mDNSu16)53);

	// Used random value for dstport
	dstport.NotAnInteger = swap16((mDNSu16)49339);

	// Set message to a DNS message (copied from a WireShark packet)
	msg = (DNSMessage *)udns_query_request_message_with_invalid_id;
	end = udns_query_request_message_with_invalid_id + sizeof(udns_query_request_message_with_invalid_id);

	// Execute mDNSCoreReceive to regress <rdar://problem/28556513>
	mDNSCoreReceive(m, msg, end, &srcaddr, srcport, NULL, dstport, if_nametoindex("en0"));

	// Verify that mDNSCoreReceiveQuery was NOT traversed through the normal code path
	UNITTEST_ASSERT(m->mDNSStats.NormalQueries == 0);

	// Verify code path that previously crashed, in <rdar://problem/28556513>, now traverses successfully
	// by checking a counter that was incremented on code path that crashed.
	UNITTEST_ASSERT(m->MPktNum == 1);

UNITTEST_FOOTER

void InitmDNSStorage(mDNS *const m)
{
	memset(m, 0, sizeof(mDNS));
}