Line data Source code
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; 225 : uint8_t chaddr[DHCP_CHADDR_LEN]; 226 : uint8_t sname[DHCP_NAME_LEN]; 227 : uint8_t file[DHCP_FILE_LEN]; 228 : uint8_t options[DHCP_MAX_OPTION_LEN]; 229 : }; 230 : 231 : struct Dhcpv4Options { 232 0 : void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen) { 233 0 : code = c; 234 0 : len = l; 235 0 : memcpy(data, (uint8_t *)d, l); 236 0 : *optlen += 2 + l; 237 0 : } 238 0 : void WriteByte(uint8_t c, uint16_t *optlen) { 239 0 : code = c; 240 0 : *optlen += 1; 241 0 : } 242 0 : void AppendData(uint16_t l, const void *d, uint16_t *optlen) { 243 0 : memcpy(data + len, (uint8_t *)d, l); 244 0 : len += l; 245 0 : *optlen += l; 246 0 : } 247 0 : Dhcpv4Options *GetNextOptionPtr() { 248 0 : uint8_t *next = reinterpret_cast<uint8_t *>(this); 249 0 : if (code == DHCP_OPTION_PAD || code == DHCP_OPTION_END) 250 0 : return reinterpret_cast<Dhcpv4Options *>(next + 1); 251 : else 252 0 : 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 : 264 : struct DhcpRequestData { 265 0 : DhcpRequestData() : xid(-1), flags(0), mac_addr(), ip_addr(0) { 266 0 : } 267 0 : void UpdateData(uint32_t id, uint16_t fl, uint8_t *mac) { 268 0 : xid = id; 269 0 : flags = fl; 270 0 : mac_addr = mac; 271 0 : } 272 : 273 : uint32_t xid; 274 : uint16_t flags; 275 : MacAddress mac_addr; 276 : in_addr_t ip_addr; 277 : }; 278 : 279 : struct Dhcpv4OptionHandler : DhcpOptionHandler { 280 : static const uint16_t kDhcpOptionFixedLen = 2; 281 : 282 0 : explicit Dhcpv4OptionHandler(uint8_t *ptr) { dhcp_option_ptr = ptr; } 283 0 : void WriteData(uint8_t c, uint8_t l, const void *d, uint16_t *optlen) { 284 0 : option->WriteData(c, l, d, optlen); 285 0 : } 286 : void WriteByte(uint8_t c, uint16_t *optlen) { 287 : option->WriteByte(c, optlen); 288 : } 289 0 : void AppendData(uint16_t l, const void *d, uint16_t *optlen) { 290 0 : option->AppendData(l, d, optlen); 291 0 : } 292 0 : uint16_t GetCode() const { return option->code; } 293 0 : uint16_t GetLen() const { return option->len; } 294 0 : uint16_t GetFixedLen() const { return kDhcpOptionFixedLen; } 295 0 : uint8_t *GetData() { return option->data; } 296 0 : void SetCode(uint16_t c) { option->code = (uint8_t) c; } 297 0 : void SetLen(uint16_t l) { option->len = (uint8_t) l; } 298 0 : void AddLen(uint16_t l) { option->len += (uint8_t) l; } 299 0 : void SetNextOptionPtr(uint16_t optlen) { 300 0 : option = (Dhcpv4Options *)(dhcp_option_ptr + optlen); 301 0 : } 302 0 : 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); 319 : bool GetGatewayInterfaceLease(); 320 : void ReleaseGatewayInterfaceLease(); 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(); 327 : bool CreateRelayResponsePacket(); 328 : void RelayRequestToFabric(); 329 : void RelayResponseFromFabric(); 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 : 344 : dhcphdr *dhcp_; 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_; 350 : DhcpRequestData request_; 351 : DISALLOW_COPY_AND_ASSIGN(DhcpHandler); 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