| // |
| // 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 |