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 6106 defines this router advertisement option 33 #define ND_OPT_ROUTE_INFO 24 34 #define ND_OPT_RECURSIVE_DNS 25 35 #define ND_OPT_DNS_SEARCH 31 36 37 // RFC 8781 defines PREF64 option 38 #define ND_OPT_PREF64 38 39 40 // RFC 9463 - Discovery of Network-designated Resolvers (DNR) 41 #define ND_OPT_DNR 144 42 43 #define INFINITE_VALID(x) ((x) == 0) 44 45 #define _unused __attribute__((unused)) 46 #define _packed __attribute__((packed)) 47 48 #define ALL_IPV6_NODES "ff02::1" 49 #define ALL_IPV6_ROUTERS "ff02::2" 50 51 #define NTP_SUBOPTION_SRV_ADDR 1 52 #define NTP_SUBOPTION_MC_ADDR 2 53 #define NTP_SUBOPTION_SRV_FQDN 3 54 #define IPV6_ADDR_LEN 16 55 56 #define IN6_IS_ADDR_ULA(a) (((a)->s6_addr32[0] & htonl(0xfe000000)) == htonl(0xfc000000)) 57 58 #define ADDR_MATCH_PIO_FILTER(_addr, iface) (odhcpd_bmemcmp(&(_addr)->addr, \ 59 &(iface)->pio_filter_addr, \ 60 (iface)->pio_filter_length) != 0 || \ 61 (_addr)->prefix < (iface)->pio_filter_length) 62 63 struct interface; 64 struct nl_sock; 65 extern struct vlist_tree leases; 66 extern struct config config; 67 68 struct odhcpd_event { 69 struct uloop_fd uloop; 70 void (*handle_dgram)(void *addr, void *data, size_t len, 71 struct interface *iface, void *dest_addr); 72 void (*handle_error)(struct odhcpd_event *e, int error); 73 void (*recv_msgs)(struct odhcpd_event *e); 74 }; 75 76 typedef int (*send_reply_cb_t)(const void *buf, size_t len, 77 const struct sockaddr *dest, socklen_t dest_len, 78 void *opaque); 79 80 typedef void (*dhcpv6_binding_cb_handler_t)(struct in6_addr *addr, int prefix, 81 uint32_t pref, uint32_t valid, 82 void *arg); 83 84 union if_addr { 85 struct in_addr in; 86 struct in6_addr in6; 87 }; 88 89 struct netevent_handler_info { 90 struct interface *iface; 91 union { 92 struct { 93 union if_addr dst; 94 uint8_t dst_len; 95 union if_addr gateway; 96 } rt; 97 struct { 98 union if_addr dst; 99 uint16_t state; 100 uint8_t flags; 101 } neigh; 102 struct { 103 struct odhcpd_ipaddr *addrs; 104 size_t len; 105 } addrs_old; 106 union if_addr addr; 107 }; 108 }; 109 110 enum netevents { 111 NETEV_IFINDEX_CHANGE, 112 NETEV_ADDR_ADD, 113 NETEV_ADDR_DEL, 114 NETEV_ADDRLIST_CHANGE, 115 NETEV_ADDR6_ADD, 116 NETEV_ADDR6_DEL, 117 NETEV_ADDR6LIST_CHANGE, 118 NETEV_ROUTE6_ADD, 119 NETEV_ROUTE6_DEL, 120 NETEV_NEIGH6_ADD, 121 NETEV_NEIGH6_DEL, 122 }; 123 124 struct netevent_handler { 125 struct list_head head; 126 void (*cb) (unsigned long event, struct netevent_handler_info *info); 127 }; 128 129 struct odhcpd_ipaddr { 130 union if_addr addr; 131 uint8_t prefix; 132 uint32_t preferred_lt; 133 uint32_t valid_lt; 134 135 union { 136 /* ipv6 only */ 137 struct { 138 uint8_t dprefix; 139 uint8_t invalid_advertisements; 140 bool tentative; 141 }; 142 143 /* ipv4 only */ 144 struct in_addr broadcast; 145 }; 146 }; 147 148 enum odhcpd_mode { 149 MODE_DISABLED, 150 MODE_SERVER, 151 MODE_RELAY, 152 MODE_HYBRID 153 }; 154 155 156 enum odhcpd_assignment_flags { 157 OAF_TENTATIVE = (1 << 0), 158 OAF_BOUND = (1 << 1), 159 OAF_STATIC = (1 << 2), 160 OAF_BROKEN_HOSTNAME = (1 << 3), 161 OAF_DHCPV4 = (1 << 4), 162 OAF_DHCPV6_NA = (1 << 5), 163 OAF_DHCPV6_PD = (1 << 6), 164 }; 165 166 struct config { 167 bool legacy; 168 bool main_dhcpv4; 169 char *dhcp_cb; 170 char *dhcp_statefile; 171 char *dhcp_hostsfile; 172 int log_level; 173 }; 174 175 176 struct lease { 177 struct vlist_node node; 178 struct list_head assignments; 179 uint32_t ipaddr; 180 uint64_t hostid; 181 struct ether_addr mac; 182 uint16_t duid_len; 183 uint8_t *duid; 184 uint32_t leasetime; 185 char *hostname; 186 }; 187 188 enum { 189 LEASE_ATTR_IP, 190 LEASE_ATTR_MAC, 191 LEASE_ATTR_DUID, 192 LEASE_ATTR_HOSTID, 193 LEASE_ATTR_LEASETIME, 194 LEASE_ATTR_NAME, 195 LEASE_ATTR_MAX 196 }; 197 198 struct odhcpd_ref_ip; 199 200 struct dhcp_assignment { 201 struct list_head head; 202 struct list_head lease_list; 203 204 void (*dhcp_free_cb)(struct dhcp_assignment *a); 205 206 struct interface *iface; 207 struct lease *lease; 208 209 struct sockaddr_in6 peer; 210 time_t valid_until; 211 time_t preferred_until; 212 213 #define fr_timer reconf_timer 214 struct uloop_timeout reconf_timer; 215 #define accept_fr_nonce accept_reconf 216 bool accept_reconf; 217 #define fr_cnt reconf_cnt 218 int reconf_cnt; 219 uint8_t key[16]; 220 struct odhcpd_ref_ip *fr_ip; 221 222 uint32_t addr; 223 union { 224 uint64_t assigned_host_id; 225 uint32_t assigned_subnet_id; 226 }; 227 uint32_t iaid; 228 uint8_t length; // length == 128 -> IA_NA, length <= 64 -> IA_PD 229 230 struct odhcpd_ipaddr *managed; 231 ssize_t managed_size; 232 struct ustream_fd managed_sock; 233 234 unsigned int flags; 235 uint32_t leasetime; 236 char *hostname; 237 uint8_t *reqopts; 238 size_t reqopts_len; 239 240 #define hwaddr mac 241 uint8_t mac[6]; 242 243 uint16_t clid_len; 244 uint8_t clid_data[]; 245 }; 246 247 248 // DNR - RFC9463 249 struct dnr_options { 250 uint16_t priority; 251 252 uint32_t lifetime; 253 bool lifetime_set; 254 255 uint8_t *adn; 256 uint16_t adn_len; 257 258 struct in_addr *addr4; 259 size_t addr4_cnt; 260 struct in6_addr *addr6; 261 size_t addr6_cnt; 262 263 uint8_t *svc; 264 uint16_t svc_len; 265 }; 266 267 268 struct interface { 269 struct avl_node avl; 270 271 int ifflags; 272 int ifindex; 273 char *ifname; 274 const char *name; 275 276 // IPv6 runtime data 277 struct odhcpd_ipaddr *addr6; 278 size_t addr6_len; 279 struct odhcpd_ipaddr *invalid_addr6; 280 size_t invalid_addr6_len; 281 282 // RA runtime data 283 struct odhcpd_event router_event; 284 struct uloop_timeout timer_rs; 285 uint32_t ra_sent; 286 287 // DHCPv6 runtime data 288 struct odhcpd_event dhcpv6_event; 289 struct list_head ia_assignments; 290 291 // NDP runtime data 292 struct odhcpd_event ndp_event; 293 int ndp_ping_fd; 294 295 // IPv4 runtime data 296 struct odhcpd_ipaddr *addr4; 297 size_t addr4_len; 298 299 // DHCPv4 runtime data 300 struct odhcpd_event dhcpv4_event; 301 struct list_head dhcpv4_assignments; 302 struct list_head dhcpv4_fr_ips; 303 304 // Managed PD 305 char dhcpv6_pd_manager[128]; 306 struct in6_addr dhcpv6_pd_cer; 307 308 // Services 309 enum odhcpd_mode ra; 310 enum odhcpd_mode dhcpv6; 311 enum odhcpd_mode ndp; 312 enum odhcpd_mode dhcpv4; 313 314 // Config 315 bool inuse; 316 bool external; 317 bool master; 318 bool ignore; 319 bool always_rewrite_dns; 320 bool dns_service; 321 322 // NDP 323 int learn_routes; 324 325 // RA 326 uint8_t ra_flags; 327 bool ra_slaac; 328 bool ra_not_onlink; 329 bool ra_advrouter; 330 bool ra_useleasetime; 331 bool ra_dns; 332 uint8_t pref64_length; 333 uint8_t pref64_plc; 334 uint32_t pref64_prefix[3]; 335 bool no_dynamic_dhcp; 336 bool have_link_local; 337 uint8_t pio_filter_length; 338 struct in6_addr pio_filter_addr; 339 int default_router; 340 int route_preference; 341 int ra_maxinterval; 342 int ra_mininterval; 343 int ra_lifetime; 344 uint32_t ra_reachabletime; 345 uint32_t ra_retranstime; 346 uint32_t ra_hoplimit; 347 int ra_mtu; 348 uint32_t preferred_lifetime; 349 350 // DHCP 351 uint32_t dhcp_leasetime; 352 353 // DHCPv4 354 struct in_addr dhcpv4_start; 355 struct in_addr dhcpv4_end; 356 struct in_addr dhcpv4_start_ip; 357 struct in_addr dhcpv4_end_ip; 358 struct in_addr dhcpv4_local; 359 struct in_addr dhcpv4_bcast; 360 struct in_addr dhcpv4_mask; 361 struct in_addr *dhcpv4_router; 362 size_t dhcpv4_router_cnt; 363 struct in_addr *dhcpv4_dns; 364 size_t dhcpv4_dns_cnt; 365 bool dhcpv4_forcereconf; 366 367 // DNS 368 struct in6_addr *dns; 369 size_t dns_cnt; 370 uint8_t *search; 371 size_t search_len; 372 373 // DHCPV6 374 void *dhcpv6_raw; 375 size_t dhcpv6_raw_len; 376 bool dhcpv6_assignall; 377 bool dhcpv6_pd; 378 bool dhcpv6_na; 379 uint32_t dhcpv6_hostid_len; 380 uint32_t dhcpv6_pd_min_len; // minimum delegated prefix length 381 382 char *upstream; 383 size_t upstream_len; 384 385 char *filter_class; 386 387 // NTP 388 struct in_addr *dhcpv4_ntp; 389 size_t dhcpv4_ntp_cnt; 390 uint8_t *dhcpv6_ntp; 391 uint16_t dhcpv6_ntp_len; 392 size_t dhcpv6_ntp_cnt; 393 394 // SNTP 395 struct in6_addr *dhcpv6_sntp; 396 size_t dhcpv6_sntp_cnt; 397 398 // DNR 399 struct dnr_options *dnr; 400 size_t dnr_cnt; 401 }; 402 403 extern struct avl_tree interfaces; 404 extern const struct blobmsg_policy lease_attrs[LEASE_ATTR_MAX]; 405 406 inline static void free_assignment(struct dhcp_assignment *a) 407 { 408 list_del(&a->head); 409 list_del(&a->lease_list); 410 411 if (a->dhcp_free_cb) 412 a->dhcp_free_cb(a); 413 414 free(a->hostname); 415 free(a->reqopts); 416 free(a); 417 } 418 419 inline static struct dhcp_assignment *alloc_assignment(size_t extra_len) 420 { 421 struct dhcp_assignment *a = calloc(1, sizeof(*a) + extra_len); 422 423 if (!a) 424 return NULL; 425 426 INIT_LIST_HEAD(&a->head); 427 INIT_LIST_HEAD(&a->lease_list); 428 429 return a; 430 } 431 432 // Exported main functions 433 int odhcpd_register(struct odhcpd_event *event); 434 int odhcpd_deregister(struct odhcpd_event *event); 435 void odhcpd_process(struct odhcpd_event *event); 436 437 ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest, 438 struct iovec *iov, size_t iov_len, 439 const struct interface *iface); 440 int odhcpd_get_interface_dns_addr(const struct interface *iface, 441 struct in6_addr *addr); 442 int odhcpd_get_interface_config(const char *ifname, const char *what); 443 int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6]); 444 int odhcpd_get_flags(const struct interface *iface); 445 struct interface* odhcpd_get_interface_by_index(int ifindex); 446 int odhcpd_urandom(void *data, size_t len); 447 448 void odhcpd_run(void); 449 time_t odhcpd_time(void); 450 ssize_t odhcpd_unhexlify(uint8_t *dst, size_t len, const char *src); 451 void odhcpd_hexlify(char *dst, const uint8_t *src, size_t len); 452 const char *odhcpd_print_mac(const uint8_t *mac, const size_t len); 453 454 int odhcpd_bmemcmp(const void *av, const void *bv, size_t bits); 455 void odhcpd_bmemcpy(void *av, const void *bv, size_t bits); 456 457 int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix); 458 int odhcpd_netmask2bitlen(bool v6, void *mask); 459 bool odhcpd_bitlen2netmask(bool v6, unsigned int bits, void *mask); 460 bool odhcpd_valid_hostname(const char *name); 461 462 int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite); 463 struct lease *config_find_lease_by_duid(const uint8_t *duid, const uint16_t len); 464 struct lease *config_find_lease_by_mac(const uint8_t *mac); 465 struct lease *config_find_lease_by_hostid(const uint64_t hostid); 466 struct lease *config_find_lease_by_ipaddr(const uint32_t ipaddr); 467 int set_lease_from_blobmsg(struct blob_attr *ba); 468 469 #ifdef WITH_UBUS 470 int ubus_init(void); 471 const char* ubus_get_ifname(const char *name); 472 void ubus_apply_network(void); 473 bool ubus_has_prefix(const char *name, const char *ifname); 474 void ubus_bcast_dhcp_event(const char *type, const uint8_t *mac, const size_t mac_len, 475 const struct in_addr *addr, const char *name, const char *interface); 476 #endif 477 478 ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *iface, 479 const struct sockaddr_in6 *addr, const void *data, const uint8_t *end); 480 int dhcpv6_ia_init(void); 481 int dhcpv6_ia_setup_interface(struct interface *iface, bool enable); 482 void dhcpv6_ia_enum_addrs(struct interface *iface, struct dhcp_assignment *c, time_t now, 483 dhcpv6_binding_cb_handler_t func, void *arg); 484 void dhcpv6_ia_write_statefile(void); 485 486 int netlink_add_netevent_handler(struct netevent_handler *hdlr); 487 ssize_t netlink_get_interface_addrs(const int ifindex, bool v6, 488 struct odhcpd_ipaddr **addrs); 489 ssize_t netlink_get_interface_linklocal(int ifindex, struct odhcpd_ipaddr **addrs); 490 int netlink_get_interface_proxy_neigh(int ifindex, const struct in6_addr *addr); 491 int netlink_setup_route(const struct in6_addr *addr, const int prefixlen, 492 const int ifindex, const struct in6_addr *gw, 493 const uint32_t metric, const bool add); 494 int netlink_setup_proxy_neigh(const struct in6_addr *addr, 495 const int ifindex, const bool add); 496 int netlink_setup_addr(struct odhcpd_ipaddr *addr, 497 const int ifindex, const bool v6, const bool add); 498 void netlink_dump_neigh_table(const bool proxy); 499 void netlink_dump_addr_table(const bool v6); 500 501 // Exported module initializers 502 int netlink_init(void); 503 int router_init(void); 504 int dhcpv6_init(void); 505 int ndp_init(void); 506 #ifdef DHCPV4_SUPPORT 507 int dhcpv4_init(void); 508 509 int dhcpv4_setup_interface(struct interface *iface, bool enable); 510 void dhcpv4_handle_msg(void *addr, void *data, size_t len, 511 struct interface *iface, _unused void *dest_addr, 512 send_reply_cb_t send_reply, void *opaque); 513 #endif 514 int router_setup_interface(struct interface *iface, bool enable); 515 int dhcpv6_setup_interface(struct interface *iface, bool enable); 516 int ndp_setup_interface(struct interface *iface, bool enable); 517 void reload_services(struct interface *iface); 518 519 void odhcpd_reload(void); 520
This page was automatically generated by LXR 0.3.1. • OpenWrt