OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dhcp_handler.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef vnsw_agent_dhcp_handler_hpp
6 #define vnsw_agent_dhcp_handler_hpp
7 
8 #include "dhcp_handler_base.h"
9 
10 #define DHCP_PKT_SIZE 1024
11 
12 // Magic cookie for DHCP Options
13 #define DHCP_OPTIONS_COOKIE "\143\202\123\143"
14 
15 // Supported DHCP options
16 #define DHCP_OPTION_PAD 0
17 #define DHCP_OPTION_SUBNET_MASK 1
18 #define DHCP_OPTION_TIME_OFFSET 2 // deprecated
19 #define DHCP_OPTION_ROUTER 3
20 #define DHCP_OPTION_TIME_SERVER 4
21 #define DHCP_OPTION_NAME_SERVER 5
22 #define DHCP_OPTION_DNS 6
23 #define DHCP_OPTION_LOG_SERVER 7
24 #define DHCP_OPTION_QUOTE_SERVER 8
25 #define DHCP_OPTION_LPR_SERVER 9
26 #define DHCP_OPTION_IMPRESS_SERVER 10
27 #define DHCP_OPTION_RESOURCE_LOCATION_SERVER 11
28 #define DHCP_OPTION_HOST_NAME 12
29 #define DHCP_OPTION_BOOT_FILE_SIZE 13
30 #define DHCP_OPTION_MERIT_DUMP_FILE 14
31 #define DHCP_OPTION_DOMAIN_NAME 15
32 #define DHCP_OPTION_SWAP_SERVER 16
33 #define DHCP_OPTION_ROOT_PATH 17
34 #define DHCP_OPTION_EXTENSION_PATH 18
35 #define DHCP_OPTION_IP_FWD_CONTROL 19
36 #define DHCP_OPTION_NL_SRC_ROUTING 20
37 #define DHCP_OPTION_POLICY_FILTER 21
38 #define DHCP_OPTION_MAX_DG_REASSEMBLY_SIZE 22
39 #define DHCP_OPTION_DEFAULT_IP_TTL 23
40 #define DHCP_OPTION_PATH_MTU_AGING_TIMEOUT 24
41 #define DHCP_OPTION_PATH_MTU_PLATEAU_TABLE 25
42 #define DHCP_OPTION_INTERFACE_MTU 26
43 #define DHCP_OPTION_ALL_SUBNETS_LOCAL 27
44 #define DHCP_OPTION_BCAST_ADDRESS 28
45 #define DHCP_OPTION_PERFORM_MASK_DISCOVERY 29
46 #define DHCP_OPTION_MASK_SUPPLIER 30
47 #define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31
48 #define DHCP_OPTION_ROUTER_SOLICIT_ADDRESS 32
49 #define DHCP_OPTION_STATIC_ROUTING_TABLE 33
50 #define DHCP_OPTION_TRAILER_ENCAP 34
51 #define DHCP_OPTION_ARP_CACHE_TIMEOUT 35
52 #define DHCP_OPTION_ETHERNET_ENCAP 36
53 #define DHCP_OPTION_DEFAULT_TCP_TTL 37
54 #define DHCP_OPTION_TCP_KEEPALIVE_INTERVAL 38
55 #define DHCP_OPTION_TCP_KEEPALIVE_GARBAGE 39
56 #define DHCP_OPTION_NIS_DOMAIN 40
57 #define DHCP_OPTION_NIS_SERVERS 41
58 #define DHCP_OPTION_NTP_SERVERS 42
59 #define DHCP_OPTION_VENDOR_SPECIFIC_INFO 43
60 #define DHCP_OPTION_NETBIOS_OVER_TCP_NS 44
61 #define DHCP_OPTION_NETBIOS_OVER_TCP_DG_DS 45
62 #define DHCP_OPTION_NETBIOS_OVER_TCP_NODE_TYPE 46
63 #define DHCP_OPTION_NETBIOS_OVER_TCP_SCOPE 47
64 #define DHCP_OPTION_XWINDOW_FONT_SERVER 48
65 #define DHCP_OPTION_XWINDOW_SYSTEM_DISP_MGR 49
66 #define DHCP_OPTION_REQ_IP_ADDRESS 50
67 #define DHCP_OPTION_IP_LEASE_TIME 51
68 #define DHCP_OPTION_OVERLOAD 52
69 #define DHCP_OPTION_MSG_TYPE 53
70 #define DHCP_OPTION_SERVER_IDENTIFIER 54
71 #define DHCP_OPTION_PARAMETER_REQUEST_LIST 55
72 #define DHCP_OPTION_MESSAGE 56
73 #define DHCP_OPTION_MAX_DHCP_MSG_SIZE 57
74 #define DHCP_OPTION_RENEW_TIME_VALUE 58
75 #define DHCP_OPTION_REBIND_TIME_VALUE 59
76 #define DHCP_OPTION_CLASS_ID 60
77 #define DHCP_OPTION_CLIENT_ID 61
78 #define DHCP_OPTION_NETWARE_IP_DOMAIN_NAME 62
79 #define DHCP_OPTION_NETWARE_IP_INFO 63
80 #define DHCP_OPTION_NIS_PLUS_DOMAIN 64
81 #define DHCP_OPTION_NIS_PLUS_SERVERS 65
82 #define DHCP_OPTION_TFTP_SERVER_NAME 66
83 #define DHCP_OPTION_BOOTFILE_NAME 67
84 #define DHCP_OPTION_MOBILE_IP_HA 68
85 #define DHCP_OPTION_SMTP_SERVER 69
86 #define DHCP_OPTION_POP_SERVER 70
87 #define DHCP_OPTION_NNTP_SERVER 71
88 #define DHCP_OPTION_DEFAULT_WWW_SERVER 72
89 #define DHCP_OPTION_DEFAULT_FINGER_SERVER 73
90 #define DHCP_OPTION_DEFAULT_IRC_SERVER 74
91 #define DHCP_OPTION_STREETTALK_SERVER 75
92 #define DHCP_OPTION_STREETTALK_DA_SERVER 76
93 #define DHCP_OPTION_USER_CLASS_INFO 77
94 #define DHCP_OPTION_SLP_DIRECTORY_AGENT 78
95 #define DHCP_OPTION_SLP_SERVICE_SCOPE 79
96 #define DHCP_OPTION_RAPID_COMMIT 80
97 #define DHCP_OPTION_CLIENT_FQDN 81
98 #define DHCP_OPTION_82 82
99 #define DHCP_OPTION_STORAGE_NS 83
100 // ignoring option 84 (removed / unassigned)
101 #define DHCP_OPTION_NDS_SERVERS 85
102 #define DHCP_OPTION_NDS_TREE_NAME 86
103 #define DHCP_OPTION_NDS_CONTEXT 87
104 #define DHCP_OPTION_BCMCS_DN_LIST 88
105 #define DHCP_OPTION_BCMCS_ADDR_LIST 89
106 #define DHCP_OPTION_AUTH 90
107 #define DHCP_OPTION_CLIENT_LAST_XTIME 91
108 #define DHCP_OPTION_ASSOCIATE_IP 92
109 #define DHCP_OPTION_CLIENT_SYSARCH_TYPE 93
110 #define DHCP_OPTION_CLIENT_NW_INTERFACE_ID 94
111 #define DHCP_OPTION_LDAP 95
112 // ignoring 96 (removed / unassigned)
113 #define DHCP_OPTION_CLIENT_MACHINE_ID 97
114 #define DHCP_OPTION_OPENGROUP_USER_AUTH 98
115 #define DHCP_OPTION_GEOCONF_CIVIC 99
116 #define DHCP_OPTION_IEEE_1003_1_TZ 100
117 #define DHCP_OPTION_REF_TZ_DB 101
118 // ignoring 102 to 111 & 115 (removed / unassigned)
119 #define DHCP_OPTION_NETINFO_PARENT_SERVER_ADDR 112
120 #define DHCP_OPTION_NETINFO_PARENT_SERVER_TAG 113
121 #define DHCP_OPTION_URL 114
122 #define DHCP_OPTION_AUTO_CONFIGURE 116
123 #define DHCP_OPTION_NAME_SERVICE_SEARCH 117
124 #define DHCP_OPTION_SUBNET_SELECTION 118
125 #define DHCP_OPTION_DNS_DOMAIN_SEARCH_LIST 119
126 #define DHCP_OPTION_SIP_SERVERS 120
127 #define DHCP_OPTION_CLASSLESS_ROUTE 121
128 #define DHCP_OPTION_CCC 122
129 #define DHCP_OPTION_GEOCONF 123
130 #define DHCP_OPTION_VENDOR_ID_VENDOR_CLASS 124
131 #define DHCP_OPTION_VENDOR_ID_VENDOR_SPECIFIC 125
132 // ignoring 126, 127 (removed / unassigned)
133 // options 128 - 135 arent officially assigned to PXE
134 #define DHCP_OPTION_TFTP_SERVER 128
135 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_129 129
136 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_130 130
137 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_131 131
138 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_132 132
139 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_133 133
140 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_134 134
141 #define DHCP_OPTION_PXE_VENDOR_SPECIFIC_135 135
142 #define DHCP_OPTION_PANA_AUTH_AGENT 136
143 #define DHCP_OPTION_LOST_SERVER 137
144 #define DHCP_OPTION_CAPWAP_AC_ADDRESS 138
145 #define DHCP_OPTION_IPV4_ADDRESS_MOS 139
146 #define DHCP_OPTION_IPV4_FQDN_MOS 140
147 #define DHCP_OPTION_SIP_UA_CONFIG_DOMAIN 141
148 #define DHCP_OPTION_IPV4_ADDRESS_ANDSF 142
149 #define DHCP_OPTION_GEOLOC 144
150 #define DHCP_OPTION_FORCERENEW_NONCE_CAP 145
151 #define DHCP_OPTION_RDNSS_SELECTION 146
152 // ignoring options 143, 147 - 149 (removed / unassigned)
153 // option 150 is also assigned as Etherboot, GRUB configuration path name
154 #define DHCP_OPTION_TFTP_SERVER_ADDRESS 150
155 #define DHCP_OPTION_STATUS_CODE 151
156 #define DHCP_OPTION_BASE_TIME 152
157 #define DHCP_OPTION_START_TIME_OF_STATE 153
158 #define DHCP_OPTION_QUERY_START_TIME 154
159 #define DHCP_OPTION_QUERY_END_TIME 155
160 #define DHCP_OPTION_DHCP_STATE 156
161 #define DHCP_OPTION_DATA_SOURCE 157
162 #define DHCP_OPTION_PCP_SERVER 158
163 // ignoring options 159 - 174 (removed / unassigned)
164 // ignoring options 175 - 177 (tentatively assigned)
165 // ignoring options 178 - 207 (removed / unassigned)
166 #define DHCP_OPTION_PXELINUX_MAGIC 208 // deprecated
167 #define DHCP_OPTION_CONFIG_FILE 209
168 #define DHCP_OPTION_PATH_PREFIX 210
169 #define DHCP_OPTION_REBOOT_TIME 211
170 #define DHCP_OPTION_6RD 212
171 #define DHCP_OPTION_V4_ACCESS_DOMAIN 213
172 // ignoring options 214 - 219 (removed / unassigned)
173 #define DHCP_OPTION_SUBNET_ALLOCATION 220
174 #define DHCP_OPTION_VSS 221
175 // ignoring options 222 - 254 (removed / unassigned)
176 #define DHCP_OPTION_END 255
177 
178 #define DHCP_SUBOP_CKTID 1
179 #define DHCP_SUBOP_REMOTEID 2
180 
181 // DHCP message types
182 #define DHCP_UNKNOWN 0
183 #define DHCP_DISCOVER 1
184 #define DHCP_OFFER 2
185 #define DHCP_REQUEST 3
186 #define DHCP_DECLINE 4
187 #define DHCP_ACK 5
188 #define DHCP_NAK 6
189 #define DHCP_RELEASE 7
190 #define DHCP_INFORM 8
191 #define DHCP_LEASE_QUERY 10
192 #define DHCP_LEASE_UNASSIGNED 11
193 #define DHCP_LEASE_UNKNOWN 12
194 #define DHCP_LEASE_ACTIVE 13
195 
196 #define DHCP_CHADDR_LEN 16
197 #define DHCP_NAME_LEN 64
198 #define DHCP_FILE_LEN 128
199 #define DHCP_FIXED_LEN 236
200 #define DHCP_MAX_OPTION_LEN 1236
201 
202 #define DHCP_SERVER_PORT 67
203 #define DHCP_CLIENT_PORT 68
204 
205 #define BOOT_REQUEST 1
206 #define BOOT_REPLY 2
207 #define DHCP_BCAST_FLAG 0x8000
208 #define HW_TYPE_ETHERNET 1
209 
210 #define DHCP_SHORTLEASE_TIME 4
211 #define DHCP_GW_LEASE_TIME 86400
212 
213 struct dhcphdr {
214  uint8_t op;
215  uint8_t htype;
216  uint8_t hlen;
217  uint8_t hops; // # of relay agent hops
218  uint32_t xid;
219  uint16_t secs;
220  uint16_t flags;
221  in_addr_t ciaddr;
222  in_addr_t yiaddr;
223  in_addr_t siaddr;
224  in_addr_t giaddr;
227  uint8_t file[DHCP_FILE_LEN];
229 };
230 
232  void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen) {
233  code = c;
234  len = l;
235  memcpy(data, (uint8_t *)d, l);
236  *optlen += 2 + l;
237  }
238  void WriteByte(uint8_t c, uint16_t *optlen) {
239  code = c;
240  *optlen += 1;
241  }
242  void AppendData(uint16_t l, const void *d, uint16_t *optlen) {
243  memcpy(data + len, (uint8_t *)d, l);
244  len += l;
245  *optlen += l;
246  }
248  uint8_t *next = reinterpret_cast<uint8_t *>(this);
250  return reinterpret_cast<Dhcpv4Options *>(next + 1);
251  else
252  return reinterpret_cast<Dhcpv4Options *>(next + len + 2);
253  }
254 
255  uint8_t code;
256  uint8_t len;
257  uint8_t data[0];
258 };
259 
260 // DHCP protocol handler
261 class DhcpHandler : public DhcpHandlerBase {
262 public:
263 
265  DhcpRequestData() : xid(-1), flags(0), mac_addr(), ip_addr(0) {
266  }
267  void UpdateData(uint32_t id, uint16_t fl, uint8_t *mac) {
268  xid = id;
269  flags = fl;
270  mac_addr = mac;
271  }
272 
273  uint32_t xid;
274  uint16_t flags;
276  in_addr_t ip_addr;
277  };
278 
280  static const uint16_t kDhcpOptionFixedLen = 2;
281 
282  explicit Dhcpv4OptionHandler(uint8_t *ptr) { dhcp_option_ptr = ptr; }
283  void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen) {
284  option->WriteData(c, l, d, optlen);
285  }
286  void WriteByte(uint8_t c, uint16_t *optlen) {
287  option->WriteByte(c, optlen);
288  }
289  void AppendData(uint16_t l, const void *d, uint16_t *optlen) {
290  option->AppendData(l, d, optlen);
291  }
292  uint16_t GetCode() const { return option->code; }
293  uint16_t GetLen() const { return option->len; }
294  uint16_t GetFixedLen() const { return kDhcpOptionFixedLen; }
295  uint8_t *GetData() { return option->data; }
296  void SetCode(uint16_t c) { option->code = (uint8_t) c; }
297  void SetLen(uint16_t l) { option->len = (uint8_t) l; }
298  void AddLen(uint16_t l) { option->len += (uint8_t) l; }
299  void SetNextOptionPtr(uint16_t optlen) {
300  option = (Dhcpv4Options *)(dhcp_option_ptr + optlen);
301  }
302  void SetDhcpOptionPtr(uint8_t *ptr) { dhcp_option_ptr = ptr; }
303 
304  uint8_t *dhcp_option_ptr; // pointer to DHCP options in the packet
305  Dhcpv4Options *option; // pointer to current option being processed
306  };
307 
308  DhcpHandler(Agent *agent, boost::shared_ptr<PktInfo> info,
309  boost::asio::io_context &io);
310  virtual ~DhcpHandler();
311 
312  bool Run();
313 
314 private:
315  bool HandleVmRequest();
316  bool HandleMessage();
317  bool HandleDhcpFromFabric();
318  bool ReadOptions(int16_t opt_rem_len);
321  bool FindLeaseData();
322  void FillDhcpInfo(Ip4Address &addr, int plen,
323  Ip4Address &gw, Ip4Address &dns);
324  void WriteOption82(Dhcpv4Options *opt, uint16_t *optlen);
325  bool ReadOption82(Dhcpv4Options *opt);
326  bool CreateRelayPacket();
328  void RelayRequestToFabric();
330  uint16_t DhcpHdr(in_addr_t, in_addr_t);
331  uint16_t AddIP(uint16_t opt_len, const std::string &input);
332  uint16_t AddDomainNameOption(uint16_t opt_len);
333  uint16_t FillDhcpResponse(const MacAddress &dest_mac,
334  in_addr_t src_ip, in_addr_t dest_ip,
335  in_addr_t siaddr, in_addr_t yiaddr);
336  void SendDhcpResponse();
337  bool IsOptionRequested(uint8_t option);
338  bool IsRouterOptionNeeded();
339  void UpdateStats();
340  DhcpHandler::DhcpOptionCategory OptionCategory(uint32_t option) const;
341  uint32_t OptionCode(const std::string &option) const;
342  void DhcpTrace(const std::string &msg) const;
343 
345  uint8_t msg_type_;
346  uint8_t out_msg_type_;
347 
348  std::string parameters_; // options requested by the DHCP client
349  std::string nak_msg_;
352 };
353 
354 typedef std::map<std::string, uint32_t> Dhcpv4NameCodeMap;
355 typedef std::map<std::string, uint32_t>::const_iterator Dhcpv4NameCodeIter;
356 typedef std::map<uint32_t, DhcpHandler::DhcpOptionCategory> Dhcpv4CategoryMap;
357 typedef std::map<uint32_t, DhcpHandler::DhcpOptionCategory>::const_iterator Dhcpv4CategoryIter;
358 
359 #endif // vnsw_agent_dhcp_handler_hpp
uint16_t DhcpHdr(in_addr_t, in_addr_t)
in_addr_t yiaddr
Definition: dhcp_handler.h:222
#define DHCP_OPTION_PAD
Definition: dhcp_handler.h:16
uint8_t msg_type_
Definition: dhcp_handler.h:345
bool IsRouterOptionNeeded()
void ReleaseGatewayInterfaceLease()
bool HandleMessage()
std::map< std::string, uint32_t >::const_iterator Dhcpv4NameCodeIter
Definition: dhcp_handler.h:355
std::map< std::string, uint32_t > Dhcpv4NameCodeMap
Definition: dhcp_handler.h:354
bool GetGatewayInterfaceLease()
void WriteByte(uint8_t c, uint16_t *optlen)
Definition: dhcp_handler.h:286
uint8_t options[DHCP_MAX_OPTION_LEN]
Definition: dhcp_handler.h:228
Dhcpv4Options * GetNextOptionPtr()
Definition: dhcp_handler.h:247
void DhcpTrace(const std::string &msg) const
uint8_t htype
Definition: dhcp_handler.h:215
void SetNextOptionPtr(uint16_t optlen)
Definition: dhcp_handler.h:299
uint8_t sname[DHCP_NAME_LEN]
Definition: dhcp_handler.h:226
uint32_t xid
Definition: dhcp_handler.h:218
std::map< uint32_t, DhcpHandler::DhcpOptionCategory > Dhcpv4CategoryMap
Definition: dhcp_handler.h:356
void UpdateData(uint32_t id, uint16_t fl, uint8_t *mac)
Definition: dhcp_handler.h:267
uint16_t secs
Definition: dhcp_handler.h:219
void AppendData(uint16_t l, const void *d, uint16_t *optlen)
Definition: dhcp_handler.h:289
Agent * agent() const
Definition: proto_handler.h:80
uint8_t chaddr[DHCP_CHADDR_LEN]
Definition: dhcp_handler.h:225
#define DHCP_OPTION_END
Definition: dhcp_handler.h:176
std::string nak_msg_
Definition: dhcp_handler.h:349
in_addr_t ciaddr
Definition: dhcp_handler.h:221
uint16_t flags
Definition: dhcp_handler.h:220
bool CreateRelayResponsePacket()
uint8_t op
Definition: dhcp_handler.h:214
in_addr_t siaddr
Definition: dhcp_handler.h:223
void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen)
Definition: dhcp_handler.h:283
DhcpHandler(Agent *agent, boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
void SendDhcpResponse()
Definition: agent.h:358
bool ReadOptions(int16_t opt_rem_len)
void AppendData(uint16_t l, const void *d, uint16_t *optlen)
Definition: dhcp_handler.h:242
bool FindLeaseData()
uint16_t FillDhcpResponse(const MacAddress &dest_mac, in_addr_t src_ip, in_addr_t dest_ip, in_addr_t siaddr, in_addr_t yiaddr)
void RelayResponseFromFabric()
bool IsOptionRequested(uint8_t option)
DhcpRequestData request_
Definition: dhcp_handler.h:350
bool ReadOption82(Dhcpv4Options *opt)
#define DHCP_CHADDR_LEN
Definition: dhcp_handler.h:196
DhcpHandler::DhcpOptionCategory OptionCategory(uint32_t option) const
#define DHCP_MAX_OPTION_LEN
Definition: dhcp_handler.h:200
void FillDhcpInfo(Ip4Address &addr, int plen, Ip4Address &gw, Ip4Address &dns)
in_addr_t giaddr
Definition: dhcp_handler.h:224
void WriteOption82(Dhcpv4Options *opt, uint16_t *optlen)
void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen)
Definition: dhcp_handler.h:232
bool CreateRelayPacket()
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
uint8_t hops
Definition: dhcp_handler.h:217
void RelayRequestToFabric()
uint16_t AddIP(uint16_t opt_len, const std::string &input)
#define DHCP_NAME_LEN
Definition: dhcp_handler.h:197
#define DHCP_FILE_LEN
Definition: dhcp_handler.h:198
bool HandleDhcpFromFabric()
bool HandleVmRequest()
void UpdateStats()
uint32_t OptionCode(const std::string &option) const
void SetDhcpOptionPtr(uint8_t *ptr)
Definition: dhcp_handler.h:302
virtual ~DhcpHandler()
std::string parameters_
Definition: dhcp_handler.h:348
std::map< uint32_t, DhcpHandler::DhcpOptionCategory >::const_iterator Dhcpv4CategoryIter
Definition: dhcp_handler.h:357
uint8_t data[0]
Definition: dhcp_handler.h:257
void WriteByte(uint8_t c, uint16_t *optlen)
Definition: dhcp_handler.h:238
uint8_t out_msg_type_
Definition: dhcp_handler.h:346
uint8_t hlen
Definition: dhcp_handler.h:216
uint8_t file[DHCP_FILE_LEN]
Definition: dhcp_handler.h:227
DISALLOW_COPY_AND_ASSIGN(DhcpHandler)
dhcphdr * dhcp_
Definition: dhcp_handler.h:344
static const uint16_t kDhcpOptionFixedLen
Definition: dhcp_handler.h:280
uint16_t AddDomainNameOption(uint16_t opt_len)