Style fix: f(x) is better than f((x))
[sliver-openvswitch.git] / lib / dhcp.h
1 /* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
2  * Junior University
3  *
4  * We are making the OpenFlow specification and associated documentation
5  * (Software) available for public use and benefit with the expectation
6  * that others will use, modify and enhance the Software and contribute
7  * those enhancements back to the community. However, since we would
8  * like to make the Software available for broadest use, with as few
9  * restrictions as possible permission is hereby granted, free of
10  * charge, to any person obtaining a copy of this Software to deal in
11  * the Software under the copyrights without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  *
29  * The name and trademarks of copyright holder(s) may NOT be used in
30  * advertising or publicity pertaining to the Software or any
31  * derivatives without specific, written prior permission.
32  */
33
34 #ifndef DHCP_H
35 #define DHCP_H 1
36
37 #include <stdint.h>
38 #include "packets.h"
39 #include "util.h"
40
41 struct ds;
42 struct ofpbuf;
43
44 /* Values for 'op' field. */
45 #define DHCP_BOOTREQUEST        1        /* Message sent by DHCP client. */
46 #define DHCP_BOOTREPLY          2        /* Message sent by DHCP server. */
47
48 /* Bits in 'flags' field. */
49 #define DHCP_FLAGS_BROADCAST    0x8000 /* Server must broadcast all replies. */
50 #define DHCP_FLAGS_MBZ          0x7fff /* Must be zero. */
51
52 /* First four bytes of 'options' field. */
53 #define DHCP_OPTS_COOKIE 0x63825363
54
55 #define DHCP_HEADER_LEN 236
56 struct dhcp_header {
57     uint8_t op;                 /* DHCP_BOOTREQUEST or DHCP_BOOTREPLY. */
58     uint8_t htype;              /* ARP_HRD_ETHERNET (typically). */
59     uint8_t hlen;               /* ETH_ADDR_LEN (typically). */
60     uint8_t hops;               /* Hop count; set to 0 by client. */
61     uint32_t xid;               /* Transaction ID. */
62     uint16_t secs;              /* Since client started address acquisition. */
63     uint16_t flags;             /* DHCP_FLAGS_*. */
64     uint32_t ciaddr;            /* Client IP, if it has a lease for one. */
65     uint32_t yiaddr;            /* Client ("your") IP address. */
66     uint32_t siaddr;            /* Next server IP address. */
67     uint32_t giaddr;            /* Relay agent IP address. */
68     uint8_t chaddr[16];         /* Client hardware address. */
69     char sname[64];             /* Optional server host name. */
70     char file[128];             /* Boot file name. */
71     /* Followed by variable-length options field. */
72 };
73 BUILD_ASSERT_DECL(DHCP_HEADER_LEN == sizeof(struct dhcp_header));
74
75 #define DHCP_ARGS                                                             \
76     DHCP_ARG(FIXED, 0)          /* Fixed-length option (PAD and END only). */ \
77     DHCP_ARG(IP, 4)             /* IP addresses. */                           \
78     DHCP_ARG(SECS, 4)           /* 32-bit duration in seconds. */             \
79     DHCP_ARG(STRING, 1)         /* NVT string, optionally null-terminated. */ \
80     DHCP_ARG(UINT8, 1)          /* 8-bit unsigned integer. */                 \
81     DHCP_ARG(UINT16, 2)         /* 16-bit unsigned integer. */                \
82     DHCP_ARG(UINT32, 4)         /* 32-bit unsigned integer. */                \
83     DHCP_ARG(BOOLEAN, 1)        /* Boolean octet (0 or 1). */
84
85 /* DHCP option argument types. */
86 enum dhcp_arg_type {
87 #define DHCP_ARG(NAME, SIZE) DHCP_ARG_##NAME,
88     DHCP_ARGS
89 #undef DHCP_ARG
90 };
91
92 #define DHCP_MSGS                                                             \
93     DHCP_MSG(DHCPDISCOVER, 1)   /* Client->server: What IPs are available? */ \
94     DHCP_MSG(DHCPOFFER, 2)      /* Server->client: This IP is available. */   \
95     DHCP_MSG(DHCPREQUEST, 3)    /* Client->server: I want that IP. */         \
96     DHCP_MSG(DHCPDECLINE, 4)    /* Client->server: That IP is in use!. */     \
97     DHCP_MSG(DHCPACK, 5)        /* Server->client: You can have that IP. */   \
98     DHCP_MSG(DHCPNAK, 6)        /* Server->client: You can't have that IP. */ \
99     DHCP_MSG(DHCPRELEASE, 7)    /* Client->server: I'm done with this IP. */  \
100     DHCP_MSG(DCHPINFORM, 8)     /* Client->server: I'm using this IP. */
101
102 /* DHCP message type (this is the argument for the DHCP_MSG_TYPE option). */
103 enum dhcp_msg_type {
104 #define DHCP_MSG(NAME, VALUE) NAME = VALUE,
105     DHCP_MSGS
106 #undef DHCP_MSG
107 };
108 const char *dhcp_type_name(enum dhcp_msg_type);
109
110 /* DHCP allows for 256 standardized options and 256 vendor-specific options.
111  * We put them in a single array, with the standard options at the
112  * beginning. */
113 #define DHCP_N_OPTIONS          512
114 #define DHCP_VENDOR_OFS         256
115
116 /* DHCP options. */
117 #define DHCP_OPTS                                                       \
118     /*                                        arg   min  max         */ \
119     /*          name                    code  type  args args        */ \
120     DHCP_OPT(PAD,                       0, FIXED,   0, 0)               \
121     DHCP_OPT(END,                     255, FIXED,   0, 0)               \
122     DHCP_OPT(SUBNET_MASK,               1, IP,      1, 1)               \
123     DHCP_OPT(TIME_OFFSET,               2, SECS,    1, 1)               \
124     DHCP_OPT(ROUTER,                    3, IP,      1, SIZE_MAX)        \
125     /* Time Server Option is obsolete. */                               \
126     /* Name Server Option is obsolete. */                               \
127     DHCP_OPT(DNS_SERVER,                6, IP,      1, SIZE_MAX)        \
128     /* Log Server Option is obsolete. */                                \
129     /* Cookie Server Option is obsolete. */                             \
130     DHCP_OPT(LPR_SERVER,                9, IP,      1, SIZE_MAX)        \
131     /* Impress Server Option is obsolete. */                            \
132     /* Resource Location Server Option is obsolete. */                  \
133     DHCP_OPT(HOST_NAME,                12, STRING,  1, SIZE_MAX)        \
134     DHCP_OPT(BOOT_FILE_SIZE,           13, UINT16,  1, 1)               \
135     /* Merit Dump File option is obsolete. */                           \
136     DHCP_OPT(DOMAIN_NAME,              15, STRING,  1, SIZE_MAX)        \
137     /* Swap Server option is obsolete. */                               \
138     DHCP_OPT(ROOT_PATH,                17, STRING,  1, SIZE_MAX)        \
139     DHCP_OPT(EXTENSIONS_PATH,          18, STRING,  1, SIZE_MAX)        \
140     DHCP_OPT(IP_FORWARDING,            19, BOOLEAN, 1, 1)               \
141     DHCP_OPT(SOURCE_ROUTING,           20, BOOLEAN, 1, 1)               \
142     DHCP_OPT(POLICY_FILTER,            21, IP,      2, SIZE_MAX)        \
143     DHCP_OPT(MAX_DGRAM_REASSEMBLY,     22, UINT16,  1, 1)               \
144     DHCP_OPT(IP_TTL,                   23, UINT8,   1, 1)               \
145     DHCP_OPT(PATH_MTU_TIMEOUT,         24, SECS,    1, 1)               \
146     DHCP_OPT(PATH_MTU_PLATEAU,         25, UINT16,  2, SIZE_MAX)        \
147     DHCP_OPT(MTU,                      26, UINT16,  1, 1)               \
148     DHCP_OPT(ALL_SUBNETS_ARE_LOCAL,    27, BOOLEAN, 1, 1)               \
149     DHCP_OPT(BROADCAST_ADDRESS,        28, IP,      1, 1)               \
150     DHCP_OPT(PERFORM_MASK_DISCOVERY,   29, BOOLEAN, 1, 1)               \
151     DHCP_OPT(MASK_SUPPLIER,            30, BOOLEAN, 1, 1)               \
152     DHCP_OPT(PERFORM_ROUTER_DISCOVERY, 31, BOOLEAN, 1, 1)               \
153     DHCP_OPT(ROUTER_SOLICITATION,      32, IP,      1, 1)               \
154     DHCP_OPT(STATIC_ROUTE,             33, IP,      2, SIZE_MAX)        \
155     /* Trailer Encapsulation Option is obsolete. */                     \
156     DHCP_OPT(ARP_CACHE_TIMEOUT,        35, SECS,    1, 1)               \
157     DHCP_OPT(ETHERNET_ENCAPSULATION,   36, BOOLEAN, 1, 1)               \
158     DHCP_OPT(TCP_TTL,                  37, UINT8,   1, 1)               \
159     DHCP_OPT(TCP_KEEPALIVE_INTERVAL,   38, SECS,    1, 1)               \
160     DHCP_OPT(TCP_KEEPALIVE_GARBAGE,    39, BOOLEAN, 1, 1)               \
161     DHCP_OPT(NIS_DOMAIN,               40, STRING,  1, SIZE_MAX)        \
162     DHCP_OPT(NIS_SERVERS,              41, IP,      1, SIZE_MAX)        \
163     DHCP_OPT(NTP_SERVERS,              42, IP,      1, SIZE_MAX)        \
164     DHCP_OPT(VENDOR_SPECIFIC,          43, UINT8,   1, SIZE_MAX)        \
165     DHCP_OPT(NETBIOS_NS,               44, IP,      1, SIZE_MAX)        \
166     DHCP_OPT(NETBIOS_DDS,              45, IP,      1, SIZE_MAX)        \
167     DHCP_OPT(NETBIOS_NODE_TYPE,        46, UINT8,   1, 1)               \
168     DHCP_OPT(NETBIOS_SCOPE,            47, STRING,  1, SIZE_MAX)        \
169     DHCP_OPT(X_FONT_SERVER,            48, IP,      1, SIZE_MAX)        \
170     DHCP_OPT(XDM,                      49, IP,      1, SIZE_MAX)        \
171     DHCP_OPT(NISPLUS_DOMAIN,           64, STRING,  1, SIZE_MAX)        \
172     DHCP_OPT(NISPLUS_SERVERS,          65, IP,      1, SIZE_MAX)        \
173     DHCP_OPT(MOBILE_IP_HOME_AGENT,     68, IP,      0, SIZE_MAX)        \
174     DHCP_OPT(SMTP_SERVER,              69, IP,      1, SIZE_MAX)        \
175     DHCP_OPT(POP3_SERVER,              70, IP,      1, SIZE_MAX)        \
176     DHCP_OPT(NNTP_SERVER,              71, IP,      1, SIZE_MAX)        \
177     DHCP_OPT(WWW_SERVER,               72, IP,      1, SIZE_MAX)        \
178     DHCP_OPT(FINGER_SERVER,            73, IP,      1, SIZE_MAX)        \
179     DHCP_OPT(IRC_SERVER,               74, IP,      1, SIZE_MAX)        \
180     /* StreetTalk Server Option is obsolete. */                         \
181     /* StreetTalk Directory Assistance Server Option is obsolete. */    \
182     DHCP_OPT(REQUESTED_IP,             50, IP,      1, 1)               \
183     DHCP_OPT(LEASE_TIME,               51, SECS,    1, 1)               \
184     DHCP_OPT(OPTION_OVERLOAD,          52, UINT8,   1, 1)               \
185     DHCP_OPT(TFTP_SERVER,              66, STRING,  1, SIZE_MAX)        \
186     DHCP_OPT(BOOTFILE_NAME,            67, STRING,  1, SIZE_MAX)        \
187     DHCP_OPT(DHCP_MSG_TYPE,            53, UINT8,   1, 1)               \
188     DHCP_OPT(SERVER_IDENTIFIER,        54, IP,      1, 1)               \
189     DHCP_OPT(PARAMETER_REQUEST_LIST,   55, UINT8,   1, SIZE_MAX)        \
190     DHCP_OPT(MESSAGE,                  56, STRING,  1, SIZE_MAX)        \
191     DHCP_OPT(MAX_DHCP_MSG_SIZE,        57, UINT16,  1, 1)               \
192     DHCP_OPT(T1,                       58, SECS,    1, 1)               \
193     DHCP_OPT(T2,                       59, SECS,    1, 1)               \
194     DHCP_OPT(VENDOR_CLASS,             60, STRING,  1, SIZE_MAX)        \
195     DHCP_OPT(CLIENT_ID,                61, UINT8,   2, SIZE_MAX)        \
196     DHCP_VNDOPT(OFP_CONTROLLER_VCONN,   1, STRING,  1, SIZE_MAX)        \
197     DHCP_VNDOPT(OFP_PKI_URI,            2, STRING,  1, SIZE_MAX)
198
199 /* Shorthand for defining vendor options (used above). */
200 #define DHCP_VNDOPT(NAME, CODE, ARG, MIN, MAX) \
201     DHCP_OPT(NAME, (CODE) + DHCP_VENDOR_OFS, ARG, MIN, MAX)
202
203 /* DHCP option codes. */
204 enum {
205 #define DHCP_OPT(NAME, VALUE, ARGTYPE, MIN_ARGS, MAX_ARGS) \
206     DHCP_CODE_##NAME = VALUE,
207 DHCP_OPTS
208 #undef DHCP_OPT
209 };
210
211 /* The contents of a DHCP option.
212  *
213  * DHCP options can (rarely) be present but lack content.  To represent such an
214  * option, 'n' is 0 and 'data' is non-null (but does not point to anything
215  * useful).  */
216 struct dhcp_option {
217     size_t n;                   /* Number of bytes of data. */
218     void *data;                 /* Data. */
219 };
220
221 const char *dhcp_option_to_string(const struct dhcp_option *, int code,
222                                   struct ds *);
223 bool dhcp_option_equals(const struct dhcp_option *,
224                         const struct dhcp_option *);
225
226 /* Abstracted DHCP protocol message, to make them easier to manipulate than
227  * through raw protocol buffers. */
228 struct dhcp_msg {
229     /* For use by calling code. */
230     uint8_t op;                 /* DHCP_BOOTREQUEST or DHCP_BOOTREPLY. */
231     uint32_t xid;               /* Transaction ID. */
232     uint16_t secs;              /* Since client started address acquisition. */
233     uint16_t flags;             /* DHCP_FLAGS_*. */
234     uint32_t ciaddr;            /* Client IP, if it has a lease for one. */
235     uint32_t yiaddr;            /* Client ("your") IP address. */
236     uint32_t siaddr;            /* Next server IP address. */
237     uint32_t giaddr;            /* Relay agent IP address. */
238     uint8_t chaddr[ETH_ADDR_LEN]; /* Client hardware address. */
239     enum dhcp_msg_type type;    /* DHCP_CODE_DHCP_MSG_TYPE option argument. */
240     struct dhcp_option options[DHCP_N_OPTIONS]; /* Indexed by option code. */
241
242     /* For direct use only by dhcp_msg_*() functions. */
243     uint8_t *data;
244     size_t data_used, data_allocated;
245 };
246
247 void dhcp_msg_init(struct dhcp_msg *);
248 void dhcp_msg_uninit(struct dhcp_msg *);
249 void dhcp_msg_copy(struct dhcp_msg *, const struct dhcp_msg *);
250 void dhcp_msg_put(struct dhcp_msg *, int code, const void *, size_t);
251 void dhcp_msg_put_bool(struct dhcp_msg *, int code, bool);
252 void dhcp_msg_put_secs(struct dhcp_msg *, int code, uint32_t);
253 void dhcp_msg_put_ip(struct dhcp_msg *, int code, uint32_t);
254 void dhcp_msg_put_string(struct dhcp_msg *, int code, const char *);
255 void dhcp_msg_put_uint8(struct dhcp_msg *, int code, uint8_t);
256 void dhcp_msg_put_uint8_array(struct dhcp_msg *, int code,
257                               const uint8_t[], size_t n);
258 void dhcp_msg_put_uint16(struct dhcp_msg *, int code, uint16_t);
259 void dhcp_msg_put_uint16_array(struct dhcp_msg *, int code,
260                                const uint16_t[], size_t n);
261 const void *dhcp_msg_get(const struct dhcp_msg *, int code, size_t offset,
262                          size_t size);
263 bool dhcp_msg_get_bool(const struct dhcp_msg *, int code,
264                        size_t offset, bool *);
265 bool dhcp_msg_get_secs(const struct dhcp_msg *, int code,
266                        size_t offset, uint32_t *);
267 bool dhcp_msg_get_ip(const struct dhcp_msg *, int code,
268                      size_t offset, uint32_t *);
269 char *dhcp_msg_get_string(const struct dhcp_msg *, int code);
270 bool dhcp_msg_get_uint8(const struct dhcp_msg *, int code,
271                         size_t offset, uint8_t *);
272 bool dhcp_msg_get_uint16(const struct dhcp_msg *, int code,
273                          size_t offset, uint16_t *);
274 const char *dhcp_msg_to_string(const struct dhcp_msg *, bool multiline,
275                                struct ds *);
276 int dhcp_parse(struct dhcp_msg *, const struct ofpbuf *);
277 void dhcp_assemble(const struct dhcp_msg *, struct ofpbuf *);
278
279 #endif /* dhcp.h */