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

Sources/odhcpd/src/odhcpd.h

  1 /**
  2  * Copyright (C) 2012-2013 Steven Barth <steven@midlink.org>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License v2 as published by
  6  * the Free Software Foundation.
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11  * GNU General Public License for more details.
 12  *
 13  */
 14 
 15 #pragma once
 16 #include <netinet/in.h>
 17 #include <netinet/icmp6.h>
 18 #include <netinet/ether.h>
 19 #include <stdbool.h>
 20 #include <syslog.h>
 21 
 22 #include <libubox/blobmsg.h>
 23 #include <libubox/list.h>
 24 #include <libubox/uloop.h>
 25 #include <libubox/avl.h>
 26 #include <libubox/ustream.h>
 27 #include <libubox/vlist.h>
 28 
 29 #define min(a, b) (((a) < (b)) ? (a) : (b))
 30 #define max(a, b) (((a) > (b)) ? (a) : (b))
 31 
 32 /* RFC 1035, §2.3.4, with one extra byte for buffers */
 33 #define DNS_MAX_NAME_LEN 256
 34 #define DNS_MAX_LABEL_LEN 63
 35 
 36 // RFC 6106 defines this router advertisement option
 37 #define ND_OPT_ROUTE_INFO 24
 38 #define ND_OPT_RECURSIVE_DNS 25
 39 #define ND_OPT_DNS_SEARCH 31
 40 
 41 // RFC 8781 defines PREF64 option
 42 #define ND_OPT_PREF64 38
 43 
 44 // RFC9096 defines recommended option lifetimes configuration values
 45 #define ND_PREFERRED_LIMIT 2700
 46 #define ND_VALID_LIMIT 5400
 47 
 48 // RFC 9463 - Discovery of Network-designated Resolvers (DNR)
 49 #define ND_OPT_DNR 144
 50 
 51 #define INFINITE_VALID(x) ((x) == 0)
 52 
 53 #define _unused __attribute__((unused))
 54 #define _packed __attribute__((packed))
 55 #define _fallthrough __attribute__((__fallthrough__))
 56 
 57 #define ALL_IPV6_NODES "ff02::1"
 58 #define ALL_IPV6_ROUTERS "ff02::2"
 59 
 60 #define NTP_SUBOPTION_SRV_ADDR 1
 61 #define NTP_SUBOPTION_MC_ADDR 2
 62 #define NTP_SUBOPTION_SRV_FQDN 3
 63 #define IPV6_ADDR_LEN 16
 64 
 65 #define IN6_IS_ADDR_ULA(a) (((a)->s6_addr32[0] & htonl(0xfe000000)) == htonl(0xfc000000))
 66 
 67 #define ADDR_MATCH_PIO_FILTER(_addr, iface) (odhcpd_bmemcmp(&(_addr)->addr, \
 68                                                             &(iface)->pio_filter_addr, \
 69                                                             (iface)->pio_filter_length) != 0 || \
 70                                              (_addr)->prefix < (iface)->pio_filter_length)
 71 
 72 struct interface;
 73 struct nl_sock;
 74 extern struct vlist_tree leases;
 75 extern struct config config;
 76 extern struct sys_conf sys_conf;
 77 
 78 void __iflog(int lvl, const char *fmt, ...);
 79 #define debug(fmt, ...)     __iflog(LOG_DEBUG, fmt __VA_OPT__(, ) __VA_ARGS__)
 80 #define info(fmt, ...)      __iflog(LOG_INFO, fmt __VA_OPT__(, ) __VA_ARGS__)
 81 #define notice(fmt, ...)    __iflog(LOG_NOTICE, fmt __VA_OPT__(, ) __VA_ARGS__)
 82 #define warn(fmt, ...)      __iflog(LOG_WARNING, fmt __VA_OPT__(, ) __VA_ARGS__)
 83 #define error(fmt, ...)     __iflog(LOG_ERR, fmt __VA_OPT__(, ) __VA_ARGS__)
 84 #define critical(fmt, ...)  __iflog(LOG_CRIT, fmt __VA_OPT__(, ) __VA_ARGS__)
 85 #define alert(fmt, ...)     __iflog(LOG_ALERT, fmt __VA_OPT__(, ) __VA_ARGS__)
 86 #define emergency(fmt, ...) __iflog(LOG_EMERG, fmt __VA_OPT__(, ) __VA_ARGS__)
 87 
 88 
 89 struct odhcpd_event {
 90         struct uloop_fd uloop;
 91         void (*handle_dgram)(void *addr, void *data, size_t len,
 92                         struct interface *iface, void *dest_addr);
 93         void (*handle_error)(struct odhcpd_event *e, int error);
 94         void (*recv_msgs)(struct odhcpd_event *e);
 95 };
 96 
 97 typedef ssize_t (*send_reply_cb_t)(struct iovec *iov, size_t iov_len,
 98                                    struct sockaddr *dest, socklen_t dest_len,
 99                                    void *opaque);
100 
101 typedef void (*dhcpv6_binding_cb_handler_t)(struct in6_addr *addr, int prefix,
102                                             uint32_t pref, uint32_t valid,
103                                             void *arg);
104 
105 union if_addr {
106         struct in_addr in;
107         struct in6_addr in6;
108 };
109 
110 struct netevent_handler_info {
111         struct interface *iface;
112         union {
113                 struct {
114                         union if_addr dst;
115                         uint8_t dst_len;
116                         union if_addr gateway;
117                 } rt;
118                 struct {
119                         union if_addr dst;
120                         uint16_t state;
121                         uint8_t flags;
122                 } neigh;
123                 struct {
124                         struct odhcpd_ipaddr *addrs;
125                         size_t len;
126                 } addrs_old;
127                 union if_addr addr;
128         };
129 };
130 
131 enum netevents {
132         NETEV_IFINDEX_CHANGE,
133         NETEV_ADDR_ADD,
134         NETEV_ADDR_DEL,
135         NETEV_ADDRLIST_CHANGE,
136         NETEV_ADDR6_ADD,
137         NETEV_ADDR6_DEL,
138         NETEV_ADDR6LIST_CHANGE,
139         NETEV_ROUTE6_ADD,
140         NETEV_ROUTE6_DEL,
141         NETEV_NEIGH6_ADD,
142         NETEV_NEIGH6_DEL,
143 };
144 
145 struct netevent_handler {
146         struct list_head head;
147         void (*cb) (unsigned long event, struct netevent_handler_info *info);
148 };
149 
150 struct odhcpd_ipaddr {
151         union if_addr addr;
152         uint8_t prefix;
153         uint32_t preferred_lt;
154         uint32_t valid_lt;
155 
156         union {
157                 /* ipv6 only */
158                 struct {
159                         uint8_t dprefix;
160                         bool tentative;
161                 };
162 
163                 /* ipv4 only */
164                 struct in_addr broadcast;
165         };
166 };
167 
168 enum odhcpd_mode {
169         MODE_DISABLED,
170         MODE_SERVER,
171         MODE_RELAY,
172         MODE_HYBRID
173 };
174 
175 
176 enum odhcpd_assignment_flags {
177         OAF_TENTATIVE           = (1 << 0),
178         OAF_BOUND               = (1 << 1),
179         OAF_STATIC              = (1 << 2),
180         OAF_BROKEN_HOSTNAME     = (1 << 3),
181         OAF_DHCPV4              = (1 << 4),
182         OAF_DHCPV6_NA           = (1 << 5),
183         OAF_DHCPV6_PD           = (1 << 6),
184 };
185 
186 struct config {
187         bool legacy;
188         bool enable_tz;
189         bool main_dhcpv4;
190         char *dhcp_cb;
191         char *dhcp_statefile;
192         char *dhcp_hostsfile;
193 
194         char *ra_piofolder;
195         int ra_piofolder_fd;
196 
197         char *uci_cfgfile;
198         int log_level;
199         bool log_level_cmdline;
200         bool log_syslog;
201 };
202 
203 struct sys_conf {
204         uint8_t *posix_tz;
205         size_t posix_tz_len;
206         char *uci_cfgfile;
207         uint8_t *tzdb_tz;
208         size_t tzdb_tz_len;
209 };
210 
211 /* 2-byte type + 128-byte DUID, RFC8415, §11.1 */
212 #define DUID_MAX_LEN 130
213 #define DUID_HEXSTRLEN (DUID_MAX_LEN * 2 + 1)
214 
215 struct duid {
216         uint8_t len;
217         uint8_t id[DUID_MAX_LEN];
218         uint32_t iaid;
219         bool iaid_set;
220 };
221 
222 struct lease {
223         struct vlist_node node;
224         struct list_head assignments;
225         uint32_t ipaddr;
226         uint64_t hostid;
227         size_t mac_count;
228         struct ether_addr *macs;
229         size_t duid_count;
230         struct duid *duids;
231         uint32_t leasetime;
232         char *hostname;
233 };
234 
235 enum {
236         LEASE_ATTR_IP,
237         LEASE_ATTR_MAC,
238         LEASE_ATTR_DUID,
239         LEASE_ATTR_HOSTID,
240         LEASE_ATTR_LEASETIME,
241         LEASE_ATTR_NAME,
242         LEASE_ATTR_MAX
243 };
244 
245 struct odhcpd_ref_ip;
246 
247 struct dhcp_assignment {
248         struct list_head head;
249         struct list_head lease_list;
250 
251         void (*dhcp_free_cb)(struct dhcp_assignment *a);
252 
253         struct interface *iface;
254         struct lease *lease;
255 
256         struct sockaddr_in6 peer;
257         time_t valid_until;
258         time_t preferred_until;
259 
260         // ForceRenew - RFC6704 §3.1.2 (IPv4), RFC8415 (IPv6), §20.4, §21.11
261         struct uloop_timeout fr_timer;
262         bool accept_fr_nonce;
263         int fr_cnt;
264         uint8_t key[16];
265         struct odhcpd_ref_ip *fr_ip;
266 
267         uint32_t addr;
268         union {
269                 uint64_t assigned_host_id;
270                 uint32_t assigned_subnet_id;
271         };
272         uint32_t iaid;
273         uint8_t length; // length == 128 -> IA_NA, length <= 64 -> IA_PD
274 
275         struct odhcpd_ipaddr *managed;
276         ssize_t managed_size;
277         struct ustream_fd managed_sock;
278 
279         unsigned int flags;
280         uint32_t leasetime;
281         char *hostname;
282 
283         uint8_t hwaddr[6];
284 
285         uint16_t clid_len;
286         uint8_t clid_data[];
287 };
288 
289 
290 // DNR - RFC9463
291 struct dnr_options {
292         uint16_t priority;
293 
294         uint32_t lifetime;
295         bool lifetime_set;
296 
297         uint8_t *adn;
298         uint16_t adn_len;
299 
300         struct in_addr *addr4;
301         size_t addr4_cnt;
302         struct in6_addr *addr6;
303         size_t addr6_cnt;
304 
305         uint8_t *svc;
306         uint16_t svc_len;
307 };
308 
309 
310 // RA PIO - RFC9096
311 struct ra_pio {
312         struct in6_addr prefix;
313         uint8_t length;
314         time_t lifetime;
315 };
316 
317 
318 struct interface {
319         struct avl_node avl;
320 
321         int ifflags;
322         int ifindex;
323         char *ifname;
324         const char *name;
325 
326         // IPv6 runtime data
327         struct odhcpd_ipaddr *addr6;
328         size_t addr6_len;
329 
330         // RA runtime data
331         struct odhcpd_event router_event;
332         struct uloop_timeout timer_rs;
333         uint32_t ra_sent;
334 
335         // DHCPv6 runtime data
336         struct odhcpd_event dhcpv6_event;
337         struct list_head ia_assignments;
338 
339         // NDP runtime data
340         struct odhcpd_event ndp_event;
341         int ndp_ping_fd;
342 
343         // IPv4 runtime data
344         struct odhcpd_ipaddr *addr4;
345         size_t addr4_len;
346 
347         // DHCPv4 runtime data
348         struct odhcpd_event dhcpv4_event;
349         struct list_head dhcpv4_assignments;
350         struct list_head dhcpv4_fr_ips;
351 
352         // Managed PD
353         char dhcpv6_pd_manager[128];
354         struct in6_addr dhcpv6_pd_cer;
355 
356         // Services
357         enum odhcpd_mode ra;
358         enum odhcpd_mode dhcpv6;
359         enum odhcpd_mode ndp;
360         enum odhcpd_mode dhcpv4;
361 
362         // Config
363         bool inuse;
364         bool external;
365         bool master;
366         bool ignore;
367         bool always_rewrite_dns;
368         bool dns_service;
369 
370         // NDP
371         int learn_routes;
372         bool ndp_from_link_local;
373         struct in6_addr cached_linklocal_addr;
374         bool cached_linklocal_valid;
375 
376         // RA
377         uint8_t ra_flags;
378         bool ra_slaac;
379         bool ra_not_onlink;
380         bool ra_advrouter;
381         bool ra_dns;
382         uint8_t pref64_length;
383         uint8_t pref64_plc;
384         uint32_t pref64_prefix[3];
385         bool no_dynamic_dhcp;
386         bool have_link_local;
387         uint8_t pio_filter_length;
388         struct in6_addr pio_filter_addr;
389         int default_router;
390         int route_preference;
391         uint32_t ra_maxinterval;
392         uint32_t ra_mininterval;
393         uint32_t ra_lifetime;
394         uint32_t ra_reachabletime;
395         uint32_t ra_retranstime;
396         uint32_t ra_hoplimit;
397         int ra_mtu;
398         uint32_t max_preferred_lifetime;
399         uint32_t max_valid_lifetime;
400 
401         // DHCP
402         uint32_t dhcp_leasetime;
403 
404         // DHCPv4
405         struct in_addr dhcpv4_start;
406         struct in_addr dhcpv4_end;
407         struct in_addr dhcpv4_start_ip;
408         struct in_addr dhcpv4_end_ip;
409         struct in_addr dhcpv4_local;
410         struct in_addr dhcpv4_bcast;
411         struct in_addr dhcpv4_mask;
412         struct in_addr *dhcpv4_router;
413         size_t dhcpv4_router_cnt;
414         struct in_addr *dhcpv4_dns;
415         size_t dhcpv4_dns_cnt;
416         bool dhcpv4_forcereconf;
417 
418         // DNS
419         struct in6_addr *dns;
420         size_t dns_cnt;
421         uint8_t *search;
422         size_t search_len;
423 
424         // DHCPV6
425         void *dhcpv6_raw;
426         size_t dhcpv6_raw_len;
427         bool dhcpv6_assignall;
428         bool dhcpv6_pd;
429         bool dhcpv6_na;
430         uint32_t dhcpv6_hostid_len;
431         uint32_t dhcpv6_pd_min_len; // minimum delegated prefix length
432 
433         char *upstream;
434         size_t upstream_len;
435 
436         char *filter_class;
437 
438         // NTP
439         struct in_addr *dhcpv4_ntp;
440         size_t dhcpv4_ntp_cnt;
441         uint8_t *dhcpv6_ntp;
442         uint16_t dhcpv6_ntp_len;
443         size_t dhcpv6_ntp_cnt;
444 
445         // SNTP
446         struct in6_addr *dhcpv6_sntp;
447         size_t dhcpv6_sntp_cnt;
448 
449         // DNR
450         struct dnr_options *dnr;
451         size_t dnr_cnt;
452 
453         // RA PIO - RFC9096
454         struct ra_pio *pios;
455         size_t pio_cnt;
456         bool pio_update;
457 };
458 
459 extern struct avl_tree interfaces;
460 extern const struct blobmsg_policy lease_attrs[LEASE_ATTR_MAX];
461 
462 inline static void free_assignment(struct dhcp_assignment *a)
463 {
464         list_del(&a->head);
465         list_del(&a->lease_list);
466 
467         if (a->dhcp_free_cb)
468                 a->dhcp_free_cb(a);
469 
470         free(a->hostname);
471         free(a);
472 }
473 
474 inline static struct dhcp_assignment *alloc_assignment(size_t extra_len)
475 {
476         struct dhcp_assignment *a = calloc(1, sizeof(*a) + extra_len);
477 
478         if (!a)
479                 return NULL;
480 
481         INIT_LIST_HEAD(&a->head);
482         INIT_LIST_HEAD(&a->lease_list);
483 
484         return a;
485 }
486 
487 inline static bool ra_pio_expired(const struct ra_pio *pio, time_t now)
488 {
489         return pio->lifetime && (now > pio->lifetime);
490 }
491 
492 inline static uint32_t ra_pio_lifetime(const struct ra_pio *pio, time_t now)
493 {
494         if (!pio->lifetime || now > pio->lifetime)
495                 return 0;
496 
497         return (uint32_t) (pio->lifetime - now);
498 }
499 
500 inline static bool ra_pio_stale(const struct ra_pio *pio)
501 {
502         return !!pio->lifetime;
503 }
504 
505 // Exported main functions
506 int odhcpd_register(struct odhcpd_event *event);
507 int odhcpd_deregister(struct odhcpd_event *event);
508 void odhcpd_process(struct odhcpd_event *event);
509 
510 ssize_t odhcpd_send_with_src(int socket, struct sockaddr_in6 *dest,
511                 struct iovec *iov, size_t iov_len,
512                 const struct interface *iface, const struct in6_addr *src_addr);
513 ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
514                 struct iovec *iov, size_t iov_len,
515                 const struct interface *iface);
516 ssize_t odhcpd_try_send_with_src(int socket, struct sockaddr_in6 *dest,
517                 struct iovec *iov, size_t iov_len,
518                 struct interface *iface);
519 int odhcpd_get_interface_dns_addr(struct interface *iface,
520                 struct in6_addr *addr);
521 int odhcpd_get_interface_linklocal_addr(struct interface *iface,
522                 struct in6_addr *addr);
523 int odhcpd_get_interface_config(const char *ifname, const char *what);
524 int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6]);
525 int odhcpd_get_flags(const struct interface *iface);
526 struct interface* odhcpd_get_interface_by_index(int ifindex);
527 void odhcpd_urandom(void *data, size_t len);
528 
529 void odhcpd_run(void);
530 time_t odhcpd_time(void);
531 ssize_t odhcpd_unhexlify(uint8_t *dst, size_t len, const char *src);
532 void odhcpd_hexlify(char *dst, const uint8_t *src, size_t len);
533 const char *odhcpd_print_mac(const uint8_t *mac, const size_t len);
534 
535 int odhcpd_bmemcmp(const void *av, const void *bv, size_t bits);
536 void odhcpd_bmemcpy(void *av, const void *bv, size_t bits);
537 
538 int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix);
539 int odhcpd_netmask2bitlen(bool v6, void *mask);
540 bool odhcpd_bitlen2netmask(bool v6, unsigned int bits, void *mask);
541 bool odhcpd_valid_hostname(const char *name);
542 
543 int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite);
544 struct lease *config_find_lease_by_duid_and_iaid(const uint8_t *duid, const uint16_t len,
545                                                  const uint32_t iaid);
546 struct lease *config_find_lease_by_mac(const uint8_t *mac);
547 struct lease *config_find_lease_by_hostid(const uint64_t hostid);
548 struct lease *config_find_lease_by_ipaddr(const uint32_t ipaddr);
549 void config_load_ra_pio(struct interface *iface);
550 void config_save_ra_pio(struct interface *iface);
551 int set_lease_from_blobmsg(struct blob_attr *ba);
552 
553 #ifdef WITH_UBUS
554 int ubus_init(void);
555 const char* ubus_get_ifname(const char *name);
556 void ubus_apply_network(void);
557 bool ubus_has_prefix(const char *name, const char *ifname);
558 void ubus_bcast_dhcp_event(const char *type, const uint8_t *mac,
559                            const struct in_addr *addr, const char *name,
560                            const char *interface);
561 #else
562 static inline int ubus_init(void)
563 {
564         return 0;
565 }
566 
567 static inline void ubus_apply_network(void)
568 {
569         return;
570 }
571 
572 static inline
573 void ubus_bcast_dhcp_event(const char *type, const uint8_t *mac,
574                            const struct in_addr *addr, const char *name,
575                            const char *interface)
576 {
577         return;
578 }
579 #endif /* WITH_UBUS */
580 
581 ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *iface,
582                 const struct sockaddr_in6 *addr, const void *data, const uint8_t *end);
583 int dhcpv6_ia_init(void);
584 int dhcpv6_ia_setup_interface(struct interface *iface, bool enable);
585 void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, time_t now,
586                                 dhcpv6_binding_cb_handler_t func, void *arg);
587 void dhcpv6_ia_write_statefile(void);
588 
589 int netlink_add_netevent_handler(struct netevent_handler *hdlr);
590 ssize_t netlink_get_interface_addrs(const int ifindex, bool v6,
591                 struct odhcpd_ipaddr **addrs);
592 ssize_t netlink_get_interface_linklocal(int ifindex, struct odhcpd_ipaddr **addrs);
593 int netlink_get_interface_proxy_neigh(int ifindex, const struct in6_addr *addr);
594 int netlink_setup_route(const struct in6_addr *addr, const int prefixlen,
595                 const int ifindex, const struct in6_addr *gw,
596                 const uint32_t metric, const bool add);
597 int netlink_setup_proxy_neigh(const struct in6_addr *addr,
598                 const int ifindex, const bool add);
599 int netlink_setup_addr(struct odhcpd_ipaddr *addr,
600                 const int ifindex, const bool v6, const bool add);
601 void netlink_dump_neigh_table(const bool proxy);
602 void netlink_dump_addr_table(const bool v6);
603 
604 // Exported module initializers
605 int netlink_init(void);
606 int router_init(void);
607 int dhcpv6_init(void);
608 int ndp_init(void);
609 #ifdef DHCPV4_SUPPORT
610 int dhcpv4_init(void);
611 
612 int dhcpv4_setup_interface(struct interface *iface, bool enable);
613 void dhcpv4_handle_msg(void *addr, void *data, size_t len,
614                        struct interface *iface, _unused void *dest_addr,
615                        send_reply_cb_t send_reply, void *opaque);
616 #endif
617 int router_setup_interface(struct interface *iface, bool enable);
618 int dhcpv6_setup_interface(struct interface *iface, bool enable);
619 int ndp_setup_interface(struct interface *iface, bool enable);
620 void reload_services(struct interface *iface);
621 
622 void odhcpd_reload(void);
623 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt