blob: 9ffd8d3bb76fbe8733893b869fb2eea88ecdf1c8 [file] [log] [blame]
Ningyuan Wang48f82042016-01-04 11:28:09 -08001//
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#ifndef DHCP_CLIENT_DHCP_MESSAGE_H_
18#define DHCP_CLIENT_DHCP_MESSAGE_H_
19
Ningyuan Wang37b081d2016-01-12 10:29:39 -080020#include <map>
21#include <memory>
Ningyuan Wang3030ddf2016-01-19 11:40:09 -080022#include <set>
Ningyuan Wang48f82042016-01-04 11:28:09 -080023#include <string>
Ningyuan Wang37b081d2016-01-12 10:29:39 -080024#include <vector>
Ningyuan Wang48f82042016-01-04 11:28:09 -080025
26#include <base/macros.h>
Ningyuan Wang63aa9b52016-01-19 10:24:59 -080027#include <shill/net/byte_string.h>
Ningyuan Wang37b081d2016-01-12 10:29:39 -080028
Ningyuan Wangd4b86842016-01-13 11:28:54 -080029#include "dhcp_client/dhcp_options_parser.h"
30
Ningyuan Wang48f82042016-01-04 11:28:09 -080031namespace dhcp_client {
32
Ningyuan Wang37b081d2016-01-12 10:29:39 -080033static const uint8_t kDHCPMessageTypeDiscover = 1;
34static const uint8_t kDHCPMessageTypeOffer = 2;
35static const uint8_t kDHCPMessageTypeRequest = 3;
36static const uint8_t kDHCPMessageTypeDecline = 4;
37static const uint8_t kDHCPMessageTypeAck = 5;
38static const uint8_t kDHCPMessageTypeNak = 6;
39static const uint8_t kDHCPMessageTypeRelease = 7;
40static const uint8_t kDHCPMessageTypeInform = 8;
41
42typedef std::unique_ptr<DHCPOptionsParser> ParserPtr;
43
44struct ParserContext{
45 ParserPtr parser;
46 void* output;
47 ParserContext(DHCPOptionsParser* parser_ptr, void* output_ptr)
48 : parser(parser_ptr),
49 output(output_ptr) {}
50};
51
Ningyuan Wang48f82042016-01-04 11:28:09 -080052class DHCPMessage {
53 public:
Ningyuan Wang48f82042016-01-04 11:28:09 -080054 DHCPMessage();
55 ~DHCPMessage();
Ningyuan Wang599dffb2016-01-15 15:29:05 -080056 // Initialize the data fields from a buffer with existing DHCP message.
57 // This is used for inbound DHCP message.
Ningyuan Wang48f82042016-01-04 11:28:09 -080058 static bool InitFromBuffer(const unsigned char* buffer,
59 size_t length,
60 DHCPMessage* message);
Ningyuan Wangb5c518a2016-02-02 10:08:07 -080061 static void InitRequest(DHCPMessage* message);
Ningyuan Wang679654b2016-01-08 15:43:36 -080062 static uint16_t ComputeChecksum(const uint8_t* data, size_t len);
Ningyuan Wang599dffb2016-01-15 15:29:05 -080063 // Initialize part of the data fields for outbound DHCP message.
64 // Serialize the message to a buffer
Ningyuan Wang2e8b9372016-01-25 14:15:46 -080065 bool Serialize(shill::ByteString* data) const;
Ningyuan Wang252c5552016-01-19 15:07:32 -080066
Ningyuan Wang787f45d2016-01-28 13:03:23 -080067 // DHCP option and field setters
Ningyuan Wang599dffb2016-01-15 15:29:05 -080068 void SetClientHardwareAddress(
69 const shill::ByteString& client_hardware_address);
70 void SetClientIdentifier(const shill::ByteString& client_identifier);
71 void SetClientIPAddress(uint32_t client_ip_address);
Ningyuan Wang787f45d2016-01-28 13:03:23 -080072 void SetErrorMessage(const std::string& error_message);
Ningyuan Wang599dffb2016-01-15 15:29:05 -080073 void SetLeaseTime(uint32_t lease_time);
74 void SetMessageType(uint8_t message_type);
Ningyuan Wang3af3d832016-01-28 10:28:56 -080075 void SetParameterRequestList(
76 const std::vector<uint8_t>& parameter_request_list);
Ningyuan Wang738c8b62016-02-01 14:19:23 -080077 void SetRequestedIpAddress(uint32_t requested_ip_address);
Ningyuan Wang599dffb2016-01-15 15:29:05 -080078 void SetServerIdentifier(uint32_t server_identifier);
79 void SetTransactionID(uint32_t transaction_id);
Ningyuan Wang57c5f542016-01-28 16:21:00 -080080 void SetVendorSpecificInfo(const shill::ByteString& vendor_specific_info);
Ningyuan Wang37b081d2016-01-12 10:29:39 -080081
Ningyuan Wang787f45d2016-01-28 13:03:23 -080082 // DHCP option and field getters
Ningyuan Wang63aa9b52016-01-19 10:24:59 -080083 const shill::ByteString& client_hardware_address() const {
Ningyuan Wang37b081d2016-01-12 10:29:39 -080084 return client_hardware_address_;
85 }
Ningyuan Wang599dffb2016-01-15 15:29:05 -080086 const shill::ByteString& client_identifier() const {
87 return client_identifier_;
88 }
89 uint32_t client_ip_address() const { return client_ip_address_; }
Ningyuan Wang57c5f542016-01-28 16:21:00 -080090 const std::vector<uint32_t>& dns_server() const { return dns_server_; }
Ningyuan Wang787f45d2016-01-28 13:03:23 -080091 const std::string& domain_name() const { return domain_name_; }
92 const std::string& error_message() const { return error_message_; }
Ningyuan Wang599dffb2016-01-15 15:29:05 -080093 uint32_t lease_time() const { return lease_time_; }
94 uint8_t message_type() const { return message_type_; }
95 uint32_t rebinding_time() const { return rebinding_time_; }
96 uint32_t renewal_time() const { return renewal_time_; }
97 const std::vector<uint32_t>& router() const { return router_; }
98 uint32_t server_identifier() const { return server_identifier_; }
99 uint32_t subnet_mask() const { return subnet_mask_; }
100 uint32_t transaction_id() const { return transaction_id_; }
Ningyuan Wang57c5f542016-01-28 16:21:00 -0800101 const shill::ByteString& vendor_specific_info() const {
102 return vendor_specific_info_;
103 }
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800104 uint32_t your_ip_address() const { return your_ip_address_; }
Ningyuan Wang48f82042016-01-04 11:28:09 -0800105
106 private:
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800107 bool ParseDHCPOptions(const uint8_t* options, size_t options_length);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800108 bool IsValid();
Ningyuan Wang3030ddf2016-01-19 11:40:09 -0800109 bool ContainsValidOptions(const std::set<uint8_t>& options_set);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800110
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800111 // Message type: request or reply.
Ningyuan Wang48f82042016-01-04 11:28:09 -0800112 uint8_t opcode_;
113 // Hardware address type.
114 uint8_t hardware_address_type_;
115 // Hardware address length.
116 uint8_t hardware_address_length_;
117 // Client sets to zero, optionally used by relay agents
118 // when booting via a relay agent.
119 uint8_t relay_hops_;
120 // Transaction id.
121 uint32_t transaction_id_;
122 // Elapsed time from boot in seconds.
123 uint16_t seconds_;
124 // Broadcast flag
125 uint16_t flags_;
126 // Previously allocated client IP.
127 uint32_t client_ip_address_;
128 // Client IP address.
129 uint32_t your_ip_address_;
130 // IP address of next server to use in bootstrap;
131 // returned in DHCPOFFER, DHCPACK by server.
132 // It should be zero in client's messages.
133 uint32_t next_server_ip_address_;
134 // Relay agent IP address, used in booting via a relay agent.
135 // It should be zero in client's messages.
136 uint32_t agent_ip_address_;
137 // Client's hardware address.
Ningyuan Wang63aa9b52016-01-19 10:24:59 -0800138 shill::ByteString client_hardware_address_;
Ningyuan Wang48f82042016-01-04 11:28:09 -0800139 // Server host name.
140 std::string servername_;
141 // Boot file name.
142 std::string bootfile_;
143 uint32_t cookie_;
144
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800145 // A map from DHCP Options number to corresponding callbacks.
146 std::map<uint8_t, ParserContext> options_map_;
147
148 // Fields for DHCP Options.
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800149 // Option 1: Subnet Mask.
150 uint32_t subnet_mask_;
151 // Option 3: Router(Default Gateway).
152 std::vector<uint32_t> router_;
153 // Option 6: Domain Name Server.
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800154 std::vector<uint32_t> dns_server_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800155 // Option 15: Domain Name.
156 std::string domain_name_;
Ningyuan Wang57c5f542016-01-28 16:21:00 -0800157 // Option 43: Vendor Specific Information.
158 shill::ByteString vendor_specific_info_;
Ningyuan Wang738c8b62016-02-01 14:19:23 -0800159 // Option 50: Requested IP Address.
160 uint32_t requested_ip_address_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800161 // Option 51: IP address lease time in unit of seconds.
162 uint32_t lease_time_;
163 // Option 53: DHCP message type.
164 uint8_t message_type_;
165 // Option 54: Server Identifier.
166 uint32_t server_identifier_;
Ningyuan Wang3af3d832016-01-28 10:28:56 -0800167 // Option 55: Parameter Request List.
168 std::vector<uint8_t> parameter_request_list_;
Ningyuan Wang787f45d2016-01-28 13:03:23 -0800169 // Option 56: (Error) Message.
170 std::string error_message_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800171 // Option 58: Renewal time value in unit of seconds.
172 uint32_t renewal_time_;
173 // Option 59: Rebinding time value in unit of seconds.
174 uint32_t rebinding_time_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800175 // Option 61: Client identifier.
176 shill::ByteString client_identifier_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800177
Ningyuan Wang48f82042016-01-04 11:28:09 -0800178 DISALLOW_COPY_AND_ASSIGN(DHCPMessage);
179};
180
181} // namespace dhcp_client
182
183#endif // DHCP_CLIENT_DHCP_MESSAGE_H_