blob: dc492c9221ac269501ecde2ea0159c80f353cec7 [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 Wang599dffb2016-01-15 15:29:05 -080061 static DHCPMessage InitRequest();
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 static uint32_t GenerateTransactionID();
64 // Initialize part of the data fields for outbound DHCP message.
65 // Serialize the message to a buffer
Ningyuan Wang2e8b9372016-01-25 14:15:46 -080066 bool Serialize(shill::ByteString* data) const;
Ningyuan Wang252c5552016-01-19 15:07:32 -080067
Ningyuan Wang787f45d2016-01-28 13:03:23 -080068 // DHCP option and field setters
Ningyuan Wang599dffb2016-01-15 15:29:05 -080069 void SetClientHardwareAddress(
70 const shill::ByteString& client_hardware_address);
71 void SetClientIdentifier(const shill::ByteString& client_identifier);
72 void SetClientIPAddress(uint32_t client_ip_address);
Ningyuan Wang787f45d2016-01-28 13:03:23 -080073 void SetErrorMessage(const std::string& error_message);
Ningyuan Wang599dffb2016-01-15 15:29:05 -080074 void SetLeaseTime(uint32_t lease_time);
75 void SetMessageType(uint8_t message_type);
Ningyuan Wang3af3d832016-01-28 10:28:56 -080076 void SetParameterRequestList(
77 const std::vector<uint8_t>& parameter_request_list);
Ningyuan Wang599dffb2016-01-15 15:29:05 -080078 void SetServerIdentifier(uint32_t server_identifier);
79 void SetTransactionID(uint32_t transaction_id);
Ningyuan Wang37b081d2016-01-12 10:29:39 -080080
Ningyuan Wang787f45d2016-01-28 13:03:23 -080081 // DHCP option and field getters
Ningyuan Wang63aa9b52016-01-19 10:24:59 -080082 const shill::ByteString& client_hardware_address() const {
Ningyuan Wang37b081d2016-01-12 10:29:39 -080083 return client_hardware_address_;
84 }
Ningyuan Wang599dffb2016-01-15 15:29:05 -080085 const shill::ByteString& client_identifier() const {
86 return client_identifier_;
87 }
88 uint32_t client_ip_address() const { return client_ip_address_; }
Ningyuan Wang787f45d2016-01-28 13:03:23 -080089 const std::string& domain_name() const { return domain_name_; }
90 const std::string& error_message() const { return error_message_; }
Ningyuan Wang599dffb2016-01-15 15:29:05 -080091 uint32_t lease_time() const { return lease_time_; }
92 uint8_t message_type() const { return message_type_; }
93 uint32_t rebinding_time() const { return rebinding_time_; }
94 uint32_t renewal_time() const { return renewal_time_; }
95 const std::vector<uint32_t>& router() const { return router_; }
96 uint32_t server_identifier() const { return server_identifier_; }
97 uint32_t subnet_mask() const { return subnet_mask_; }
98 uint32_t transaction_id() const { return transaction_id_; }
99 uint32_t your_ip_address() const { return your_ip_address_; }
100 const std::vector<uint32_t>& dns_server() const { return dns_server_; }
Ningyuan Wang48f82042016-01-04 11:28:09 -0800101
102 private:
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800103 bool ParseDHCPOptions(const uint8_t* options, size_t options_length);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800104 bool IsValid();
Ningyuan Wang3030ddf2016-01-19 11:40:09 -0800105 bool ContainsValidOptions(const std::set<uint8_t>& options_set);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800106
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800107 // Message type: request or reply.
Ningyuan Wang48f82042016-01-04 11:28:09 -0800108 uint8_t opcode_;
109 // Hardware address type.
110 uint8_t hardware_address_type_;
111 // Hardware address length.
112 uint8_t hardware_address_length_;
113 // Client sets to zero, optionally used by relay agents
114 // when booting via a relay agent.
115 uint8_t relay_hops_;
116 // Transaction id.
117 uint32_t transaction_id_;
118 // Elapsed time from boot in seconds.
119 uint16_t seconds_;
120 // Broadcast flag
121 uint16_t flags_;
122 // Previously allocated client IP.
123 uint32_t client_ip_address_;
124 // Client IP address.
125 uint32_t your_ip_address_;
126 // IP address of next server to use in bootstrap;
127 // returned in DHCPOFFER, DHCPACK by server.
128 // It should be zero in client's messages.
129 uint32_t next_server_ip_address_;
130 // Relay agent IP address, used in booting via a relay agent.
131 // It should be zero in client's messages.
132 uint32_t agent_ip_address_;
133 // Client's hardware address.
Ningyuan Wang63aa9b52016-01-19 10:24:59 -0800134 shill::ByteString client_hardware_address_;
Ningyuan Wang48f82042016-01-04 11:28:09 -0800135 // Server host name.
136 std::string servername_;
137 // Boot file name.
138 std::string bootfile_;
139 uint32_t cookie_;
140
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800141 // A map from DHCP Options number to corresponding callbacks.
142 std::map<uint8_t, ParserContext> options_map_;
143
144 // Fields for DHCP Options.
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800145 // Option 1: Subnet Mask.
146 uint32_t subnet_mask_;
147 // Option 3: Router(Default Gateway).
148 std::vector<uint32_t> router_;
149 // Option 6: Domain Name Server.
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800150 std::vector<uint32_t> dns_server_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800151 // Option 15: Domain Name.
152 std::string domain_name_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800153 // Option 51: IP address lease time in unit of seconds.
154 uint32_t lease_time_;
155 // Option 53: DHCP message type.
156 uint8_t message_type_;
157 // Option 54: Server Identifier.
158 uint32_t server_identifier_;
Ningyuan Wang3af3d832016-01-28 10:28:56 -0800159 // Option 55: Parameter Request List.
160 std::vector<uint8_t> parameter_request_list_;
Ningyuan Wang787f45d2016-01-28 13:03:23 -0800161 // Option 56: (Error) Message.
162 std::string error_message_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800163 // Option 58: Renewal time value in unit of seconds.
164 uint32_t renewal_time_;
165 // Option 59: Rebinding time value in unit of seconds.
166 uint32_t rebinding_time_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800167 // Option 61: Client identifier.
168 shill::ByteString client_identifier_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800169
Ningyuan Wang48f82042016-01-04 11:28:09 -0800170 DISALLOW_COPY_AND_ASSIGN(DHCPMessage);
171};
172
173} // namespace dhcp_client
174
175#endif // DHCP_CLIENT_DHCP_MESSAGE_H_