blob: 124000bbfc84d46f315532f69c43995633a1fa88 [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 Wang252c5552016-01-19 15:07:32 -080066 bool Serialize(shill::ByteString* data);
67
Ningyuan Wang599dffb2016-01-15 15:29:05 -080068 // DHCP option and filed setters
69 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);
73 void SetLeaseTime(uint32_t lease_time);
74 void SetMessageType(uint8_t message_type);
75 void SetServerIdentifier(uint32_t server_identifier);
76 void SetTransactionID(uint32_t transaction_id);
Ningyuan Wang37b081d2016-01-12 10:29:39 -080077
Ningyuan Wang599dffb2016-01-15 15:29:05 -080078 // DHCP option and filed getters
Ningyuan Wang63aa9b52016-01-19 10:24:59 -080079 const shill::ByteString& client_hardware_address() const {
Ningyuan Wang37b081d2016-01-12 10:29:39 -080080 return client_hardware_address_;
81 }
Ningyuan Wang599dffb2016-01-15 15:29:05 -080082 const shill::ByteString& client_identifier() const {
83 return client_identifier_;
84 }
85 uint32_t client_ip_address() const { return client_ip_address_; }
86 std::string domain_name() const { return domain_name_; }
87
88 uint32_t lease_time() const { return lease_time_; }
89 uint8_t message_type() const { return message_type_; }
90 uint32_t rebinding_time() const { return rebinding_time_; }
91 uint32_t renewal_time() const { return renewal_time_; }
92 const std::vector<uint32_t>& router() const { return router_; }
93 uint32_t server_identifier() const { return server_identifier_; }
94 uint32_t subnet_mask() const { return subnet_mask_; }
95 uint32_t transaction_id() const { return transaction_id_; }
96 uint32_t your_ip_address() const { return your_ip_address_; }
97 const std::vector<uint32_t>& dns_server() const { return dns_server_; }
Ningyuan Wang48f82042016-01-04 11:28:09 -080098
99 private:
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800100 bool ParseDHCPOptions(const uint8_t* options, size_t options_length);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800101 bool IsValid();
Ningyuan Wang3030ddf2016-01-19 11:40:09 -0800102 bool ContainsValidOptions(const std::set<uint8_t>& options_set);
Ningyuan Wang48f82042016-01-04 11:28:09 -0800103
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800104 // Message type: request or reply.
Ningyuan Wang48f82042016-01-04 11:28:09 -0800105 uint8_t opcode_;
106 // Hardware address type.
107 uint8_t hardware_address_type_;
108 // Hardware address length.
109 uint8_t hardware_address_length_;
110 // Client sets to zero, optionally used by relay agents
111 // when booting via a relay agent.
112 uint8_t relay_hops_;
113 // Transaction id.
114 uint32_t transaction_id_;
115 // Elapsed time from boot in seconds.
116 uint16_t seconds_;
117 // Broadcast flag
118 uint16_t flags_;
119 // Previously allocated client IP.
120 uint32_t client_ip_address_;
121 // Client IP address.
122 uint32_t your_ip_address_;
123 // IP address of next server to use in bootstrap;
124 // returned in DHCPOFFER, DHCPACK by server.
125 // It should be zero in client's messages.
126 uint32_t next_server_ip_address_;
127 // Relay agent IP address, used in booting via a relay agent.
128 // It should be zero in client's messages.
129 uint32_t agent_ip_address_;
130 // Client's hardware address.
Ningyuan Wang63aa9b52016-01-19 10:24:59 -0800131 shill::ByteString client_hardware_address_;
Ningyuan Wang48f82042016-01-04 11:28:09 -0800132 // Server host name.
133 std::string servername_;
134 // Boot file name.
135 std::string bootfile_;
136 uint32_t cookie_;
137
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800138 // A map from DHCP Options number to corresponding callbacks.
139 std::map<uint8_t, ParserContext> options_map_;
140
141 // Fields for DHCP Options.
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800142 // Option 1: Subnet Mask.
143 uint32_t subnet_mask_;
144 // Option 3: Router(Default Gateway).
145 std::vector<uint32_t> router_;
146 // Option 6: Domain Name Server.
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800147 std::vector<uint32_t> dns_server_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800148 // Option 15: Domain Name.
149 std::string domain_name_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800150 // Option 51: IP address lease time in unit of seconds.
151 uint32_t lease_time_;
152 // Option 53: DHCP message type.
153 uint8_t message_type_;
154 // Option 54: Server Identifier.
155 uint32_t server_identifier_;
156 // Option 58: Renewal time value in unit of seconds.
157 uint32_t renewal_time_;
158 // Option 59: Rebinding time value in unit of seconds.
159 uint32_t rebinding_time_;
Ningyuan Wang599dffb2016-01-15 15:29:05 -0800160 // Option 61: Client identifier.
161 shill::ByteString client_identifier_;
Ningyuan Wang37b081d2016-01-12 10:29:39 -0800162
Ningyuan Wang48f82042016-01-04 11:28:09 -0800163 DISALLOW_COPY_AND_ASSIGN(DHCPMessage);
164};
165
166} // namespace dhcp_client
167
168#endif // DHCP_CLIENT_DHCP_MESSAGE_H_