1d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// 2d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// Copyright (C) 2015 The Android Open Source Project 3d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// 4d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// Licensed under the Apache License, Version 2.0 (the "License"); 5d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// you may not use this file except in compliance with the License. 6d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// You may obtain a copy of the License at 7d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// 8d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// http://www.apache.org/licenses/LICENSE-2.0 9d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// 10d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// Unless required by applicable law or agreed to in writing, software 11d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// distributed under the License is distributed on an "AS IS" BASIS, 12d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// See the License for the specific language governing permissions and 14d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// limitations under the License. 15d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang// 16d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 17d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include "dhcp_client/dhcp_options_writer.h" 18d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 19d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <netinet/in.h> 20d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 21d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <string> 22d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <utility> 23d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <vector> 24d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 25d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <base/logging.h> 26d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include <base/macros.h> 27d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 28d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang#include "dhcp_client/dhcp_options.h" 29d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 3015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangusing shill::ByteString; 31d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wangnamespace { 32d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wangbase::LazyInstance<dhcp_client::DHCPOptionsWriter> g_dhcp_options_writer 33d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang = LAZY_INSTANCE_INITIALIZER; 34d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} // namespace 35d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 36d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wangnamespace dhcp_client { 37d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 38d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan WangDHCPOptionsWriter* DHCPOptionsWriter::GetInstance() { 39d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang return g_dhcp_options_writer.Pointer(); 40d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 41d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 4215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt8Option(ByteString* buffer, 43d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 44d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t value) { 4515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = sizeof(uint8_t); 4615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 4715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 4815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 4915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 5015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value), 5115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 5215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 53d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 54d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 5515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt16Option(ByteString* buffer, 56d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 57d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint16_t value) { 5815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = sizeof(uint16_t); 5915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint16_t value_net = htons(value); 6015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 6115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 6215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 6315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 6415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value_net), 6515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint16_t))); 6615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 67d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 68d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 6915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt32Option(ByteString* buffer, 70d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 71d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint32_t value) { 7215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = sizeof(uint32_t); 7315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint32_t value_net = htonl(value); 7415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 7515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 7615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 7715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 7815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value_net), 7915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint32_t))); 8015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 81d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 82d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 8315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt8ListOption(ByteString* buffer, 84d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 85d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const std::vector<uint8_t>& value) { 8615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang if (value.size() == 0) { 8715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang LOG(ERROR) << "Faild to write option: " << static_cast<int>(option_code) 8815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang << ", because value size cannot be 0"; 8915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return -1; 90d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 9115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.size() * sizeof(uint8_t); 9215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 9315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 9415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 9515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 9615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value.front()), 9715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang length * sizeof(uint8_t))); 9815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 99d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 100d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 10115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt16ListOption(ByteString* buffer, 102d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 103d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const std::vector<uint16_t>& value) { 104d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang if (value.size() == 0) { 105d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang LOG(ERROR) << "Faild to write option: " << static_cast<int>(option_code) 106d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang << ", because value size cannot be 0"; 107d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang return -1; 108d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 10915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.size() * sizeof(uint16_t); 11015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 11115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 11215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 11315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 114d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang for (uint16_t element : value) { 11515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint16_t element_net = htons(element); 11615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char *>(&element_net), 11715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint16_t))); 118d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 11915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 120d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 121d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 12215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt32ListOption(ByteString* buffer, 123d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 124d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const std::vector<uint32_t>& value) { 125d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang if (value.size() == 0) { 126d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang LOG(ERROR) << "Faild to write option: " << static_cast<int>(option_code) 127d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang << ", because value size cannot be 0"; 128d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang return -1; 129d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 13015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.size() * sizeof(uint32_t); 13115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 13215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 13315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 13415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 135d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang for (uint32_t element : value) { 13615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint32_t element_net = htonl(element); 13715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&element_net), 13815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint32_t))); 139d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 14015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 141d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 142d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 14315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteUInt32PairListOption(ByteString* buffer, 144d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 145d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const std::vector<std::pair<uint32_t, uint32_t>>& value) { 146d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang if (value.size() == 0) { 147d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang LOG(ERROR) << "Faild to write option: " << static_cast<int>(option_code) 148d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang << ", because value size cannot be 0"; 149d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang return -1; 150d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 15115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.size() * sizeof(uint32_t) * 2; 15215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 15315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 15415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 15515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 156d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang for (auto element : value) { 15715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint32_t first_net = htonl(element.first); 15815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint32_t second_net = htonl(element.second); 15915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&first_net), 16015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint32_t))); 16115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&second_net), 16215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint32_t))); 163d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 16415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 165d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 166d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 16715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteBoolOption(ByteString* buffer, 168d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 169d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const bool value) { 17015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = sizeof(uint8_t); 17115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t value_uint8 = value ? 1 : 0; 17215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 17315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 17415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 17515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 17615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value_uint8), 17715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 17815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 179d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 180d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 18115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteStringOption(ByteString* buffer, 182d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang uint8_t option_code, 183d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang const std::string& value) { 184d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang if (value.size() == 0) { 185d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang LOG(ERROR) << "Faild to write option: " << static_cast<int>(option_code) 186d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang << ", because value size cannot be 0"; 187d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang return -1; 188d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang } 18915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.size(); 19015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 19115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 19215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 19315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 19415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&value.front()), 19515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang length * sizeof(uint8_t))); 19615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 19715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang} 19815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang 19915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteByteArrayOption(ByteString* buffer, 20015c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t option_code, 20115c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang const ByteString& value) { 20215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t length = value.GetLength(); 20315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&option_code), 20415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 20515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&length), 20615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 20715c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang 20815c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(value); 20915c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return length + 2; 210d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 211d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 21215c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wangint DHCPOptionsWriter::WriteEndTag(ByteString* buffer) { 21315c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang uint8_t tag = kDHCPOptionEnd; 21415c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang buffer->Append(ByteString(reinterpret_cast<const char*>(&tag), 21515c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang sizeof(uint8_t))); 21615c10d2a1c42c31c68c1d88f85627ff9bdefd29dNingyuan Wang return 1; 217d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} 218d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang 219d4b86841f58d9c4b299e651ce1772cd0b505c614Ningyuan Wang} // namespace dhcp_client 220