• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/odhcp6c/src/odhcp6c.h

  1 /**
  2  * Copyright (C) 2012-2014 Steven Barth <steven@midlink.org>
  3  * Copyright (C) 2018 Hans Dedecker <dedeckeh@gmail.com>
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License v2 as published by
  7  * the Free Software Foundation.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU General Public License for more details.
 13  *
 14  */
 15 
 16 #ifndef _ODHCP6C_H_
 17 #define _ODHCP6C_H_
 18 
 19 #include <netinet/in.h>
 20 #include <stdbool.h>
 21 #include <stdint.h>
 22 
 23 #define _unused __attribute__((unused))
 24 #define _packed __attribute__((packed))
 25 #define _aligned(n) __attribute__((aligned(n)))
 26 
 27 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
 28 
 29 #define ND_OPT_RECURSIVE_DNS 25
 30 #define ND_OPT_DNSSL 31
 31 
 32 #define DHCPV6_MAX_DELAY 1
 33 #define DHCPV6_IRT_DEFAULT 86400
 34 #define DHCPV6_IRT_MIN 600
 35 #define DHCPV6_RAND_FACTOR 100
 36 
 37 #define DHCPV6_SOL_INIT_RT 1
 38 #define DHCPV6_SOL_MAX_RT 120
 39 
 40 #define DHCPV6_REQ_INIT_RT 1
 41 #define DHCPV6_REQ_MAX_RT 30
 42 #define DHCPV6_REQ_MAX_RC 10
 43 
 44 #define DHCPV6_REN_INIT_RT 10
 45 #define DHCPV6_REN_MAX_RT 600
 46 
 47 #define DHCPV6_REB_INIT_RT 10
 48 #define DHCPV6_REB_MAX_RT 600
 49 
 50 #define DHCPV6_INF_INIT_RT 1
 51 #define DHCPV6_INF_MAX_RT 3600
 52 
 53 #define DHCPV6_REL_INIT_RT 1
 54 #define DHCPV6_REL_MAX_RC 4
 55 
 56 #define DHCPV6_DEC_INIT_RT 1
 57 #define DHCPV6_DEC_MAX_RC 4
 58 
 59 #define RA_MIN_ADV_INTERVAL 3   /* RFC 4861 paragraph 6.2.1 */
 60 
 61 enum dhcvp6_opt {
 62         DHCPV6_OPT_CLIENTID = 1,
 63         DHCPV6_OPT_SERVERID = 2,
 64         DHCPV6_OPT_IA_NA = 3,
 65         DHCPV6_OPT_IA_TA = 4,
 66         DHCPV6_OPT_IA_ADDR = 5,
 67         DHCPV6_OPT_ORO = 6,
 68         DHCPV6_OPT_PREF = 7,
 69         DHCPV6_OPT_ELAPSED = 8,
 70         DHCPV6_OPT_RELAY_MSG = 9,
 71         DHCPV6_OPT_AUTH = 11,
 72         DHCPV6_OPT_UNICAST = 12,
 73         DHCPV6_OPT_STATUS = 13,
 74         DHCPV6_OPT_RAPID_COMMIT = 14,
 75         DHCPV6_OPT_USER_CLASS = 15,
 76         DHCPV6_OPT_VENDOR_CLASS = 16,
 77         DHCPV6_OPT_INTERFACE_ID = 18,
 78         DHCPV6_OPT_RECONF_MESSAGE = 19,
 79         DHCPV6_OPT_RECONF_ACCEPT = 20,
 80         DHCPV6_OPT_SIP_SERVER_D = 21,
 81         DHCPV6_OPT_SIP_SERVER_A = 22,
 82         DHCPV6_OPT_DNS_SERVERS = 23,
 83         DHCPV6_OPT_DNS_DOMAIN = 24,
 84         DHCPV6_OPT_IA_PD = 25,
 85         DHCPV6_OPT_IA_PREFIX = 26,
 86         DHCPV6_OPT_SNTP_SERVERS = 31,
 87         DHCPV6_OPT_INFO_REFRESH = 32,
 88         DHCPV6_OPT_REMOTE_ID = 37,
 89         DHCPV6_OPT_SUBSCRIBER_ID = 38,
 90         DHCPV6_OPT_FQDN = 39,
 91         DHCPV6_OPT_ERO = 43,
 92         DHCPV6_OPT_LQ_QUERY = 44,
 93         DHCPV6_OPT_CLIENT_DATA = 45,
 94         DHCPV6_OPT_CLT_TIME = 46,
 95         DHCPV6_OPT_LQ_RELAY_DATA = 47,
 96         DHCPV6_OPT_LQ_CLIENT_LINK = 48,
 97         DHCPV6_OPT_RELAY_ID = 53,
 98         DHCPV6_OPT_NTP_SERVER = 56,
 99         DHCPV6_OPT_CLIENT_ARCH_TYPE = 61,
100         DHCPV6_OPT_AFTR_NAME = 64,
101         DHCPV6_OPT_RSOO = 66,
102         DHCPV6_OPT_PD_EXCLUDE = 67,
103         DHCPV6_OPT_VSS = 68,
104         DHCPV6_OPT_LINK_LAYER_ADDRESS = 79,
105         DHCPV6_OPT_LINK_ADDRESS = 80,
106         DHCPV6_OPT_RADIUS = 81,
107         DHCPV6_OPT_SOL_MAX_RT = 82,
108         DHCPV6_OPT_INF_MAX_RT = 83,
109 #ifdef EXT_CER_ID
110         /* draft-donley-dhc-cer-id-option-03 */
111         DHCPV6_OPT_CER_ID = EXT_CER_ID,
112 #endif
113         DHCPV6_OPT_DHCPV4_MSG = 87,
114         /* RFC 7598 */
115         DHCPV6_OPT_S46_RULE = 89,
116         DHCPV6_OPT_S46_BR = 90,
117         DHCPV6_OPT_S46_DMR = 91,
118         DHCPV6_OPT_S46_V4V6BIND = 92,
119         DHCPV6_OPT_S46_PORTPARAMS = 93,
120         DHCPV6_OPT_S46_CONT_MAPE = 94,
121         DHCPV6_OPT_S46_CONT_MAPT = 95,
122         DHCPV6_OPT_S46_CONT_LW = 96,
123         DHCPV6_OPT_LQ_BASE_TIME = 100,
124         DHCPV6_OPT_LQ_START_TIME = 101,
125         DHCPV6_OPT_LQ_END_TIME = 102,
126         DHCPV6_OPT_ANI_ATT = 105,
127         DHCPV6_OPT_ANI_NETWORK_NAME = 106,
128         DHCPV6_OPT_ANI_AP_NAME = 107,
129         DHCPV6_OPT_ANI_AP_BSSID = 108,
130         DHCPV6_OPT_ANI_OPERATOR_ID = 109,
131         DHCPV6_OPT_ANI_OPERATOR_REALM = 110,
132         DHCPV6_OPT_MUD_URL_V6 = 112,
133         DHCPV6_OPT_F_BINDING_STATUS = 114,
134         DHCPV6_OPT_F_CONNECT_FLAGS = 115,
135         DHCPV6_OPT_F_DNS_REMOVAL_INFO = 116,
136         DHCPV6_OPT_F_DNS_HOST_NAME = 117,
137         DHCPV6_OPT_F_DNS_ZONE_NAME = 118,
138         DHCPV6_OPT_F_DNS_FLAGS = 119,
139         DHCPV6_OPT_F_EXPIRATION_TIME = 120,
140         DHCPV6_OPT_F_MAX_UNACKED_BNDUPD = 121,
141         DHCPV6_OPT_F_MCLT = 122,
142         DHCPV6_OPT_F_PARTNER_LIFETIME = 123,
143         DHCPV6_OPT_F_PARTNER_LIFETIME_SENT = 124,
144         DHCPV6_OPT_F_PARTNER_DOWN_TIME = 125,
145         DHCPV6_OPT_F_PARTNER_RAW_CLT_TIME = 126,
146         DHCPV6_OPT_F_PROTOCOL_VERSION = 127,
147         DHCPV6_OPT_F_KEEPALIVE_TIME = 128,
148         DHCPV6_OPT_F_RECONFIGURE_DATA = 129,
149         DHCPV6_OPT_F_RELATIONSHIP_NAME = 130,
150         DHCPV6_OPT_F_SERVER_FLAGS = 131,
151         DHCPV6_OPT_F_SERVER_STATE = 132,
152         DHCPV6_OPT_F_START_TIME_OF_STATE = 133,
153         DHCPV6_OPT_F_STATE_EXPIRATION_TIME  = 134,
154         DHCPV6_OPT_RELAY_PORT = 135,
155 };
156 
157 enum dhcpv6_opt_npt {
158         NTP_SRV_ADDR = 1,
159         NTP_MC_ADDR = 2,
160         NTP_SRV_FQDN = 3
161 };
162 
163 enum dhcpv6_msg {
164         DHCPV6_MSG_UNKNOWN = 0,
165         DHCPV6_MSG_SOLICIT = 1,
166         DHCPV6_MSG_ADVERT = 2,
167         DHCPV6_MSG_REQUEST = 3,
168         DHCPV6_MSG_RENEW = 5,
169         DHCPV6_MSG_REBIND = 6,
170         DHCPV6_MSG_REPLY = 7,
171         DHCPV6_MSG_RELEASE = 8,
172         DHCPV6_MSG_DECLINE = 9,
173         DHCPV6_MSG_RECONF = 10,
174         DHCPV6_MSG_INFO_REQ = 11,
175         _DHCPV6_MSG_MAX
176 };
177 
178 enum dhcpv6_state {
179         DHCPV6_INIT,
180         DHCPV6_SOLICIT,
181         DHCPV6_SOLICIT_PROCESSING,
182         DHCPV6_ADVERT,
183         DHCPV6_REQUEST,
184         DHCPV6_REQUEST_PROCESSING,
185         DHCPV6_REPLY,
186         DHCPV6_BOUND,
187         DHCPV6_BOUND_PROCESSING,
188         DHCPV6_BOUND_REPLY,
189         DHCPV6_RECONF,
190         DHCPV6_RECONF_PROCESSING,
191         DHCPV6_RECONF_REPLY,
192         DHCPV6_RENEW,
193         DHCPV6_RENEW_PROCESSING,
194         DHCPV6_RENEW_REPLY,
195         DHCPV6_REBIND,
196         DHCPV6_REBIND_PROCESSING,
197         DHCPV6_REBIND_REPLY,
198         DHCPV6_INFO,
199         DHCPV6_INFO_PROCESSING,
200         DHCPV6_INFO_REPLY,
201         DHCPV6_EXIT,
202         DHCPV6_RESET
203 };
204 
205 enum dhcpv6_status {
206         DHCPV6_Success = 0,
207         DHCPV6_UnspecFail = 1,
208         DHCPV6_NoAddrsAvail = 2,
209         DHCPV6_NoBinding = 3,
210         DHCPV6_NotOnLink = 4,
211         DHCPV6_UseMulticast = 5,
212         DHCPV6_NoPrefixAvail = 6,
213         _DHCPV6_Status_Max
214 };
215 
216 enum dhcpv6_config {
217         DHCPV6_STRICT_OPTIONS = 1,
218         DHCPV6_CLIENT_FQDN = 2,
219         DHCPV6_ACCEPT_RECONFIGURE = 4,
220         DHCPV6_IGNORE_OPT_UNICAST = 8,
221 };
222 
223 typedef int(reply_handler)(enum dhcpv6_msg orig, const int rc,
224                 const void *opt, const void *end, const struct sockaddr_in6 *from);
225 
226 // retransmission strategy
227 struct dhcpv6_retx {
228         uint8_t max_delay;
229         uint8_t init_timeo;
230         uint16_t max_timeo;
231         uint8_t max_rc;
232         char name[8];
233         reply_handler *handler_reply;
234         int(*handler_finish)(void);
235         bool is_retransmit;
236         uint64_t timeout;
237         uint8_t rc;
238         uint64_t start;
239         uint8_t tr_id[3];
240         int64_t rto;
241         uint64_t round_start;
242         uint64_t round_end;
243         int reply_ret;
244         uint64_t delay_msec;
245 };
246 
247 // DHCPv6 Protocol Headers
248 struct dhcpv6_header {
249         uint8_t msg_type;
250         uint8_t tr_id[3];
251 } __attribute__((packed));
252 
253 struct dhcpv6_ia_hdr {
254         uint16_t type;
255         uint16_t len;
256         uint32_t iaid;
257         uint32_t t1;
258         uint32_t t2;
259 } _packed;
260 
261 struct dhcpv6_ia_addr {
262         uint16_t type;
263         uint16_t len;
264         struct in6_addr addr;
265         uint32_t preferred;
266         uint32_t valid;
267 } _packed;
268 
269 struct dhcpv6_ia_prefix {
270         uint16_t type;
271         uint16_t len;
272         uint32_t preferred;
273         uint32_t valid;
274         uint8_t prefix;
275         struct in6_addr addr;
276 } _packed;
277 
278 struct dhcpv6_duid {
279         uint16_t type;
280         uint16_t len;
281         uint16_t duid_type;
282         uint8_t data[128];
283 } _packed;
284 
285 struct dhcpv6_auth {
286         uint16_t type;
287         uint16_t len;
288         uint8_t protocol;
289         uint8_t algorithm;
290         uint8_t rdm;
291         uint64_t replay;
292         uint8_t data[];
293 } _packed;
294 
295 struct dhcpv6_auth_reconfigure {
296         uint8_t reconf_type;
297         uint8_t key[16];
298 } _packed;
299 
300 struct dhcpv6_cer_id {
301         uint16_t type;
302         uint16_t len;
303         struct in6_addr addr;
304 } _packed;
305 
306 struct dhcpv6_s46_portparams {
307         uint8_t offset;
308         uint8_t psid_len;
309         uint16_t psid;
310 } _packed;
311 
312 struct dhcpv6_s46_v4v6bind {
313         struct in_addr ipv4_address;
314         uint8_t bindprefix6_len;
315         uint8_t bind_ipv6_prefix[];
316 } _packed;
317 
318 struct dhcpv6_s46_dmr {
319         uint8_t dmr_prefix6_len;
320         uint8_t dmr_ipv6_prefix[];
321 } _packed;
322 
323 struct dhcpv6_s46_rule {
324         uint8_t flags;
325         uint8_t ea_len;
326         uint8_t prefix4_len;
327         struct in_addr ipv4_prefix;
328         uint8_t prefix6_len;
329         uint8_t ipv6_prefix[];
330 } _packed;
331 
332 #define dhcpv6_for_each_option(start, end, otype, olen, odata)\
333         for (uint8_t *_o = (uint8_t*)(start); _o + 4 <= (uint8_t*)(end) &&\
334                 ((otype) = _o[0] << 8 | _o[1]) && ((odata) = (void*)&_o[4]) &&\
335                 ((olen) = _o[2] << 8 | _o[3]) + (odata) <= (uint8_t*)(end); \
336                 _o += 4 + (_o[2] << 8 | _o[3]))
337 
338 
339 struct dhcpv6_server_cand {
340         bool has_noaddravail;
341         bool wants_reconfigure;
342         int16_t preference;
343         uint8_t duid_len;
344         uint8_t duid[130];
345         struct in6_addr server_addr;
346         uint32_t sol_max_rt;
347         uint32_t inf_max_rt;
348         void *ia_na;
349         void *ia_pd;
350         size_t ia_na_len;
351         size_t ia_pd_len;
352 };
353 
354 struct dhcpv6_stats {
355         uint64_t solicit;
356         uint64_t advertise;
357         uint64_t request;
358         uint64_t confirm;
359         uint64_t renew;
360         uint64_t rebind;
361         uint64_t reply;
362         uint64_t release;
363         uint64_t decline;
364         uint64_t reconfigure;
365         uint64_t information_request;
366         uint64_t discarded_packets;
367         uint64_t transmit_failures;
368 };
369 
370 enum odhcp6c_state {
371         STATE_CLIENT_ID,
372         STATE_SERVER_ID,
373         STATE_SERVER_CAND,
374         STATE_SERVER_ADDR,
375         STATE_ORO,
376         STATE_DNS,
377         STATE_SEARCH,
378         STATE_IA_NA,
379         STATE_IA_PD,
380         STATE_IA_PD_INIT,
381         STATE_CUSTOM_OPTS,
382         STATE_SNTP_IP,
383         STATE_NTP_IP,
384         STATE_NTP_FQDN,
385         STATE_SIP_IP,
386         STATE_SIP_FQDN,
387         STATE_RA_ROUTE,
388         STATE_RA_PREFIX,
389         STATE_RA_DNS,
390         STATE_RA_SEARCH,
391         STATE_AFTR_NAME,
392         STATE_OPTS,
393         STATE_CER,
394         STATE_S46_MAPT,
395         STATE_S46_MAPE,
396         STATE_S46_LW,
397         STATE_PASSTHRU,
398         _STATE_MAX
399 };
400 
401 struct icmp6_opt {
402         uint8_t type;
403         uint8_t len;
404         uint8_t data[6];
405 };
406 
407 
408 enum dhcpv6_mode {
409         DHCPV6_UNKNOWN = -1,
410         DHCPV6_STATELESS,
411         DHCPV6_STATEFUL
412 };
413 
414 enum ra_config {
415         RA_RDNSS_DEFAULT_LIFETIME = 1,
416 };
417 
418 enum odhcp6c_ia_mode {
419         IA_MODE_NONE,
420         IA_MODE_TRY,
421         IA_MODE_FORCE,
422 };
423 
424 enum odhcp6c_auth_protocol {
425         AUTH_PROT_NONE = -1,
426         /* RFC3118 */
427         AUTH_PROT_TOKEN = 0,
428         /* draft-ietf-dhc-rfc8415bis-12 */
429         AUTH_PROT_RKAP = 3,
430 };
431 
432 enum odhcp6c_auth_algorithm {
433         /* RFC3118 */
434         AUTH_ALG_TOKEN = 0,
435         /* draft-ietf-dhc-rfc8415bis-12 */
436         AUTH_ALG_HMACMD5 = 1
437 };
438 
439 enum odhcp6c_rkap_type {
440         /* draft-ietf-dhc-rfc8415bis-12 */
441         RKAP_TYPE_KEY = 1,
442         RKAP_TYPE_HMACMD5 = 2,
443 };
444 
445 struct odhcp6c_entry {
446         struct in6_addr router;
447         uint8_t auxlen;
448         uint8_t length;
449         struct in6_addr target;
450         int16_t priority;
451         uint32_t valid;
452         uint32_t preferred;
453         uint32_t t1;
454         uint32_t t2;
455         uint32_t iaid;
456         uint8_t auxtarget[];
457 };
458 
459 // Include padding after auxtarget to align the next entry
460 #define odhcp6c_entry_size(entry) \
461         (sizeof(struct odhcp6c_entry) + (((entry)->auxlen + 3) & ~3))
462 
463 #define odhcp6c_next_entry(entry) \
464         ((struct odhcp6c_entry *)((uint8_t *)(entry) + odhcp6c_entry_size(entry)))
465 
466 
467 struct odhcp6c_request_prefix {
468         uint32_t iaid;
469         uint8_t length;
470         struct in6_addr addr;
471 };
472 
473 enum odhcp6c_opt_flags {
474         OPT_U8 = 0,
475         OPT_IP6,
476         OPT_STR,
477         OPT_DNS_STR,
478         OPT_USER_CLASS,
479         OPT_MASK_SIZE = 0x0F,
480         OPT_ARRAY = 0x10,
481         OPT_INTERNAL = 0x20,
482         OPT_NO_PASSTHRU = 0x40,
483         OPT_ORO = 0x80,
484         OPT_ORO_STATEFUL = 0x100,
485         OPT_ORO_STATELESS = 0x200,
486         OPT_ORO_SOLICIT = 0x400
487 };
488 
489 struct odhcp6c_opt {
490         uint16_t code;
491         uint16_t flags;
492         const char *str;
493 };
494 
495 int init_dhcpv6(const char *ifname);
496 int dhcpv6_get_ia_mode(void);
497 int dhcpv6_promote_server_cand(void);
498 int dhcpv6_send_request(enum dhcpv6_msg type);
499 int dhcpv6_receive_response(enum dhcpv6_msg type);
500 enum dhcpv6_state dhcpv6_get_state(void);
501 void dhcpv6_set_state(enum dhcpv6_state state);
502 int dhcpv6_get_socket(void);
503 struct dhcpv6_stats dhcpv6_get_stats(void);
504 void dhcpv6_reset_stats(void);
505 int dhcpv6_state_processing(enum dhcpv6_msg type);
506 int dhcpv6_get_state_timeout(void);
507 void dhcpv6_set_state_timeout(int timeout);
508 void dhcpv6_reset_state_timeout(void);
509 const char *dhcpv6_state_to_str(enum dhcpv6_state state);
510 
511 int init_rtnetlink(void);
512 int set_rtnetlink_addr(int ifindex, const struct in6_addr *addr,
513                 uint32_t pref, uint32_t valid);
514 
515 int ra_get_hoplimit(void);
516 int ra_get_mtu(void);
517 int ra_get_reachable(void);
518 int ra_get_retransmit(void);
519 
520 void notify_state_change(const char *status, int delay, bool resume);
521 
522 int script_init(const char *path, const char *ifname);
523 ssize_t script_unhexlify(uint8_t *dst, size_t len, const char *src);
524 void script_hexlify(char *dst, const uint8_t *src, size_t len);
525 void script_call(const char *status, int delay, bool resume);
526 
527 bool odhcp6c_signal_process(void);
528 uint64_t odhcp6c_get_milli_time(void);
529 int odhcp6c_random(void *buf, size_t len);
530 bool odhcp6c_is_bound(void);
531 bool odhcp6c_addr_in_scope(const struct in6_addr *addr);
532 
533 // State manipulation
534 void odhcp6c_clear_state(enum odhcp6c_state state);
535 int odhcp6c_add_state(enum odhcp6c_state state, const void *data, size_t len);
536 void odhcp6c_append_state(enum odhcp6c_state state, const void *data, size_t len);
537 int odhcp6c_insert_state(enum odhcp6c_state state, size_t offset, const void *data, size_t len);
538 size_t odhcp6c_remove_state(enum odhcp6c_state state, size_t offset, size_t len);
539 void* odhcp6c_move_state(enum odhcp6c_state state, size_t *len);
540 void* odhcp6c_get_state(enum odhcp6c_state state, size_t *len);
541 
542 // Entry manipulation
543 bool odhcp6c_update_entry(enum odhcp6c_state state, struct odhcp6c_entry *new,
544                                 uint32_t safe, unsigned int holdoff_interval);
545 
546 void odhcp6c_expire(bool expire_ia_pd);
547 uint32_t odhcp6c_elapsed(void);
548 struct odhcp6c_opt *odhcp6c_find_opt(const uint16_t code);
549 struct odhcp6c_opt *odhcp6c_find_opt_by_name(const char *name);
550 
551 #endif /* _ODHCP6C_H_ */
552 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt