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