• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
22 #include <utility>
23 #include <vector>
24 
25 #include <base/logging.h>
26 #include <base/macros.h>
27 #include <shill/net/byte_string.h>
28 
29 using shill::ByteString;
30 
31 namespace dhcp_client {
32 
GetOption(const uint8_t * buffer,uint8_t length,void * value)33 bool UInt8Parser::GetOption(const uint8_t* buffer,
34                             uint8_t length,
35                             void* value) {
36   if (length != sizeof(uint8_t)) {
37     LOG(ERROR) << "Invalid option length field";
38     return false;
39   }
40   uint8_t* value_uint8 = static_cast<uint8_t*>(value);
41   *value_uint8 = *buffer;
42   return true;
43 }
44 
GetOption(const uint8_t * buffer,uint8_t length,void * value)45 bool UInt16Parser::GetOption(const uint8_t* buffer,
46                              uint8_t length,
47                              void* value) {
48   if (length != sizeof(uint16_t)) {
49     LOG(ERROR) << "Invalid option length field";
50     return false;
51   }
52   uint16_t* value_uint16 = static_cast<uint16_t*>(value);
53   *value_uint16 = ntohs(*reinterpret_cast<const uint16_t*>(buffer));
54   return true;
55 }
56 
GetOption(const uint8_t * buffer,uint8_t length,void * value)57 bool UInt32Parser::GetOption(const uint8_t* buffer,
58                              uint8_t length,
59                              void* value) {
60   if (length != sizeof(uint32_t)) {
61     LOG(ERROR) << "Invalid option length field";
62     return false;
63   }
64   uint32_t* value_uint32 = static_cast<uint32_t*>(value);
65   *value_uint32 = ntohl(*reinterpret_cast<const uint32_t*>(buffer));
66   return true;
67 }
68 
GetOption(const uint8_t * buffer,uint8_t length,void * value)69 bool UInt8ListParser::GetOption(const uint8_t* buffer,
70                                 uint8_t length,
71                                 void* value) {
72   if (length == 0) {
73     LOG(ERROR) << "Invalid option length field";
74     return false;
75   }
76   std::vector<uint8_t>* value_vector =
77       static_cast<std::vector<uint8_t>*>(value);
78   for (int i = 0; i < length; i++) {
79     uint8_t content = *reinterpret_cast<const uint8_t*>(buffer);
80     value_vector->push_back(content);
81     buffer += sizeof(uint8_t);
82   }
83   return true;
84 }
85 
GetOption(const uint8_t * buffer,uint8_t length,void * value)86 bool UInt16ListParser::GetOption(const uint8_t* buffer,
87                                  uint8_t length,
88                                  void* value) {
89   if (length == 0 || length % sizeof(uint16_t)) {
90     LOG(ERROR) << "Invalid option length field";
91     return false;
92   }
93   int num_int16s = length / sizeof(uint16_t);
94   std::vector<uint16_t>* value_vector =
95       static_cast<std::vector<uint16_t>*>(value);
96   for (int i = 0; i < num_int16s; i++) {
97     uint16_t content = *reinterpret_cast<const uint16_t*>(buffer);
98     content = ntohs(content);
99     value_vector->push_back(content);
100     buffer += sizeof(uint16_t);
101   }
102   return true;
103 }
104 
GetOption(const uint8_t * buffer,uint8_t length,void * value)105 bool UInt32ListParser::GetOption(const uint8_t* buffer,
106                                  uint8_t length,
107                                  void* value) {
108   if (length == 0 || length % sizeof(uint32_t)) {
109     LOG(ERROR) << "Invalid option length field";
110     return false;
111   }
112   int num_int32s = length / sizeof(uint32_t);
113   std::vector<uint32_t>* value_vector =
114       static_cast<std::vector<uint32_t>*>(value);
115   for (int i = 0; i < num_int32s; i++) {
116     uint32_t content = *reinterpret_cast<const uint32_t*>(buffer);
117     content = ntohl(content);
118     value_vector->push_back(content);
119     buffer += sizeof(uint32_t);
120   }
121   return true;
122 }
123 
GetOption(const uint8_t * buffer,uint8_t length,void * value)124 bool UInt32PairListParser::GetOption(const uint8_t* buffer,
125                                      uint8_t length,
126                                      void* value) {
127   if (length == 0 || length % (2 * sizeof(uint32_t))) {
128     LOG(ERROR) << "Invalid option length field";
129     return false;
130   }
131   int num_int32pairs = length / (2 * sizeof(uint32_t));
132   std::vector<std::pair<uint32_t, uint32_t>>* value_vector =
133       static_cast<std::vector<std::pair<uint32_t, uint32_t>>*>(value);
134   for (int i = 0; i < num_int32pairs; i++) {
135     uint32_t first = *reinterpret_cast<const uint32_t*>(buffer);
136     first = ntohl(first);
137     buffer += sizeof(uint32_t);
138     uint32_t second = *reinterpret_cast<const uint32_t*>(buffer);
139     second = ntohl(second);
140     value_vector->push_back(std::pair<uint32_t, uint32_t>(first, second));
141     buffer += sizeof(uint32_t);
142   }
143   return true;
144 }
145 
GetOption(const uint8_t * buffer,uint8_t length,void * value)146 bool BoolParser::GetOption(const uint8_t* buffer,
147                            uint8_t length,
148                            void* value) {
149   if (length != sizeof(uint8_t)) {
150     LOG(ERROR) << "Invalid option length field";
151     return false;
152   }
153   uint8_t content = *buffer;
154   bool* enable = static_cast<bool*>(value);
155   if (content == 1) {
156     *enable = true;
157   } else if (content == 0) {
158     *enable = false;
159   } else {
160     LOG(ERROR) << "Invalid option value field";
161     return false;
162   }
163   return true;
164 }
165 
GetOption(const uint8_t * buffer,uint8_t length,void * value)166 bool StringParser::GetOption(const uint8_t* buffer,
167                              uint8_t length,
168                              void* value) {
169   if (length == 0) {
170     LOG(ERROR) << "Invalid option length field";
171     return false;
172   }
173   std::string* option_string = static_cast<std::string*>(value);
174   option_string->assign(reinterpret_cast<const char*>(buffer), length);
175   return true;
176 }
177 
GetOption(const uint8_t * buffer,uint8_t length,void * value)178 bool ByteArrayParser::GetOption(const uint8_t* buffer,
179                                 uint8_t length,
180                                 void* value) {
181   if (length == 0) {
182     LOG(ERROR) << "Invalid option length field";
183     return false;
184   }
185   ByteString* byte_array =
186       static_cast<ByteString*>(value);
187   *byte_array = ByteString(buffer, length);
188   return true;
189 }
190 
191 }  // namespace dhcp_client
192