dhcp_message_unittest.cc revision 3030ddf90560522166c2c25865db084199ca38f7
1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "dhcp_client/dhcp_message.h"
18
19#include <netinet/in.h>
20
21#include <cstring>
22
23#include <gtest/gtest.h>
24#include <shill/net/byte_string.h>
25
26#include "dhcp_client/dhcp_options.h"
27
28#define SERVER_NAME 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
29                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
30                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
31                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
32                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
33                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
34                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
35                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36
37#define BOOT_FILE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
38                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
39                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
40                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
41                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
42                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
43                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
44                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
45                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
46                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
47                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
48                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
49                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
50                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
51                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
52                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
53#define COOKIE 0x63, 0x82, 0x53, 0x63
54// The fake client hardware address(the first 6 bytes) contains a zero.
55#define CLIENT_HARDWARE_ADDRESS 0xbf, 0x78, 0xa2, 0x00, \
56                                0x0c, 0xea, 0x00, 0x00, \
57                                0x00, 0x00, 0x00, 0x00, \
58                                0x00, 0x00, 0x00, 0x00
59
60#define TRANSACTION_ID 0x0f, 0x22, 0xa3, 0x50
61#define CLIENT_IP_ADDRESS 0x00, 0x00, 0x00, 0x00
62#define YOUR_IP_ADDRESS 0xaf, 0x23, 0x11, 0x34
63#define NEXT_SERVER_IP_ADDRESS 0x00, 0x00, 0x00, 0x00
64#define AGENT_IP_ADDRESS 0x00, 0x00, 0x00, 0x00
65#define SECONDS 0x00, 0x00
66#define FLAGS 0x00, 0x00
67#define HOPS 0x00
68#define HARDWARE_ADDRESS_LENGTH 0x06
69#define HARDWARE_ADDRESS_TYPE 0x01
70#define REQUEST 0x01
71#define REPLY 0x02
72#define END_TAG 0xff
73#define SERVER_ID 0x01, 0xa2, 0x01, 0x1b
74#define LEASE_TIME 0x00, 0x00, 0x11, 0x11
75
76namespace dhcp_client {
77namespace {
78const uint8_t kFakeBufferEvenLength[] = {0x08, 0x00, 0x00, 0x00,
79                                         0x71, 0x50, 0x00, 0x00};
80const size_t kFakeBufferEvenLengthSize = 8;
81const uint16_t kFakeBufferEvenLengthChecksum = 0x86af;
82
83const uint8_t kFakeBufferOddLength[] = {0x08, 0x00, 0x00, 0x00, 0xac, 0x51,
84                                        0x00, 0x00, 0x00, 0x00, 0x01};
85const size_t kFakeBufferOddLengthSize = 11;
86const uint16_t kFakeBufferOddLengthChecksum = 0x4aae;
87
88const uint8_t kFakeDHCPOfferMessage[] = {
89    REPLY,  // op, offer is a reply message
90    HARDWARE_ADDRESS_TYPE,  // htype
91    HARDWARE_ADDRESS_LENGTH,  // hlen
92    HOPS,  // hops
93    TRANSACTION_ID,  // xid
94    SECONDS,  // secs
95    FLAGS,  // flags
96    CLIENT_IP_ADDRESS,  // ciaddr
97    YOUR_IP_ADDRESS,  // yiaddr
98    NEXT_SERVER_IP_ADDRESS,  // siaddr
99    AGENT_IP_ADDRESS,  // giaddr
100    CLIENT_HARDWARE_ADDRESS,  // chaddr
101    SERVER_NAME,  // sname
102    BOOT_FILE,  // file
103    COOKIE,  // cookie
104    kDHCPOptionMessageType, 0x01, kDHCPMessageTypeOffer,  // message type option
105    kDHCPOptionLeaseTime, 0x04, LEASE_TIME,  // lease time option
106    kDHCPOptionServerIdentifier, 0x04, SERVER_ID,  // server identifier option
107    END_TAG  // options end tag
108};
109
110const uint8_t kFakeDHCPAckMessage[] = {
111    REPLY,  // op, ack is a reply message
112    HARDWARE_ADDRESS_TYPE,  // htype
113    HARDWARE_ADDRESS_LENGTH,  // hlen
114    HOPS,  // hops
115    TRANSACTION_ID,  // xid
116    SECONDS,  // secs
117    FLAGS,  // flags
118    CLIENT_IP_ADDRESS,  // ciaddr
119    YOUR_IP_ADDRESS,  // yiaddr
120    NEXT_SERVER_IP_ADDRESS,  // siaddr
121    AGENT_IP_ADDRESS,  // giaddr
122    CLIENT_HARDWARE_ADDRESS,  // chaddr
123    SERVER_NAME,  // sname
124    BOOT_FILE,  // file
125    COOKIE,  // cookie
126    kDHCPOptionMessageType, 0x01, kDHCPMessageTypeAck,  // message type option
127    kDHCPOptionLeaseTime, 0x04, LEASE_TIME,  // lease time option
128    kDHCPOptionServerIdentifier, 0x04, SERVER_ID,  // server identifier option
129    END_TAG  // options end tag
130};
131
132const uint8_t kFakeDHCPNakMessage[] = {
133    REPLY,  // op, nak is a reply message
134    HARDWARE_ADDRESS_TYPE,  // htype
135    HARDWARE_ADDRESS_LENGTH,  // hlen
136    HOPS,  // hops
137    TRANSACTION_ID,  // xid
138    SECONDS,  // secs
139    FLAGS,  // flags
140    CLIENT_IP_ADDRESS,  // ciaddr
141    YOUR_IP_ADDRESS,  // yiaddr
142    NEXT_SERVER_IP_ADDRESS,  // siaddr
143    AGENT_IP_ADDRESS,  // giaddr
144    CLIENT_HARDWARE_ADDRESS,  // chaddr
145    SERVER_NAME,  // sname
146    BOOT_FILE,  // file
147    COOKIE,  // cookie
148    kDHCPOptionMessageType, 0x01, kDHCPMessageTypeNak,  // message type option
149    kDHCPOptionServerIdentifier, 0x04, SERVER_ID,  // server identifier option
150    END_TAG  // options end tag
151};
152const uint8_t kFakeTransactionID[] = {TRANSACTION_ID};
153const uint8_t kFakeServerIdentifier[] = {SERVER_ID};
154const uint8_t kFakeLeaseTime[] = {LEASE_TIME};
155const uint8_t kFakeYourIPAddress[] = {YOUR_IP_ADDRESS};
156const uint8_t kFakeHardwareAddress[] = {CLIENT_HARDWARE_ADDRESS};
157size_t kFakeDHCPOfferMessageLength = sizeof(kFakeDHCPOfferMessage);
158size_t kFakeDHCPAckMessageLength = sizeof(kFakeDHCPAckMessage);
159size_t kFakeDHCPNakMessageLength = sizeof(kFakeDHCPNakMessage);
160}  // namespace
161
162class DHCPMessageTest : public testing::Test {
163 public:
164  DHCPMessageTest() {}
165 protected:
166};
167
168TEST_F(DHCPMessageTest, ComputeChecksumEvenLengthTest) {
169  uint16_t checksum = DHCPMessage::ComputeChecksum(kFakeBufferEvenLength,
170                                                   kFakeBufferEvenLengthSize);
171  EXPECT_EQ(kFakeBufferEvenLengthChecksum, checksum);
172}
173
174TEST_F(DHCPMessageTest, ComputeChecksumOddLengthTest) {
175  uint16_t checksum = DHCPMessage::ComputeChecksum(kFakeBufferOddLength,
176                                                   kFakeBufferOddLengthSize);
177  EXPECT_EQ(kFakeBufferOddLengthChecksum, checksum);
178}
179
180TEST_F(DHCPMessageTest, InitFromBufferMessageTypeOffer) {
181  DHCPMessage msg;
182  EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPOfferMessage,
183                                          kFakeDHCPOfferMessageLength,
184                                          &msg));
185  EXPECT_EQ(kDHCPMessageTypeOffer, msg.message_type());
186  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeTransactionID)),
187            msg.transaction_id());
188  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeServerIdentifier)),
189            msg.server_identifier());
190  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeLeaseTime)),
191            msg.lease_time());
192  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeYourIPAddress)),
193            msg.your_ip_address());
194  EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress,
195                           msg.client_hardware_address().GetConstData(),
196                           msg.client_hardware_address().GetLength()));
197}
198
199TEST_F(DHCPMessageTest, InitFromBufferMessageTypeAck) {
200  DHCPMessage msg;
201  EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPAckMessage,
202                                          kFakeDHCPAckMessageLength,
203                                          &msg));
204  EXPECT_EQ(kDHCPMessageTypeAck, msg.message_type());
205  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeTransactionID)),
206            msg.transaction_id());
207  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeServerIdentifier)),
208            msg.server_identifier());
209  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeLeaseTime)),
210            msg.lease_time());
211  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeYourIPAddress)),
212            msg.your_ip_address());
213  EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress,
214                           msg.client_hardware_address().GetConstData(),
215                           msg.client_hardware_address().GetLength()));
216}
217
218TEST_F(DHCPMessageTest, InitFromBufferMessageTypeNak) {
219  DHCPMessage msg;
220  EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPNakMessage,
221                                          kFakeDHCPNakMessageLength,
222                                          &msg));
223  EXPECT_EQ(kDHCPMessageTypeNak, msg.message_type());
224  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeTransactionID)),
225            msg.transaction_id());
226  EXPECT_EQ(ntohl(*reinterpret_cast<const uint32_t*>(kFakeServerIdentifier)),
227            msg.server_identifier());
228  EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress,
229                           msg.client_hardware_address().GetConstData(),
230                           msg.client_hardware_address().GetLength()));
231}
232
233}  // namespace dhcp_client
234