// // Copyright (C) 2015 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "dhcp_client/dhcp_message.h" #include #include #include #include #include "dhcp_client/dhcp_options.h" #define SERVER_NAME 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 #define BOOT_FILE 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 #define COOKIE 0x63, 0x82, 0x53, 0x63 // The fake client hardware address(the first 6 bytes) contains a zero. #define CLIENT_HARDWARE_ADDRESS 0xbf, 0x78, 0xa2, 0x00, \ 0x0c, 0xea, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00 #define TRANSACTION_ID 0x0f, 0x22, 0xa3, 0x50 #define CLIENT_IP_ADDRESS 0x00, 0x00, 0x00, 0x00 #define YOUR_IP_ADDRESS 0xaf, 0x23, 0x11, 0x34 #define NEXT_SERVER_IP_ADDRESS 0x00, 0x00, 0x00, 0x00 #define AGENT_IP_ADDRESS 0x00, 0x00, 0x00, 0x00 #define SECONDS 0x00, 0x00 #define FLAGS 0x00, 0x00 #define HOPS 0x00 #define HARDWARE_ADDRESS_LENGTH 0x06 #define HARDWARE_ADDRESS_TYPE 0x01 #define REQUEST 0x01 #define REPLY 0x02 #define END_TAG 0xff #define SERVER_ID 0x01, 0xa2, 0x01, 0x1b #define LEASE_TIME 0x00, 0x00, 0x11, 0x11 namespace dhcp_client { namespace { const uint8_t kFakeBufferEvenLength[] = {0x08, 0x00, 0x00, 0x00, 0x71, 0x50, 0x00, 0x00}; const size_t kFakeBufferEvenLengthSize = 8; const uint16_t kFakeBufferEvenLengthChecksum = 0x86af; const uint8_t kFakeBufferOddLength[] = {0x08, 0x00, 0x00, 0x00, 0xac, 0x51, 0x00, 0x00, 0x00, 0x00, 0x01}; const size_t kFakeBufferOddLengthSize = 11; const uint16_t kFakeBufferOddLengthChecksum = 0x4aae; const uint8_t kFakeDHCPOfferMessage[] = { REPLY, // op, offer is a reply message HARDWARE_ADDRESS_TYPE, // htype HARDWARE_ADDRESS_LENGTH, // hlen HOPS, // hops TRANSACTION_ID, // xid SECONDS, // secs FLAGS, // flags CLIENT_IP_ADDRESS, // ciaddr YOUR_IP_ADDRESS, // yiaddr NEXT_SERVER_IP_ADDRESS, // siaddr AGENT_IP_ADDRESS, // giaddr CLIENT_HARDWARE_ADDRESS, // chaddr SERVER_NAME, // sname BOOT_FILE, // file COOKIE, // cookie kDHCPOptionMessageType, 0x01, kDHCPMessageTypeOffer, // message type option kDHCPOptionLeaseTime, 0x04, LEASE_TIME, // lease time option kDHCPOptionServerIdentifier, 0x04, SERVER_ID, // server identifier option END_TAG // options end tag }; const uint8_t kFakeDHCPAckMessage[] = { REPLY, // op, ack is a reply message HARDWARE_ADDRESS_TYPE, // htype HARDWARE_ADDRESS_LENGTH, // hlen HOPS, // hops TRANSACTION_ID, // xid SECONDS, // secs FLAGS, // flags CLIENT_IP_ADDRESS, // ciaddr YOUR_IP_ADDRESS, // yiaddr NEXT_SERVER_IP_ADDRESS, // siaddr AGENT_IP_ADDRESS, // giaddr CLIENT_HARDWARE_ADDRESS, // chaddr SERVER_NAME, // sname BOOT_FILE, // file COOKIE, // cookie kDHCPOptionMessageType, 0x01, kDHCPMessageTypeAck, // message type option kDHCPOptionLeaseTime, 0x04, LEASE_TIME, // lease time option kDHCPOptionServerIdentifier, 0x04, SERVER_ID, // server identifier option END_TAG // options end tag }; const uint8_t kFakeDHCPNakMessage[] = { REPLY, // op, nak is a reply message HARDWARE_ADDRESS_TYPE, // htype HARDWARE_ADDRESS_LENGTH, // hlen HOPS, // hops TRANSACTION_ID, // xid SECONDS, // secs FLAGS, // flags CLIENT_IP_ADDRESS, // ciaddr YOUR_IP_ADDRESS, // yiaddr NEXT_SERVER_IP_ADDRESS, // siaddr AGENT_IP_ADDRESS, // giaddr CLIENT_HARDWARE_ADDRESS, // chaddr SERVER_NAME, // sname BOOT_FILE, // file COOKIE, // cookie kDHCPOptionMessageType, 0x01, kDHCPMessageTypeNak, // message type option kDHCPOptionServerIdentifier, 0x04, SERVER_ID, // server identifier option END_TAG // options end tag }; const uint8_t kFakeTransactionID[] = {TRANSACTION_ID}; const uint8_t kFakeServerIdentifier[] = {SERVER_ID}; const uint8_t kFakeLeaseTime[] = {LEASE_TIME}; const uint8_t kFakeYourIPAddress[] = {YOUR_IP_ADDRESS}; const uint8_t kFakeHardwareAddress[] = {CLIENT_HARDWARE_ADDRESS}; size_t kFakeDHCPOfferMessageLength = sizeof(kFakeDHCPOfferMessage); size_t kFakeDHCPAckMessageLength = sizeof(kFakeDHCPAckMessage); size_t kFakeDHCPNakMessageLength = sizeof(kFakeDHCPNakMessage); } // namespace class DHCPMessageTest : public testing::Test { public: DHCPMessageTest() {} protected: }; TEST_F(DHCPMessageTest, ComputeChecksumEvenLengthTest) { uint16_t checksum = DHCPMessage::ComputeChecksum(kFakeBufferEvenLength, kFakeBufferEvenLengthSize); EXPECT_EQ(kFakeBufferEvenLengthChecksum, checksum); } TEST_F(DHCPMessageTest, ComputeChecksumOddLengthTest) { uint16_t checksum = DHCPMessage::ComputeChecksum(kFakeBufferOddLength, kFakeBufferOddLengthSize); EXPECT_EQ(kFakeBufferOddLengthChecksum, checksum); } TEST_F(DHCPMessageTest, InitFromBufferMessageTypeOffer) { DHCPMessage msg; EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPOfferMessage, kFakeDHCPOfferMessageLength, &msg)); EXPECT_EQ(kDHCPMessageTypeOffer, msg.message_type()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeTransactionID)), msg.transaction_id()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeServerIdentifier)), msg.server_identifier()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeLeaseTime)), msg.lease_time()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeYourIPAddress)), msg.your_ip_address()); EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress, msg.client_hardware_address().GetConstData(), msg.client_hardware_address().GetLength())); } TEST_F(DHCPMessageTest, InitFromBufferMessageTypeAck) { DHCPMessage msg; EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPAckMessage, kFakeDHCPAckMessageLength, &msg)); EXPECT_EQ(kDHCPMessageTypeAck, msg.message_type()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeTransactionID)), msg.transaction_id()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeServerIdentifier)), msg.server_identifier()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeLeaseTime)), msg.lease_time()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeYourIPAddress)), msg.your_ip_address()); EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress, msg.client_hardware_address().GetConstData(), msg.client_hardware_address().GetLength())); } TEST_F(DHCPMessageTest, InitFromBufferMessageTypeNak) { DHCPMessage msg; EXPECT_TRUE(DHCPMessage::InitFromBuffer(kFakeDHCPNakMessage, kFakeDHCPNakMessageLength, &msg)); EXPECT_EQ(kDHCPMessageTypeNak, msg.message_type()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeTransactionID)), msg.transaction_id()); EXPECT_EQ(ntohl(*reinterpret_cast(kFakeServerIdentifier)), msg.server_identifier()); EXPECT_EQ(0, std::memcmp(kFakeHardwareAddress, msg.client_hardware_address().GetConstData(), msg.client_hardware_address().GetLength())); } } // namespace dhcp_client