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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt