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_writer.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 #include "dhcp_client/dhcp_options.h" 30 31 using shill::ByteString; 32 namespace dhcp_client { 33 34 namespace { 35 const uint8_t kFakeOptionCode1 = 3; 36 const uint8_t kFakeOptionCode2 = 45; 37 const uint8_t kFakeOptionCode3 = 251; 38 } // namespace 39 40 41 class DHCPOptionsWriterTest : public testing::Test { 42 protected: 43 DHCPOptionsWriter* options_writer_; 44 }; 45 46 TEST_F(DHCPOptionsWriterTest, WriteUInt8) { 47 const uint8_t kFakeUInt8Option = 0x22; 48 const uint8_t kFakeUInt8OptionResult[] = { 49 kFakeOptionCode1, 50 sizeof(uint8_t), 51 0x22}; 52 53 ByteString option; 54 options_writer_ = DHCPOptionsWriter::GetInstance(); 55 int length = options_writer_->WriteUInt8Option(&option, 56 kFakeOptionCode1, 57 kFakeUInt8Option); 58 EXPECT_NE(-1, length); 59 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 60 kFakeUInt8OptionResult, 61 length)); 62 } 63 64 TEST_F(DHCPOptionsWriterTest, WriteUInt16) { 65 const uint16_t kFakeUInt16Option = 0x1516; 66 const uint8_t kFakeUInt16OptionResult[] = { 67 kFakeOptionCode2, 68 sizeof(uint16_t), 69 // Use the network byte order. 70 0x15, 0x16}; 71 72 ByteString option; 73 options_writer_ = DHCPOptionsWriter::GetInstance(); 74 int length = options_writer_->WriteUInt16Option(&option, 75 kFakeOptionCode2, 76 kFakeUInt16Option); 77 EXPECT_NE(-1, length); 78 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 79 kFakeUInt16OptionResult, 80 length)); 81 } 82 83 TEST_F(DHCPOptionsWriterTest, WriteUInt32) { 84 const uint32_t kFakeUInt32Option = 0x32a0bf01; 85 const uint8_t kFakeUInt32OptionResult[] = { 86 kFakeOptionCode3, 87 sizeof(uint32_t), 88 // Use the network byte order. 89 0x32, 0xa0, 0xbf, 0x01}; 90 91 ByteString option; 92 options_writer_ = DHCPOptionsWriter::GetInstance(); 93 int length = options_writer_->WriteUInt32Option(&option, 94 kFakeOptionCode3, 95 kFakeUInt32Option); 96 EXPECT_NE(-1, length); 97 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 98 kFakeUInt32OptionResult, 99 length)); 100 } 101 102 TEST_F(DHCPOptionsWriterTest, WriteUInt8List) { 103 const std::vector<uint8_t> kFakeUInt8ListOption = 104 {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; 105 const uint8_t kFakeUInt8ListOptionResult[] = { 106 kFakeOptionCode1, 107 static_cast<uint8_t>(kFakeUInt8ListOption.size()), 108 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; 109 110 ByteString option; 111 options_writer_ = DHCPOptionsWriter::GetInstance(); 112 int length = options_writer_->WriteUInt8ListOption(&option, 113 kFakeOptionCode1, 114 kFakeUInt8ListOption); 115 EXPECT_NE(-1, length); 116 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 117 kFakeUInt8ListOptionResult, 118 length)); 119 } 120 121 TEST_F(DHCPOptionsWriterTest, WriteUInt16List) { 122 const std::vector<uint16_t> kFakeUInt16ListOption = 123 {0xb1a2, 0x0264, 0xdc03, 0x92c4, 0xa500, 0x0010}; 124 const uint8_t kFakeUInt16ListOptionResult[] = { 125 kFakeOptionCode2, 126 static_cast<uint8_t>(sizeof(uint16_t) * kFakeUInt16ListOption.size()), 127 // Use the network byte order. 128 0xb1, 0xa2, 0x02, 0x64, 0xdc, 0x03, 0x92, 0xc4, 0xa5, 0x00, 0x00, 0x10}; 129 130 ByteString option; 131 options_writer_ = DHCPOptionsWriter::GetInstance(); 132 int length = options_writer_->WriteUInt16ListOption(&option, 133 kFakeOptionCode2, 134 kFakeUInt16ListOption); 135 EXPECT_NE(-1, length); 136 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 137 kFakeUInt16ListOptionResult, 138 length)); 139 } 140 141 TEST_F(DHCPOptionsWriterTest, WriteUInt32List) { 142 const std::vector<uint32_t> kFakeUInt32ListOption = 143 {0x03a64301, 0x03f52614, 0x7c5d9eff, 0x0138b26e}; 144 const uint8_t kFakeUInt32ListOptionResult[] = { 145 kFakeOptionCode3, 146 static_cast<uint8_t>(sizeof(uint32_t) * kFakeUInt32ListOption.size()), 147 // Use the network byte order. 148 0x03, 0xa6, 0x43, 0x01, 0x03, 0xf5, 0x26, 0x14, 149 0x7c, 0x5d, 0x9e, 0xff, 0x01, 0x38, 0xb2, 0x6e}; 150 151 ByteString option; 152 options_writer_ = DHCPOptionsWriter::GetInstance(); 153 int length = options_writer_->WriteUInt32ListOption(&option, 154 kFakeOptionCode3, 155 kFakeUInt32ListOption); 156 EXPECT_NE(-1, length); 157 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 158 kFakeUInt32ListOptionResult, 159 length)); 160 } 161 162 TEST_F(DHCPOptionsWriterTest, WriteUInt32PairList) { 163 const std::vector<std::pair<uint32_t, uint32_t>> kFakeUInt32PairListOption = 164 {{0x03b576a1, 0xfa070054}, {0x650c3d22, 0x1397e5bb}}; 165 const uint8_t kFakeUInt32PairListOptionResult[] = { 166 kFakeOptionCode1, 167 static_cast<uint8_t> 168 (sizeof(uint32_t) * 2 * kFakeUInt32PairListOption.size()), 169 // Use the network byte order. 170 0x03, 0xb5, 0x76, 0xa1, 0xfa, 0x07, 0x00, 0x54, 171 0x65, 0x0c, 0x3d, 0x22, 0x13, 0x97, 0xe5, 0xbb}; 172 173 ByteString option; 174 options_writer_ = DHCPOptionsWriter::GetInstance(); 175 int length = 176 options_writer_->WriteUInt32PairListOption(&option, 177 kFakeOptionCode1, 178 kFakeUInt32PairListOption); 179 EXPECT_NE(-1, length); 180 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 181 kFakeUInt32PairListOptionResult, 182 length)); 183 } 184 185 TEST_F(DHCPOptionsWriterTest, WriteString) { 186 const std::string kFakeStringOption = "fakestring"; 187 const uint8_t kFakeStringOptionResult[] = { 188 kFakeOptionCode1, 189 static_cast<uint8_t>(kFakeStringOption.size()), 190 'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g'}; 191 192 ByteString option; 193 options_writer_ = DHCPOptionsWriter::GetInstance(); 194 int length = options_writer_->WriteStringOption(&option, 195 kFakeOptionCode1, 196 kFakeStringOption); 197 EXPECT_NE(-1, length); 198 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 199 kFakeStringOptionResult, 200 length)); 201 } 202 203 204 TEST_F(DHCPOptionsWriterTest, WriteBoolTrue) { 205 const uint8_t kFakeBoolOptionTrue = true; 206 const uint8_t kFakeBoolOptionResultTrue[] = { 207 kFakeOptionCode1, 208 sizeof(uint8_t), 209 0x01}; 210 211 ByteString option; 212 options_writer_ = DHCPOptionsWriter::GetInstance(); 213 int length = options_writer_->WriteBoolOption(&option, 214 kFakeOptionCode1, 215 kFakeBoolOptionTrue); 216 EXPECT_NE(-1, length); 217 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 218 kFakeBoolOptionResultTrue, 219 length)); 220 } 221 222 TEST_F(DHCPOptionsWriterTest, WriteBoolFalse) { 223 const uint8_t kFakeBoolOptionFalse = false; 224 const uint8_t kFakeBoolOptionResultFalse[] = { 225 kFakeOptionCode2, 226 sizeof(uint8_t), 227 0x00}; 228 229 ByteString option; 230 options_writer_ = DHCPOptionsWriter::GetInstance(); 231 int length = options_writer_->WriteBoolOption(&option, 232 kFakeOptionCode2, 233 kFakeBoolOptionFalse); 234 EXPECT_NE(-1, length); 235 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 236 kFakeBoolOptionResultFalse, 237 length)); 238 } 239 240 TEST_F(DHCPOptionsWriterTest, WriteByteArray) { 241 const ByteString kFakeByteArrayOption = 242 ByteString({0x06, 0x05, 0x04, 0x03, 0x02, 0x01}); 243 const uint8_t kFakeByteArrayOptionResult[] = { 244 kFakeOptionCode1, 245 static_cast<uint8_t>(kFakeByteArrayOption.GetLength()), 246 0x06, 0x05, 0x04, 0x03, 0x02, 0x01}; 247 248 ByteString option; 249 options_writer_ = DHCPOptionsWriter::GetInstance(); 250 int length = options_writer_->WriteByteArrayOption(&option, 251 kFakeOptionCode1, 252 kFakeByteArrayOption); 253 EXPECT_NE(-1, length); 254 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 255 kFakeByteArrayOptionResult, 256 length)); 257 } 258 259 TEST_F(DHCPOptionsWriterTest, WriteEndTag) { 260 const std::string kFakeStringOption = "fakestring1"; 261 const uint8_t kFakeStringOptionResult[] = { 262 kFakeOptionCode1, 263 static_cast<uint8_t>(kFakeStringOption.size()), 264 'f', 'a', 'k', 'e', 's', 't', 'r', 'i', 'n', 'g', '1'}; 265 266 ByteString option; 267 options_writer_ = DHCPOptionsWriter::GetInstance(); 268 int length = options_writer_->WriteStringOption(&option, 269 kFakeOptionCode1, 270 kFakeStringOption); 271 EXPECT_NE(-1, length); 272 EXPECT_NE(-1, options_writer_->WriteEndTag(&option)); 273 EXPECT_EQ(0, std::memcmp(option.GetConstData(), 274 kFakeStringOptionResult, 275 length)); 276 EXPECT_EQ(kDHCPOptionEnd, *(option.GetConstData() + length)); 277 } 278 279 } // namespace dhcp_client 280