// // 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_options_writer.h> #include <netinet/in.h> #include <memory> #include <string> #include <utility> #include <vector> #include <gtest/gtest.h> #include <shill/net/byte_string.h> #include "dhcp_client/dhcp_options.h" using shill::ByteString; namespace dhcp_client { namespace { const uint8_t kFakeOptionCode1 = 3; const uint8_t kFakeOptionCode2 = 45; const uint8_t kFakeOptionCode3 = 251; } // namespace class DHCPOptionsWriterTest : public testing::Test { protected: DHCPOptionsWriter* options_writer_; }; TEST_F(DHCPOptionsWriterTest, WriteUInt8) { const uint8_t kFakeUInt8Option = 0x22; const uint8_t kFakeUInt8OptionResult[] = { kFakeOptionCode1, sizeof(uint8_t), 0x22}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt8Option(&option, kFakeOptionCode1, kFakeUInt8Option); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt8OptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt16) { const uint16_t kFakeUInt16Option = 0x1516; const uint8_t kFakeUInt16OptionResult[] = { kFakeOptionCode2, sizeof(uint16_t), // Use the network byte order. 0x15, 0x16}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt16Option(&option, kFakeOptionCode2, kFakeUInt16Option); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt16OptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt32) { const uint32_t kFakeUInt32Option = 0x32a0bf01; const uint8_t kFakeUInt32OptionResult[] = { kFakeOptionCode3, sizeof(uint32_t), // Use the network byte order. 0x32, 0xa0, 0xbf, 0x01}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt32Option(&option, kFakeOptionCode3, kFakeUInt32Option); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt32OptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt8List) { const std::vector<uint8_t> kFakeUInt8ListOption = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; const uint8_t kFakeUInt8ListOptionResult[] = { kFakeOptionCode1, static_cast<uint8_t>(kFakeUInt8ListOption.size()), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt8ListOption(&option, kFakeOptionCode1, kFakeUInt8ListOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt8ListOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt16List) { const std::vector<uint16_t> kFakeUInt16ListOption = {0xb1a2, 0x0264, 0xdc03, 0x92c4, 0xa500, 0x0010}; const uint8_t kFakeUInt16ListOptionResult[] = { kFakeOptionCode2, static_cast<uint8_t>(sizeof(uint16_t) * kFakeUInt16ListOption.size()), // Use the network byte order. 0xb1, 0xa2, 0x02, 0x64, 0xdc, 0x03, 0x92, 0xc4, 0xa5, 0x00, 0x00, 0x10}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt16ListOption(&option, kFakeOptionCode2, kFakeUInt16ListOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt16ListOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt32List) { const std::vector<uint32_t> kFakeUInt32ListOption = {0x03a64301, 0x03f52614, 0x7c5d9eff, 0x0138b26e}; const uint8_t kFakeUInt32ListOptionResult[] = { kFakeOptionCode3, static_cast<uint8_t>(sizeof(uint32_t) * kFakeUInt32ListOption.size()), // Use the network byte order. 0x03, 0xa6, 0x43, 0x01, 0x03, 0xf5, 0x26, 0x14, 0x7c, 0x5d, 0x9e, 0xff, 0x01, 0x38, 0xb2, 0x6e}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt32ListOption(&option, kFakeOptionCode3, kFakeUInt32ListOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt32ListOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteUInt32PairList) { const std::vector<std::pair<uint32_t, uint32_t>> kFakeUInt32PairListOption = {{0x03b576a1, 0xfa070054}, {0x650c3d22, 0x1397e5bb}}; const uint8_t kFakeUInt32PairListOptionResult[] = { kFakeOptionCode1, static_cast<uint8_t> (sizeof(uint32_t) * 2 * kFakeUInt32PairListOption.size()), // Use the network byte order. 0x03, 0xb5, 0x76, 0xa1, 0xfa, 0x07, 0x00, 0x54, 0x65, 0x0c, 0x3d, 0x22, 0x13, 0x97, 0xe5, 0xbb}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteUInt32PairListOption(&option, kFakeOptionCode1, kFakeUInt32PairListOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeUInt32PairListOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteString) { const std::string kFakeStringOption = "fakestring"; const uint8_t kFakeStringOptionResult[] = { kFakeOptionCode1, static_cast<uint8_t>(kFakeStringOption.size()), 'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g'}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteStringOption(&option, kFakeOptionCode1, kFakeStringOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeStringOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteBoolTrue) { const uint8_t kFakeBoolOptionTrue = true; const uint8_t kFakeBoolOptionResultTrue[] = { kFakeOptionCode1, sizeof(uint8_t), 0x01}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteBoolOption(&option, kFakeOptionCode1, kFakeBoolOptionTrue); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeBoolOptionResultTrue, length)); } TEST_F(DHCPOptionsWriterTest, WriteBoolFalse) { const uint8_t kFakeBoolOptionFalse = false; const uint8_t kFakeBoolOptionResultFalse[] = { kFakeOptionCode2, sizeof(uint8_t), 0x00}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteBoolOption(&option, kFakeOptionCode2, kFakeBoolOptionFalse); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeBoolOptionResultFalse, length)); } TEST_F(DHCPOptionsWriterTest, WriteByteArray) { const ByteString kFakeByteArrayOption = ByteString({0x06, 0x05, 0x04, 0x03, 0x02, 0x01}); const uint8_t kFakeByteArrayOptionResult[] = { kFakeOptionCode1, static_cast<uint8_t>(kFakeByteArrayOption.GetLength()), 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteByteArrayOption(&option, kFakeOptionCode1, kFakeByteArrayOption); EXPECT_NE(-1, length); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeByteArrayOptionResult, length)); } TEST_F(DHCPOptionsWriterTest, WriteEndTag) { const std::string kFakeStringOption = "fakestring1"; const uint8_t kFakeStringOptionResult[] = { kFakeOptionCode1, static_cast<uint8_t>(kFakeStringOption.size()), 'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g', '1'}; ByteString option; options_writer_ = DHCPOptionsWriter::GetInstance(); int length = options_writer_->WriteStringOption(&option, kFakeOptionCode1, kFakeStringOption); EXPECT_NE(-1, length); EXPECT_NE(-1, options_writer_->WriteEndTag(&option)); EXPECT_EQ(0, std::memcmp(option.GetConstData(), kFakeStringOptionResult, length)); EXPECT_EQ(kDHCPOptionEnd, *(option.GetConstData() + length)); } } // namespace dhcp_client