|
1 | 1 | // This file is a part of the IncludeOS unikernel - www.includeos.org |
2 | 2 | // |
3 | | -// Copyright 2015 Oslo and Akershus University College of Applied Sciences |
| 3 | +// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences |
4 | 4 | // and Alfred Bratterud |
5 | 5 | // |
6 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); |
7 | 7 | // you may not use this file except in compliance with the License. |
8 | 8 | // You may obtain a copy of the License at |
9 | | -// |
| 9 | +// |
10 | 10 | // http://www.apache.org/licenses/LICENSE-2.0 |
11 | | -// |
| 11 | +// |
12 | 12 | // Unless required by applicable law or agreed to in writing, software |
13 | 13 | // distributed under the License is distributed on an "AS IS" BASIS, |
14 | 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | 15 | // See the License for the specific language governing permissions and |
16 | 16 | // limitations under the License. |
17 | 17 |
|
18 | | -#include <net/ip4/udp.hpp> |
19 | | - |
20 | 18 | #ifndef NET_DHCP_DHCP4_HPP |
21 | 19 | #define NET_DHCP_DHCP4_HPP |
22 | 20 |
|
23 | | -#define DHCP_VEND_LEN 304 |
24 | | -#define BOOTP_MIN_LEN 300 |
25 | | -#define DHCP_MIN_LEN 548 |
26 | | -// some clients silently ignore responses less than 300 bytes |
27 | | -#define DEFAULT_PACKET_SIZE 300 |
| 21 | +#include <net/ip4/udp.hpp> |
| 22 | + |
| 23 | +namespace net { |
| 24 | + |
| 25 | + static const int DHCP_VEND_LEN = 304; |
| 26 | + static const int BOOTP_MIN_LEN = 300; |
| 27 | + static const int DHCP_MIN_LEN = 548; |
| 28 | + // some clients silently ignore responses less than 300 bytes |
| 29 | + static const int DEFAULT_PACKET_SIZE = 300; |
28 | 30 |
|
29 | | -namespace net |
30 | | -{ |
31 | | - struct dhcp_packet_t |
32 | | - { |
33 | | - static const int CHADDR_LEN = 16; |
34 | | - static const int SNAME_LEN = 64; |
35 | | - static const int FILE_LEN = 128; |
36 | | - |
37 | | - uint8_t op; // message opcode |
38 | | - uint8_t htype; // hardware addr type |
39 | | - uint8_t hlen; // hardware addr length |
40 | | - uint8_t hops; // relay agent hops from client |
41 | | - uint32_t xid; // transaction ID |
42 | | - uint16_t secs; // seconds since start |
43 | | - uint16_t flags; // flag bits |
44 | | - IP4::addr ciaddr; // client IP address |
45 | | - IP4::addr yiaddr; // client IP address |
46 | | - IP4::addr siaddr; // IP address of next server |
47 | | - IP4::addr giaddr; // DHCP relay agent IP address |
48 | | - uint8_t chaddr[CHADDR_LEN]; // client hardware address |
49 | | - uint8_t sname[SNAME_LEN]; // server name |
50 | | - uint8_t file[FILE_LEN]; // BOOT filename |
51 | | - uint8_t magic[4]; // option_format aka magic |
52 | | - uint8_t options[DHCP_VEND_LEN]; |
53 | | - }; |
54 | | - |
55 | 31 | struct dhcp_option_t |
56 | 32 | { |
57 | 33 | uint8_t code; |
58 | 34 | uint8_t length; |
59 | 35 | uint8_t val[0]; |
60 | 36 | }; |
61 | | - |
62 | | -} |
| 37 | + |
| 38 | + struct dhcp_packet_t |
| 39 | + { |
| 40 | + static const uint8_t CHADDR_LEN = 16; |
| 41 | + static const uint8_t SNAME_LEN = 64; |
| 42 | + static const uint8_t FILE_LEN = 128; |
| 43 | + |
| 44 | + uint8_t op; // message opcode |
| 45 | + uint8_t htype; // hardware addr type |
| 46 | + uint8_t hlen; // hardware addr length |
| 47 | + uint8_t hops; // relay agent hops from client |
| 48 | + uint32_t xid; // transaction ID |
| 49 | + uint16_t secs; // seconds since start |
| 50 | + uint16_t flags; // flag bits |
| 51 | + IP4::addr ciaddr; // client IP address |
| 52 | + IP4::addr yiaddr; // client IP address |
| 53 | + IP4::addr siaddr; // IP address of next server |
| 54 | + IP4::addr giaddr; // DHCP relay agent IP address |
| 55 | + uint8_t chaddr[CHADDR_LEN]; // client hardware address |
| 56 | + uint8_t sname[SNAME_LEN]; // server name |
| 57 | + uint8_t file[FILE_LEN]; // BOOT filename |
| 58 | + uint8_t magic[4]; // option_format aka magic |
| 59 | + dhcp_option_t options[0]; |
| 60 | + }; |
| 61 | + |
| 62 | + static const uint16_t PACKET_SIZE = sizeof(dhcp_packet_t) + DHCP_VEND_LEN; |
| 63 | + |
| 64 | + // BOOTP (rfc951) message types |
| 65 | + static const uint8_t BOOTREQUEST = 1; |
| 66 | + static const uint8_t BOOTREPLY = 2; |
| 67 | + |
| 68 | + // Possible values for flags field |
| 69 | + static const uint32_t BOOTP_UNICAST = 0x0000; |
| 70 | + static const uint32_t BOOTP_BROADCAST = 0x0080; |
| 71 | + |
| 72 | + // Possible values for hardware type (htype) field |
| 73 | + static const uint8_t HTYPE_ETHER = 1; // Ethernet 10Mbps |
| 74 | + static const uint8_t HTYPE_IEEE802 = 6; // IEEE 802.2 Token Ring |
| 75 | + static const uint8_t HTYPE_FDDI = 8; // FDDI |
| 76 | + static const uint8_t HTYPE_HFI = 37; // HFI |
| 77 | + |
| 78 | + /* Magic cookie validating dhcp options field (and bootp vendor |
| 79 | + extensions field). */ |
| 80 | + static const std::string DHCP_OPTIONS_COOKIE = "\143\202\123\143"; |
| 81 | + |
| 82 | + // DHCP Option codes |
| 83 | + static const uint8_t DHO_PAD = 0; |
| 84 | + static const uint8_t DHO_SUBNET_MASK = 1; |
| 85 | + static const uint8_t DHO_TIME_OFFSET = 2; |
| 86 | + static const uint8_t DHO_ROUTERS = 3; |
| 87 | + static const uint8_t DHO_TIME_SERVERS = 4; |
| 88 | + static const uint8_t DHO_NAME_SERVERS = 5; |
| 89 | + static const uint8_t DHO_DOMAIN_NAME_SERVERS = 6; |
| 90 | + static const uint8_t DHO_LOG_SERVERS = 7; |
| 91 | + static const uint8_t DHO_COOKIE_SERVERS = 8; |
| 92 | + static const uint8_t DHO_LPR_SERVERS = 9; |
| 93 | + static const uint8_t DHO_IMPRESS_SERVERS = 10; |
| 94 | + static const uint8_t DHO_RESOURCE_LOCATION_SERVERS = 11; |
| 95 | + static const uint8_t DHO_HOST_NAME = 12; |
| 96 | + static const uint8_t DHO_BOOT_SIZE = 13; |
| 97 | + static const uint8_t DHO_MERIT_DUMP = 14; |
| 98 | + static const uint8_t DHO_DOMAIN_NAME = 15; |
| 99 | + static const uint8_t DHO_SWAP_SERVER = 16; |
| 100 | + static const uint8_t DHO_ROOT_PATH = 17; |
| 101 | + static const uint8_t DHO_EXTENSIONS_PATH = 18; |
| 102 | + static const uint8_t DHO_IP_FORWARDING = 19; |
| 103 | + static const uint8_t DHO_NON_LOCAL_SOURCE_ROUTING = 20; |
| 104 | + static const uint8_t DHO_POLICY_FILTER = 21; |
| 105 | + static const uint8_t DHO_MAX_DGRAM_REASSEMBLY = 22; |
| 106 | + static const uint8_t DHO_DEFAULT_IP_TTL = 23; |
| 107 | + static const uint8_t DHO_PATH_MTU_AGING_TIMEOUT = 24; |
| 108 | + static const uint8_t DHO_PATH_MTU_PLATEAU_TABLE = 25; |
| 109 | + static const uint8_t DHO_INTERFACE_MTU = 26; |
| 110 | + static const uint8_t DHO_ALL_SUBNETS_LOCAL = 27; |
| 111 | + static const uint8_t DHO_BROADCAST_ADDRESS = 28; |
| 112 | + static const uint8_t DHO_PERFORM_MASK_DISCOVERY = 29; |
| 113 | + static const uint8_t DHO_MASK_SUPPLIER = 30; |
| 114 | + static const uint8_t DHO_ROUTER_DISCOVERY = 31; |
| 115 | + static const uint8_t DHO_ROUTER_SOLICITATION_ADDRESS = 32; |
| 116 | + static const uint8_t DHO_STATIC_ROUTES = 33; |
| 117 | + static const uint8_t DHO_TRAILER_ENCAPSULATION = 34; |
| 118 | + static const uint8_t DHO_ARP_CACHE_TIMEOUT = 35; |
| 119 | + static const uint8_t DHO_IEEE802_3_ENCAPSULATION = 36; |
| 120 | + static const uint8_t DHO_DEFAULT_TCP_TTL = 37; |
| 121 | + static const uint8_t DHO_TCP_KEEPALIVE_INTERVAL = 38; |
| 122 | + static const uint8_t DHO_TCP_KEEPALIVE_GARBAGE = 39; |
| 123 | + static const uint8_t DHO_NIS_DOMAIN = 40; |
| 124 | + static const uint8_t DHO_NIS_SERVERS = 41; |
| 125 | + static const uint8_t DHO_NTP_SERVERS = 42; |
| 126 | + static const uint8_t DHO_VENDOR_ENCAPSULATED_OPTIONS = 43; |
| 127 | + static const uint8_t DHO_NETBIOS_NAME_SERVERS = 44; |
| 128 | + static const uint8_t DHO_NETBIOS_DD_SERVER = 45; |
| 129 | + static const uint8_t DHO_NETBIOS_NODE_TYPE = 46; |
| 130 | + static const uint8_t DHO_NETBIOS_SCOPE = 47; |
| 131 | + static const uint8_t DHO_FONT_SERVERS = 48; |
| 132 | + static const uint8_t DHO_X_DISPLAY_MANAGER = 49; |
| 133 | + static const uint8_t DHO_DHCP_REQUESTED_ADDRESS = 50; |
| 134 | + static const uint8_t DHO_DHCP_LEASE_TIME = 51; |
| 135 | + static const uint8_t DHO_DHCP_OPTION_OVERLOAD = 52; |
| 136 | + static const uint8_t DHO_DHCP_MESSAGE_TYPE = 53; |
| 137 | + static const uint8_t DHO_DHCP_SERVER_IDENTIFIER = 54; |
| 138 | + static const uint8_t DHO_DHCP_PARAMETER_REQUEST_LIST = 55; |
| 139 | + static const uint8_t DHO_DHCP_MESSAGE = 56; |
| 140 | + static const uint8_t DHO_DHCP_MAX_MESSAGE_SIZE = 57; |
| 141 | + static const uint8_t DHO_DHCP_RENEWAL_TIME = 58; |
| 142 | + static const uint8_t DHO_DHCP_REBINDING_TIME = 59; |
| 143 | + static const uint8_t DHO_VENDOR_CLASS_IDENTIFIER = 60; |
| 144 | + static const uint8_t DHO_DHCP_CLIENT_IDENTIFIER = 61; |
| 145 | + static const uint8_t DHO_NWIP_DOMAIN_NAME = 62; |
| 146 | + static const uint8_t DHO_NWIP_SUBOPTIONS = 63; |
| 147 | + static const uint8_t DHO_USER_CLASS = 77; |
| 148 | + static const uint8_t DHO_FQDN = 81; |
| 149 | + static const uint8_t DHO_DHCP_AGENT_OPTIONS = 82; |
| 150 | + static const uint8_t DHO_SUBNET_SELECTION = 118; // RFC3011 |
| 151 | + /* The DHO_AUTHENTICATE option is not a standard yet, so I've |
| 152 | + allocated an option out of the "local" option space for it on a |
| 153 | + temporary basis. Once an option code number is assigned, I will |
| 154 | + immediately and shamelessly break this, so don't count on it |
| 155 | + continuing to work. */ |
| 156 | + static const uint8_t DHO_AUTHENTICATE = 210; |
| 157 | + static const uint8_t DHO_END = 255; |
| 158 | + |
| 159 | + // DHCP message types |
| 160 | + static const uint8_t DHCPDISCOVER = 1; |
| 161 | + static const uint8_t DHCPOFFER = 2; |
| 162 | + static const uint8_t DHCPREQUEST = 3; |
| 163 | + static const uint8_t DHCPDECLINE = 4; |
| 164 | + static const uint8_t DHCPACK = 5; |
| 165 | + static const uint8_t DHCPNAK = 6; |
| 166 | + static const uint8_t DHCPRELEASE = 7; |
| 167 | + static const uint8_t DHCPINFORM = 8; |
| 168 | + |
| 169 | + // Relay Agent Information option subtypes |
| 170 | + static const uint8_t RAI_CIRCUIT_ID = 1; |
| 171 | + static const uint8_t RAI_REMOTE_ID = 2; |
| 172 | + static const uint8_t RAI_AGENT_ID = 3; |
| 173 | + |
| 174 | + // FQDN suboptions |
| 175 | + static const uint8_t FQDN_NO_CLIENT_UPDATE = 1; |
| 176 | + static const uint8_t FQDN_SERVER_UPDATE = 2; |
| 177 | + static const uint8_t FQDN_ENCODED = 3; |
| 178 | + static const uint8_t FQDN_RCODE1 = 4; |
| 179 | + static const uint8_t FQDN_RCODE2 = 5; |
| 180 | + static const uint8_t FQDN_HOSTNAME = 6; |
| 181 | + static const uint8_t FQDN_DOMAINNAME = 7; |
| 182 | + static const uint8_t FQDN_FQDN = 8; |
| 183 | + static const uint8_t FQDN_SUBOPTION_COUNT = 8; |
| 184 | + |
| 185 | + static const uint8_t ETH_ALEN = 6; // octets in one ethernet header |
| 186 | + static const uint8_t DHCP_SERVER_PORT = 67; |
| 187 | + static const uint8_t DHCP_CLIENT_PORT = 68; |
| 188 | + |
| 189 | + static inline dhcp_option_t* conv_option(dhcp_option_t* option, int offset) |
| 190 | + { |
| 191 | + return (dhcp_option_t*) ((char*) option + offset); |
| 192 | + } |
| 193 | + |
| 194 | + static inline const dhcp_option_t* get_option(const dhcp_option_t* opts, uint8_t code) |
| 195 | + { |
| 196 | + const dhcp_option_t* opt = opts; |
| 197 | + while (opt->code != code && opt->code != DHO_END) |
| 198 | + { |
| 199 | + // go to next option |
| 200 | + opt = (const dhcp_option_t*) (((const uint8_t*) opt) + 2 + opt->length); |
| 201 | + } |
| 202 | + return opt; |
| 203 | + } |
| 204 | + |
| 205 | +} // < namespace net |
63 | 206 |
|
64 | 207 | #endif |
0 commit comments