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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt