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_options_parser.h> 18 19 #include <netinet/in.h> 20 21 #include <memory> 22 #include <string> 23 #include <utility> 24 #include <vector> 25 26 #include <gtest/gtest.h> 27 #include <shill/net/byte_string.h> 28 29 using shill::ByteString; 30 31 namespace { 32 const uint8_t kFakeUInt8Option[] = {0x02}; 33 const uint8_t kFakeUInt8OptionLength = 1; 34 const uint8_t kFakeUInt16Option[] = {0x2a, 0x01}; 35 const uint8_t kFakeUInt16OptionLength = 2; 36 const uint8_t kFakeUInt32Option[] = {0x01, 0x02, 0x00, 0xfa}; 37 const uint8_t kFakeUInt32OptionLength = 4; 38 const uint8_t kFakeUInt8ListOption[] = 39 {0x01, 0x02, 0x00, 0xfa, 0x23, 0xae, 0x1f, 0x00}; 40 const uint8_t kFakeUInt8ListOptionLength = 8; 41 42 const uint8_t kFakeUInt16ListOption[] = 43 {0xaa, 0x26, 0x4b, 0x00, 0xff, 0xc2, 0xcf, 0x0d, 0xe0, 0x01}; 44 const uint8_t kFakeUInt16ListOptionLength = 10; 45 46 const uint8_t kFakeUInt32ListOption[] = {0x01, 0x02, 0x00, 0xfa, 47 0x23, 0xae, 0x1f, 0x00, 48 0x0c, 0x53, 0x33, 0x10, 49 0x47, 0x80, 0xb3, 0xff}; 50 const uint8_t kFakeUInt32ListOptionLength = 16; 51 52 const uint8_t kFakeUInt32PairListOption[] = {0x21, 0xa0, 0xeb, 0x73, 53 0x01, 0x00, 0x1f, 0x10, 54 0xc9, 0x22, 0x3a, 0x37, 55 0xff, 0x00, 0xbe, 0xd0}; 56 const uint8_t kFakeUInt32PairListOptionLength = 16; 57 58 const unsigned char kFakeStringOption[] = 59 {'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g'}; 60 const uint8_t kFakeStringOptionLength = 10; 61 62 const unsigned char kFakeByteArrayOption[] = 63 {'f', 'a', 'k', 'e', 'b', 'y', 't', 'e', 'a', 'r', 'r', 'a', 'y'}; 64 65 const uint8_t kFakeBoolOptionEnable[] = {0x01}; 66 const uint8_t kFakeBoolOptionDisable[] = {0x00}; 67 const uint8_t kFakeBoolOptionLength = 1; 68 } // namespace 69 70 namespace dhcp_client { 71 72 class ParserTest : public testing::Test { 73 protected: 74 std::unique_ptr<DHCPOptionsParser> parser_; 75 }; 76 77 TEST_F(ParserTest, ParseUInt8) { 78 parser_.reset(new UInt8Parser()); 79 uint8_t value; 80 EXPECT_TRUE(parser_->GetOption(kFakeUInt8Option, 81 kFakeUInt8OptionLength, 82 &value)); 83 EXPECT_EQ(*kFakeUInt8Option, value); 84 } 85 86 TEST_F(ParserTest, ParseUInt16) { 87 parser_.reset(new UInt16Parser()); 88 uint16_t value; 89 uint16_t target_value = 90 *reinterpret_cast<const uint16_t*>(kFakeUInt16Option); 91 target_value = ntohs(target_value); 92 EXPECT_TRUE(parser_->GetOption(kFakeUInt16Option, 93 kFakeUInt16OptionLength, 94 &value)); 95 EXPECT_EQ(target_value, value); 96 } 97 98 TEST_F(ParserTest, ParseUInt32) { 99 parser_.reset(new UInt32Parser()); 100 uint32_t value; 101 uint32_t target_value = 102 *reinterpret_cast<const uint32_t*>(kFakeUInt32Option); 103 target_value = ntohl(target_value); 104 EXPECT_TRUE(parser_->GetOption(kFakeUInt32Option, 105 kFakeUInt32OptionLength, 106 &value)); 107 EXPECT_EQ(target_value, value); 108 } 109 110 TEST_F(ParserTest, ParseUInt8List) { 111 parser_.reset(new UInt8ListParser()); 112 std::vector<uint8_t> value; 113 std::vector<uint8_t> target_value; 114 uint8_t length = kFakeUInt8ListOptionLength; 115 const uint8_t* uint8_list = 116 reinterpret_cast<const uint8_t*>(kFakeUInt8ListOption); 117 target_value = std::vector<uint8_t>(uint8_list, uint8_list + length); 118 EXPECT_TRUE(parser_->GetOption(kFakeUInt8ListOption, 119 kFakeUInt8ListOptionLength, 120 &value)); 121 EXPECT_EQ(target_value, value); 122 } 123 124 TEST_F(ParserTest, ParseUInt16List) { 125 parser_.reset(new UInt16ListParser()); 126 std::vector<uint16_t> value; 127 std::vector<uint16_t> target_value; 128 std::vector<uint16_t> target_value_net_order; 129 int length = kFakeUInt16ListOptionLength / sizeof(uint16_t); 130 const uint16_t* uint16_list = 131 reinterpret_cast<const uint16_t*>(kFakeUInt16ListOption); 132 target_value_net_order = 133 std::vector<uint16_t>(uint16_list, uint16_list + length); 134 for (uint16_t element : target_value_net_order) { 135 target_value.push_back(ntohs(element)); 136 } 137 EXPECT_TRUE(parser_->GetOption(kFakeUInt16ListOption, 138 kFakeUInt16ListOptionLength, 139 &value)); 140 EXPECT_EQ(target_value, value); 141 } 142 143 TEST_F(ParserTest, ParseUInt32List) { 144 parser_.reset(new UInt32ListParser()); 145 std::vector<uint32_t> value; 146 std::vector<uint32_t> target_value; 147 std::vector<uint32_t> target_value_net_order; 148 int length = kFakeUInt32ListOptionLength / sizeof(uint32_t); 149 const uint32_t* uint32_list = 150 reinterpret_cast<const uint32_t*>(kFakeUInt32ListOption); 151 target_value_net_order = 152 std::vector<uint32_t>(uint32_list, uint32_list + length); 153 for (uint32_t element : target_value_net_order) { 154 target_value.push_back(ntohl(element)); 155 } 156 EXPECT_TRUE(parser_->GetOption(kFakeUInt32ListOption, 157 kFakeUInt32ListOptionLength, 158 &value)); 159 EXPECT_EQ(target_value, value); 160 } 161 162 TEST_F(ParserTest, ParseUInt32PairList) { 163 parser_.reset(new UInt32PairListParser()); 164 int length = kFakeUInt32PairListOptionLength / (2 * sizeof(uint32_t)); 165 const uint32_t* uint32_array = 166 reinterpret_cast<const uint32_t*>(kFakeUInt32PairListOption); 167 std::vector<uint32_t> uint32_vector = 168 std::vector<uint32_t>(uint32_array, uint32_array + length * 2); 169 std::vector<std::pair<uint32_t, uint32_t>> target_value; 170 for (int i = 0; i < length; i++) { 171 target_value.push_back( 172 std::pair<uint32_t, uint32_t>(ntohl(uint32_vector[2 * i]), 173 ntohl(uint32_vector[2 * i + 1]))); 174 } 175 std::vector<std::pair<uint32_t, uint32_t>> value; 176 EXPECT_TRUE(parser_->GetOption(kFakeUInt32PairListOption, 177 kFakeUInt32PairListOptionLength, 178 &value)); 179 EXPECT_EQ(target_value, value); 180 } 181 182 TEST_F(ParserTest, ParseBoolEnable) { 183 parser_.reset(new BoolParser()); 184 bool value; 185 EXPECT_TRUE(parser_->GetOption(kFakeBoolOptionEnable, 186 kFakeBoolOptionLength, 187 &value)); 188 EXPECT_TRUE(value); 189 } 190 191 TEST_F(ParserTest, ParseBoolDisable) { 192 parser_.reset(new BoolParser()); 193 bool value; 194 EXPECT_TRUE(parser_->GetOption(kFakeBoolOptionDisable, 195 kFakeBoolOptionLength, 196 &value)); 197 EXPECT_FALSE(value); 198 } 199 200 TEST_F(ParserTest, ParseString) { 201 parser_.reset(new StringParser()); 202 std::string value; 203 std::string target_value; 204 target_value.assign(reinterpret_cast<const char*>(kFakeStringOption), 205 kFakeStringOptionLength); 206 EXPECT_TRUE(parser_->GetOption(kFakeStringOption, 207 kFakeStringOptionLength, 208 &value)); 209 EXPECT_EQ(target_value, value); 210 } 211 212 TEST_F(ParserTest, ParseByteArray) { 213 parser_.reset(new ByteArrayParser()); 214 ByteString value; 215 ByteString target_value(reinterpret_cast<const char*>(kFakeByteArrayOption), 216 sizeof(kFakeByteArrayOption)); 217 EXPECT_TRUE(parser_->GetOption(kFakeByteArrayOption, 218 sizeof(kFakeByteArrayOption), 219 &value)); 220 EXPECT_TRUE(target_value.Equals(value)); 221 } 222 223 } // namespace dhcp_client 224