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