1 #include <fcntl.h> 2 #include <resolv.h> 3 #include <signal.h> 4 #include <arpa/inet.h> 5 #include <unistd.h> 6 #include <libgen.h> 7 #include <net/if.h> 8 #include <string.h> 9 #include <sys/stat.h> 10 #include <syslog.h> 11 12 #include <uci.h> 13 #include <uci_blob.h> 14 #include <libubox/utils.h> 15 #include <libubox/avl.h> 16 #include <libubox/avl-cmp.h> 17 #include <libubox/list.h> 18 #include <libubox/vlist.h> 19 20 #include "odhcpd.h" 21 22 static struct blob_buf b; 23 static int reload_pipe[2] = { -1, -1 }; 24 25 static int lease_cmp(const void *k1, const void *k2, void *ptr); 26 static void lease_update(struct vlist_tree *tree, struct vlist_node *node_new, 27 struct vlist_node *node_old); 28 29 struct vlist_tree leases = VLIST_TREE_INIT(leases, lease_cmp, lease_update, true, false); 30 AVL_TREE(interfaces, avl_strcmp, false, NULL); 31 struct config config = {.legacy = false, .main_dhcpv4 = false, 32 .dhcp_cb = NULL, .dhcp_statefile = NULL, .dhcp_hostsfile = NULL, 33 .log_level = LOG_WARNING}; 34 35 #define START_DEFAULT 100 36 #define LIMIT_DEFAULT 150 37 38 #define HOSTID_LEN_MIN 12 39 #define HOSTID_LEN_MAX 64 40 #define HOSTID_LEN_DEFAULT HOSTID_LEN_MIN 41 42 #define PD_MIN_LEN_MAX (64-2) // must delegate at least 2 bits of prefix 43 44 #define OAF_DHCPV6 (OAF_DHCPV6_NA | OAF_DHCPV6_PD) 45 46 enum { 47 IFACE_ATTR_INTERFACE, 48 IFACE_ATTR_IFNAME, 49 IFACE_ATTR_NETWORKID, 50 IFACE_ATTR_DYNAMICDHCP, 51 IFACE_ATTR_LEASETIME, 52 IFACE_ATTR_LIMIT, 53 IFACE_ATTR_START, 54 IFACE_ATTR_MASTER, 55 IFACE_ATTR_UPSTREAM, 56 IFACE_ATTR_RA, 57 IFACE_ATTR_DHCPV4, 58 IFACE_ATTR_DHCPV6, 59 IFACE_ATTR_NDP, 60 IFACE_ATTR_ROUTER, 61 IFACE_ATTR_DNS, 62 IFACE_ATTR_DNS_SERVICE, 63 IFACE_ATTR_DOMAIN, 64 IFACE_ATTR_FILTER_CLASS, 65 IFACE_ATTR_DHCPV4_FORCERECONF, 66 IFACE_ATTR_DHCPV6_RAW, 67 IFACE_ATTR_DHCPV6_ASSIGNALL, 68 IFACE_ATTR_DHCPV6_PD, 69 IFACE_ATTR_DHCPV6_PD_MIN_LEN, 70 IFACE_ATTR_DHCPV6_NA, 71 IFACE_ATTR_DHCPV6_HOSTID_LEN, 72 IFACE_ATTR_RA_DEFAULT, 73 IFACE_ATTR_RA_MANAGEMENT, 74 IFACE_ATTR_RA_FLAGS, 75 IFACE_ATTR_RA_SLAAC, 76 IFACE_ATTR_RA_OFFLINK, 77 IFACE_ATTR_RA_PREFERENCE, 78 IFACE_ATTR_RA_ADVROUTER, 79 IFACE_ATTR_RA_MININTERVAL, 80 IFACE_ATTR_RA_MAXINTERVAL, 81 IFACE_ATTR_RA_LIFETIME, 82 IFACE_ATTR_RA_USELEASETIME, 83 IFACE_ATTR_RA_REACHABLETIME, 84 IFACE_ATTR_RA_RETRANSTIME, 85 IFACE_ATTR_RA_HOPLIMIT, 86 IFACE_ATTR_RA_MTU, 87 IFACE_ATTR_RA_DNS, 88 IFACE_ATTR_RA_PREF64, 89 IFACE_ATTR_PD_MANAGER, 90 IFACE_ATTR_PD_CER, 91 IFACE_ATTR_NDPROXY_ROUTING, 92 IFACE_ATTR_NDPROXY_SLAVE, 93 IFACE_ATTR_PREFIX_FILTER, 94 IFACE_ATTR_PREFERRED_LIFETIME, 95 IFACE_ATTR_NTP, 96 IFACE_ATTR_MAX 97 }; 98 99 static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { 100 [IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING }, 101 [IFACE_ATTR_IFNAME] = { .name = "ifname", .type = BLOBMSG_TYPE_STRING }, 102 [IFACE_ATTR_NETWORKID] = { .name = "networkid", .type = BLOBMSG_TYPE_STRING }, 103 [IFACE_ATTR_DYNAMICDHCP] = { .name = "dynamicdhcp", .type = BLOBMSG_TYPE_BOOL }, 104 [IFACE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 105 [IFACE_ATTR_START] = { .name = "start", .type = BLOBMSG_TYPE_INT32 }, 106 [IFACE_ATTR_LIMIT] = { .name = "limit", .type = BLOBMSG_TYPE_INT32 }, 107 [IFACE_ATTR_MASTER] = { .name = "master", .type = BLOBMSG_TYPE_BOOL }, 108 [IFACE_ATTR_UPSTREAM] = { .name = "upstream", .type = BLOBMSG_TYPE_ARRAY }, 109 [IFACE_ATTR_RA] = { .name = "ra", .type = BLOBMSG_TYPE_STRING }, 110 [IFACE_ATTR_DHCPV4] = { .name = "dhcpv4", .type = BLOBMSG_TYPE_STRING }, 111 [IFACE_ATTR_DHCPV6] = { .name = "dhcpv6", .type = BLOBMSG_TYPE_STRING }, 112 [IFACE_ATTR_NDP] = { .name = "ndp", .type = BLOBMSG_TYPE_STRING }, 113 [IFACE_ATTR_ROUTER] = { .name = "router", .type = BLOBMSG_TYPE_ARRAY }, 114 [IFACE_ATTR_DNS] = { .name = "dns", .type = BLOBMSG_TYPE_ARRAY }, 115 [IFACE_ATTR_DNS_SERVICE] = { .name = "dns_service", .type = BLOBMSG_TYPE_BOOL }, 116 [IFACE_ATTR_DOMAIN] = { .name = "domain", .type = BLOBMSG_TYPE_ARRAY }, 117 [IFACE_ATTR_FILTER_CLASS] = { .name = "filter_class", .type = BLOBMSG_TYPE_STRING }, 118 [IFACE_ATTR_DHCPV4_FORCERECONF] = { .name = "dhcpv4_forcereconf", .type = BLOBMSG_TYPE_BOOL }, 119 [IFACE_ATTR_DHCPV6_RAW] = { .name = "dhcpv6_raw", .type = BLOBMSG_TYPE_STRING }, 120 [IFACE_ATTR_DHCPV6_ASSIGNALL] = { .name ="dhcpv6_assignall", .type = BLOBMSG_TYPE_BOOL }, 121 [IFACE_ATTR_DHCPV6_PD] = { .name = "dhcpv6_pd", .type = BLOBMSG_TYPE_BOOL }, 122 [IFACE_ATTR_DHCPV6_PD_MIN_LEN] = { .name = "dhcpv6_pd_min_len", .type = BLOBMSG_TYPE_INT32 }, 123 [IFACE_ATTR_DHCPV6_NA] = { .name = "dhcpv6_na", .type = BLOBMSG_TYPE_BOOL }, 124 [IFACE_ATTR_DHCPV6_HOSTID_LEN] = { .name = "dhcpv6_hostidlength", .type = BLOBMSG_TYPE_INT32 }, 125 [IFACE_ATTR_PD_MANAGER] = { .name = "pd_manager", .type = BLOBMSG_TYPE_STRING }, 126 [IFACE_ATTR_PD_CER] = { .name = "pd_cer", .type = BLOBMSG_TYPE_STRING }, 127 [IFACE_ATTR_RA_DEFAULT] = { .name = "ra_default", .type = BLOBMSG_TYPE_INT32 }, 128 [IFACE_ATTR_RA_MANAGEMENT] = { .name = "ra_management", .type = BLOBMSG_TYPE_INT32 }, 129 [IFACE_ATTR_RA_FLAGS] = { .name = "ra_flags", . type = BLOBMSG_TYPE_ARRAY }, 130 [IFACE_ATTR_RA_SLAAC] = { .name = "ra_slaac", .type = BLOBMSG_TYPE_BOOL }, 131 [IFACE_ATTR_RA_OFFLINK] = { .name = "ra_offlink", .type = BLOBMSG_TYPE_BOOL }, 132 [IFACE_ATTR_RA_PREFERENCE] = { .name = "ra_preference", .type = BLOBMSG_TYPE_STRING }, 133 [IFACE_ATTR_RA_ADVROUTER] = { .name = "ra_advrouter", .type = BLOBMSG_TYPE_BOOL }, 134 [IFACE_ATTR_RA_MININTERVAL] = { .name = "ra_mininterval", .type = BLOBMSG_TYPE_INT32 }, 135 [IFACE_ATTR_RA_MAXINTERVAL] = { .name = "ra_maxinterval", .type = BLOBMSG_TYPE_INT32 }, 136 [IFACE_ATTR_RA_LIFETIME] = { .name = "ra_lifetime", .type = BLOBMSG_TYPE_INT32 }, 137 [IFACE_ATTR_RA_USELEASETIME] = { .name = "ra_useleasetime", .type = BLOBMSG_TYPE_BOOL }, 138 [IFACE_ATTR_RA_REACHABLETIME] = { .name = "ra_reachabletime", .type = BLOBMSG_TYPE_INT32 }, 139 [IFACE_ATTR_RA_RETRANSTIME] = { .name = "ra_retranstime", .type = BLOBMSG_TYPE_INT32 }, 140 [IFACE_ATTR_RA_HOPLIMIT] = { .name = "ra_hoplimit", .type = BLOBMSG_TYPE_INT32 }, 141 [IFACE_ATTR_RA_MTU] = { .name = "ra_mtu", .type = BLOBMSG_TYPE_INT32 }, 142 [IFACE_ATTR_RA_DNS] = { .name = "ra_dns", .type = BLOBMSG_TYPE_BOOL }, 143 [IFACE_ATTR_RA_PREF64] = { .name = "ra_pref64", .type = BLOBMSG_TYPE_STRING }, 144 [IFACE_ATTR_NDPROXY_ROUTING] = { .name = "ndproxy_routing", .type = BLOBMSG_TYPE_BOOL }, 145 [IFACE_ATTR_NDPROXY_SLAVE] = { .name = "ndproxy_slave", .type = BLOBMSG_TYPE_BOOL }, 146 [IFACE_ATTR_PREFIX_FILTER] = { .name = "prefix_filter", .type = BLOBMSG_TYPE_STRING }, 147 [IFACE_ATTR_PREFERRED_LIFETIME] = { .name = "preferred_lifetime", .type = BLOBMSG_TYPE_STRING }, 148 [IFACE_ATTR_NTP] = { .name = "ntp", .type = BLOBMSG_TYPE_ARRAY }, 149 }; 150 151 static const struct uci_blob_param_info iface_attr_info[IFACE_ATTR_MAX] = { 152 [IFACE_ATTR_UPSTREAM] = { .type = BLOBMSG_TYPE_STRING }, 153 [IFACE_ATTR_DNS] = { .type = BLOBMSG_TYPE_STRING }, 154 [IFACE_ATTR_DOMAIN] = { .type = BLOBMSG_TYPE_STRING }, 155 }; 156 157 const struct uci_blob_param_list interface_attr_list = { 158 .n_params = IFACE_ATTR_MAX, 159 .params = iface_attrs, 160 .info = iface_attr_info, 161 }; 162 163 const struct blobmsg_policy lease_attrs[LEASE_ATTR_MAX] = { 164 [LEASE_ATTR_IP] = { .name = "ip", .type = BLOBMSG_TYPE_STRING }, 165 [LEASE_ATTR_MAC] = { .name = "mac", .type = BLOBMSG_TYPE_STRING }, 166 [LEASE_ATTR_DUID] = { .name = "duid", .type = BLOBMSG_TYPE_STRING }, 167 [LEASE_ATTR_HOSTID] = { .name = "hostid", .type = BLOBMSG_TYPE_STRING }, 168 [LEASE_ATTR_LEASETIME] = { .name = "leasetime", .type = BLOBMSG_TYPE_STRING }, 169 [LEASE_ATTR_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING }, 170 }; 171 172 const struct uci_blob_param_list lease_attr_list = { 173 .n_params = LEASE_ATTR_MAX, 174 .params = lease_attrs, 175 }; 176 177 enum { 178 ODHCPD_ATTR_LEGACY, 179 ODHCPD_ATTR_MAINDHCP, 180 ODHCPD_ATTR_LEASEFILE, 181 ODHCPD_ATTR_LEASETRIGGER, 182 ODHCPD_ATTR_LOGLEVEL, 183 ODHCPD_ATTR_HOSTSFILE, 184 ODHCPD_ATTR_MAX 185 }; 186 187 static const struct blobmsg_policy odhcpd_attrs[ODHCPD_ATTR_MAX] = { 188 [ODHCPD_ATTR_LEGACY] = { .name = "legacy", .type = BLOBMSG_TYPE_BOOL }, 189 [ODHCPD_ATTR_MAINDHCP] = { .name = "maindhcp", .type = BLOBMSG_TYPE_BOOL }, 190 [ODHCPD_ATTR_LEASEFILE] = { .name = "leasefile", .type = BLOBMSG_TYPE_STRING }, 191 [ODHCPD_ATTR_LEASETRIGGER] = { .name = "leasetrigger", .type = BLOBMSG_TYPE_STRING }, 192 [ODHCPD_ATTR_LOGLEVEL] = { .name = "loglevel", .type = BLOBMSG_TYPE_INT32 }, 193 [ODHCPD_ATTR_HOSTSFILE] = { .name = "hostsfile", .type = BLOBMSG_TYPE_STRING }, 194 }; 195 196 const struct uci_blob_param_list odhcpd_attr_list = { 197 .n_params = ODHCPD_ATTR_MAX, 198 .params = odhcpd_attrs, 199 }; 200 201 static const struct { const char *name; uint8_t flag; } ra_flags[] = { 202 { .name = "managed-config", .flag = ND_RA_FLAG_MANAGED }, 203 { .name = "other-config", .flag = ND_RA_FLAG_OTHER }, 204 { .name = "home-agent", .flag = ND_RA_FLAG_HOME_AGENT }, 205 { .name = "none", . flag = 0 }, 206 { .name = NULL, }, 207 }; 208 209 static void set_interface_defaults(struct interface *iface) 210 { 211 iface->ignore = true; 212 iface->dhcpv4 = MODE_DISABLED; 213 iface->dhcpv6 = MODE_DISABLED; 214 iface->ra = MODE_DISABLED; 215 iface->ndp = MODE_DISABLED; 216 iface->learn_routes = 1; 217 iface->dhcp_leasetime = 43200; 218 iface->preferred_lifetime = 604800; /* rfc4861#section-6.2.1: AdvPreferredLifetime 7 days */ 219 iface->dhcpv4_start.s_addr = htonl(START_DEFAULT); 220 iface->dhcpv4_end.s_addr = htonl(START_DEFAULT + LIMIT_DEFAULT - 1); 221 iface->dhcpv6_assignall = true; 222 iface->dhcpv6_pd = true; 223 iface->dhcpv6_pd_min_len = 0; 224 iface->dhcpv6_na = true; 225 iface->dhcpv6_hostid_len = HOSTID_LEN_DEFAULT; 226 iface->dns_service = true; 227 iface->ra_flags = ND_RA_FLAG_OTHER; 228 iface->ra_slaac = true; 229 iface->ra_maxinterval = 600; 230 iface->ra_mininterval = iface->ra_maxinterval/3; 231 iface->ra_lifetime = -1; 232 iface->ra_dns = true; 233 } 234 235 static void clean_interface(struct interface *iface) 236 { 237 free(iface->dns); 238 free(iface->search); 239 free(iface->upstream); 240 free(iface->dhcpv4_router); 241 free(iface->dhcpv4_dns); 242 free(iface->dhcpv6_raw); 243 free(iface->filter_class); 244 free(iface->dhcpv4_ntp); 245 free(iface->dhcpv6_ntp); 246 free(iface->dhcpv6_sntp); 247 memset(&iface->ra, 0, sizeof(*iface) - offsetof(struct interface, ra)); 248 set_interface_defaults(iface); 249 } 250 251 static void close_interface(struct interface *iface) 252 { 253 avl_delete(&interfaces, &iface->avl); 254 255 router_setup_interface(iface, false); 256 dhcpv6_setup_interface(iface, false); 257 ndp_setup_interface(iface, false); 258 #ifdef DHCPV4_SUPPORT 259 dhcpv4_setup_interface(iface, false); 260 #endif 261 262 /* make sure timer is not on the timeouts list before freeing */ 263 uloop_timeout_cancel(&iface->timer_rs); 264 265 clean_interface(iface); 266 free(iface->addr4); 267 free(iface->addr6); 268 free(iface->invalid_addr6); 269 free(iface->ifname); 270 free(iface); 271 } 272 273 static int parse_mode(const char *mode) 274 { 275 if (!strcmp(mode, "disabled")) 276 return MODE_DISABLED; 277 else if (!strcmp(mode, "server")) 278 return MODE_SERVER; 279 else if (!strcmp(mode, "relay")) 280 return MODE_RELAY; 281 else if (!strcmp(mode, "hybrid")) 282 return MODE_HYBRID; 283 else 284 return -1; 285 } 286 287 static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr) 288 { 289 struct blob_attr *cur; 290 unsigned rem; 291 292 blobmsg_for_each_attr(cur, attr, rem) { 293 int i; 294 295 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 296 continue; 297 298 if (!blobmsg_check_attr(cur, false)) 299 continue; 300 301 for (i = 0; ra_flags[i].name; i++) { 302 if (!strcmp(ra_flags[i].name, blobmsg_get_string(cur))) { 303 *flags |= ra_flags[i].flag; 304 break; 305 } 306 } 307 308 if (!ra_flags[i].name) 309 return -1; 310 } 311 312 return 0; 313 } 314 315 static void set_config(struct uci_section *s) 316 { 317 struct blob_attr *tb[ODHCPD_ATTR_MAX], *c; 318 319 blob_buf_init(&b, 0); 320 uci_to_blob(&b, s, &odhcpd_attr_list); 321 blobmsg_parse(odhcpd_attrs, ODHCPD_ATTR_MAX, tb, blob_data(b.head), blob_len(b.head)); 322 323 if ((c = tb[ODHCPD_ATTR_LEGACY])) 324 config.legacy = blobmsg_get_bool(c); 325 326 if ((c = tb[ODHCPD_ATTR_MAINDHCP])) 327 config.main_dhcpv4 = blobmsg_get_bool(c); 328 329 if ((c = tb[ODHCPD_ATTR_LEASEFILE])) { 330 free(config.dhcp_statefile); 331 config.dhcp_statefile = strdup(blobmsg_get_string(c)); 332 } 333 334 if ((c = tb[ODHCPD_ATTR_HOSTSFILE])) { 335 free(config.dhcp_hostsfile); 336 config.dhcp_hostsfile = strdup(blobmsg_get_string(c)); 337 } 338 339 if ((c = tb[ODHCPD_ATTR_LEASETRIGGER])) { 340 free(config.dhcp_cb); 341 config.dhcp_cb = strdup(blobmsg_get_string(c)); 342 } 343 344 if ((c = tb[ODHCPD_ATTR_LOGLEVEL])) { 345 int log_level = (blobmsg_get_u32(c) & LOG_PRIMASK); 346 347 if (config.log_level != log_level) { 348 config.log_level = log_level; 349 setlogmask(LOG_UPTO(config.log_level)); 350 } 351 } 352 } 353 354 static double parse_leasetime(struct blob_attr *c) { 355 char *val = blobmsg_get_string(c), *endptr = NULL; 356 double time = strcmp(val, "infinite") ? strtod(val, &endptr) : UINT32_MAX; 357 358 if (time && endptr && endptr[0]) { 359 if (endptr[0] == 's') 360 time *= 1; 361 else if (endptr[0] == 'm') 362 time *= 60; 363 else if (endptr[0] == 'h') 364 time *= 3600; 365 else if (endptr[0] == 'd') 366 time *= 24 * 3600; 367 else if (endptr[0] == 'w') 368 time *= 7 * 24 * 3600; 369 else 370 goto err; 371 } 372 373 if (time < 60) 374 time = 60; 375 376 return time; 377 378 err: 379 return -1; 380 } 381 382 static void free_lease(struct lease *l) 383 { 384 free(l->hostname); 385 free(l); 386 } 387 388 389 int set_lease_from_blobmsg(struct blob_attr *ba) 390 { 391 struct blob_attr *tb[LEASE_ATTR_MAX], *c; 392 struct lease *l; 393 size_t duidlen = 0; 394 uint8_t *duid; 395 396 blobmsg_parse(lease_attrs, LEASE_ATTR_MAX, tb, blob_data(ba), blob_len(ba)); 397 398 if ((c = tb[LEASE_ATTR_DUID])) 399 duidlen = (blobmsg_data_len(c) - 1) / 2; 400 401 l = calloc_a(sizeof(*l), &duid, duidlen); 402 if (!l) 403 goto err; 404 405 if ((c = tb[LEASE_ATTR_MAC])) 406 if (!ether_aton_r(blobmsg_get_string(c), &l->mac)) 407 goto err; 408 409 if ((c = tb[LEASE_ATTR_DUID])) { 410 ssize_t len; 411 412 l->duid = duid; 413 len = odhcpd_unhexlify(l->duid, duidlen, blobmsg_get_string(c)); 414 415 if (len < 0) 416 goto err; 417 418 l->duid_len = len; 419 } 420 421 if ((c = tb[LEASE_ATTR_NAME])) { 422 l->hostname = strdup(blobmsg_get_string(c)); 423 if (!l->hostname || !odhcpd_valid_hostname(l->hostname)) 424 goto err; 425 } 426 427 if ((c = tb[LEASE_ATTR_IP])) 428 if (inet_pton(AF_INET, blobmsg_get_string(c), &l->ipaddr) < 0) 429 goto err; 430 431 if ((c = tb[LEASE_ATTR_HOSTID])) { 432 errno = 0; 433 l->hostid = strtoull(blobmsg_get_string(c), NULL, 16); 434 if (errno) 435 goto err; 436 } else { 437 uint32_t i4a = ntohl(l->ipaddr) & 0xff; 438 l->hostid = ((i4a / 100) << 8) | (((i4a % 100) / 10) << 4) | (i4a % 10); 439 } 440 441 if ((c = tb[LEASE_ATTR_LEASETIME])) { 442 double time = parse_leasetime(c); 443 if (time < 0) 444 goto err; 445 446 l->leasetime = time; 447 } 448 449 INIT_LIST_HEAD(&l->assignments); 450 vlist_add(&leases, &l->node, l); 451 return 0; 452 453 err: 454 if (l) 455 free_lease(l); 456 457 return -1; 458 } 459 460 static int set_lease_from_uci(struct uci_section *s) 461 { 462 blob_buf_init(&b, 0); 463 uci_to_blob(&b, s, &lease_attr_list); 464 465 return set_lease_from_blobmsg(b.head); 466 } 467 468 /* Parse NTP Options for DHCPv6 Address */ 469 static int parse_ntp_options(uint16_t *dhcpv6_ntp_len, struct in6_addr addr6, uint8_t **dhcpv6_ntp) 470 { 471 uint16_t sub_opt = 0, sub_len = htons(IPV6_ADDR_LEN); 472 uint16_t ntp_len = IPV6_ADDR_LEN + 4; 473 uint8_t *ntp = *dhcpv6_ntp; 474 size_t pos = *dhcpv6_ntp_len; 475 476 ntp = realloc(ntp, pos + ntp_len); 477 if (!ntp) 478 return -1; 479 480 *dhcpv6_ntp = ntp; 481 482 if (IN6_IS_ADDR_MULTICAST(&addr6)) 483 sub_opt = htons(NTP_SUBOPTION_MC_ADDR); 484 else 485 sub_opt = htons(NTP_SUBOPTION_SRV_ADDR); 486 487 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 488 pos += sizeof(sub_opt); 489 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 490 pos += sizeof(sub_len); 491 memcpy(ntp + pos, &addr6, IPV6_ADDR_LEN); 492 493 *dhcpv6_ntp_len += ntp_len; 494 495 return 0; 496 } 497 498 /* Parse NTP Options for FQDN */ 499 static int parse_ntp_fqdn(uint16_t *dhcpv6_ntp_len, char *fqdn, uint8_t **dhcpv6_ntp) 500 { 501 size_t fqdn_len = strlen(fqdn); 502 uint16_t sub_opt = 0, sub_len = 0, ntp_len = 0; 503 uint8_t *ntp = *dhcpv6_ntp; 504 size_t pos = *dhcpv6_ntp_len; 505 uint8_t buf[256] = {0}; 506 507 if (fqdn_len > 0 && fqdn[fqdn_len - 1] == '.') 508 fqdn[fqdn_len - 1] = 0; 509 510 int len = dn_comp(fqdn, buf, sizeof(buf), NULL, NULL); 511 if (len <= 0) 512 return -1; 513 514 ntp_len = len + 4; 515 516 ntp = realloc(ntp, pos + ntp_len); 517 if (!ntp) 518 return -1; 519 520 *dhcpv6_ntp = ntp; 521 522 sub_opt = htons(NTP_SUBOPTION_SRV_FQDN); 523 sub_len = htons(len); 524 525 memcpy(ntp + pos, &sub_opt, sizeof(sub_opt)); 526 pos += sizeof(sub_opt); 527 memcpy(ntp + pos, &sub_len, sizeof(sub_len)); 528 pos += sizeof(sub_len); 529 memcpy(ntp + pos, buf, len); 530 531 *dhcpv6_ntp_len += ntp_len; 532 533 return 0; 534 } 535 536 int config_parse_interface(void *data, size_t len, const char *name, bool overwrite) 537 { 538 struct odhcpd_ipaddr *addrs = NULL; 539 struct interface *iface; 540 struct blob_attr *tb[IFACE_ATTR_MAX], *c; 541 ssize_t addrs_len; 542 bool get_addrs = false; 543 int mode; 544 const char *ifname = NULL; 545 546 blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, data, len); 547 548 if (tb[IFACE_ATTR_INTERFACE]) 549 name = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]); 550 551 if (!name) 552 return -1; 553 554 iface = avl_find_element(&interfaces, name, iface, avl); 555 if (!iface) { 556 char *new_name; 557 558 iface = calloc_a(sizeof(*iface), &new_name, strlen(name) + 1); 559 if (!iface) 560 return -1; 561 562 iface->name = strcpy(new_name, name); 563 iface->avl.key = iface->name; 564 iface->router_event.uloop.fd = -1; 565 iface->dhcpv6_event.uloop.fd = -1; 566 iface->ndp_event.uloop.fd = -1; 567 iface->ndp_ping_fd = -1; 568 iface->dhcpv4_event.uloop.fd = -1; 569 INIT_LIST_HEAD(&iface->ia_assignments); 570 INIT_LIST_HEAD(&iface->dhcpv4_assignments); 571 INIT_LIST_HEAD(&iface->dhcpv4_fr_ips); 572 573 set_interface_defaults(iface); 574 575 avl_insert(&interfaces, &iface->avl); 576 get_addrs = overwrite = true; 577 } 578 579 if (overwrite) { 580 if ((c = tb[IFACE_ATTR_IFNAME])) 581 ifname = blobmsg_get_string(c); 582 else if ((c = tb[IFACE_ATTR_NETWORKID])) 583 ifname = blobmsg_get_string(c); 584 } 585 586 #ifdef WITH_UBUS 587 if (overwrite || !iface->ifname) 588 ifname = ubus_get_ifname(name); 589 #endif 590 591 if (!iface->ifname && !ifname) 592 goto err; 593 594 if (ifname) { 595 free(iface->ifname); 596 iface->ifname = strdup(ifname); 597 598 if (!iface->ifname) 599 goto err; 600 601 if (!iface->ifindex && 602 (iface->ifindex = if_nametoindex(iface->ifname)) <= 0) 603 goto err; 604 605 if ((iface->ifflags = odhcpd_get_flags(iface)) < 0) 606 goto err; 607 } 608 609 if (get_addrs) { 610 addrs_len = netlink_get_interface_addrs(iface->ifindex, 611 true, &iface->addr6); 612 613 if (addrs_len > 0) 614 iface->addr6_len = addrs_len; 615 616 addrs_len = netlink_get_interface_addrs(iface->ifindex, 617 false, &iface->addr4); 618 if (addrs_len > 0) 619 iface->addr4_len = addrs_len; 620 } 621 622 addrs_len = netlink_get_interface_linklocal(iface->ifindex, &addrs); 623 if (addrs_len > 0) { 624 for (ssize_t i = 0; i < addrs_len; i++) { 625 struct odhcpd_ipaddr *addr = &addrs[i]; 626 627 if (!addr->tentative) { 628 iface->have_link_local = true; 629 break; 630 } 631 } 632 } 633 634 iface->inuse = true; 635 636 if ((c = tb[IFACE_ATTR_DYNAMICDHCP])) 637 iface->no_dynamic_dhcp = !blobmsg_get_bool(c); 638 639 if ((c = tb[IFACE_ATTR_LEASETIME])) { 640 double time = parse_leasetime(c); 641 642 if (time >= 0) 643 iface->dhcp_leasetime = time; 644 else 645 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 646 iface_attrs[IFACE_ATTR_LEASETIME].name, iface->name); 647 648 } 649 650 if ((c = tb[IFACE_ATTR_PREFERRED_LIFETIME])) { 651 double time = parse_leasetime(c); 652 653 if (time >= 0) 654 iface->preferred_lifetime = time; 655 else 656 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 657 iface_attrs[IFACE_ATTR_PREFERRED_LIFETIME].name, iface->name); 658 659 } 660 661 if ((c = tb[IFACE_ATTR_START])) { 662 iface->dhcpv4_start.s_addr = htonl(blobmsg_get_u32(c)); 663 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 664 LIMIT_DEFAULT - 1); 665 666 if (config.main_dhcpv4 && config.legacy) 667 iface->dhcpv4 = MODE_SERVER; 668 } 669 670 if ((c = tb[IFACE_ATTR_LIMIT])) 671 iface->dhcpv4_end.s_addr = htonl(ntohl(iface->dhcpv4_start.s_addr) + 672 blobmsg_get_u32(c) - 1); 673 674 if ((c = tb[IFACE_ATTR_MASTER])) 675 iface->master = blobmsg_get_bool(c); 676 677 if (overwrite && (c = tb[IFACE_ATTR_UPSTREAM])) { 678 struct blob_attr *cur; 679 unsigned rem; 680 681 blobmsg_for_each_attr(cur, c, rem) { 682 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 683 continue; 684 685 iface->upstream = realloc(iface->upstream, 686 iface->upstream_len + blobmsg_data_len(cur)); 687 if (!iface->upstream) 688 goto err; 689 690 memcpy(iface->upstream + iface->upstream_len, blobmsg_get_string(cur), blobmsg_data_len(cur)); 691 iface->upstream_len += blobmsg_data_len(cur); 692 } 693 } 694 695 if ((c = tb[IFACE_ATTR_RA])) { 696 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 697 iface->ra = mode; 698 699 if (iface->ra != MODE_DISABLED) 700 iface->ignore = false; 701 } else 702 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 703 iface_attrs[IFACE_ATTR_RA].name, iface->name); 704 } 705 706 if ((c = tb[IFACE_ATTR_DHCPV4])) { 707 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 708 if (config.main_dhcpv4) { 709 iface->dhcpv4 = mode; 710 711 if (iface->dhcpv4 != MODE_DISABLED) 712 iface->ignore = false; 713 } 714 } else 715 syslog(LOG_ERR, "Invalid %s mode configured for interface %s", 716 iface_attrs[IFACE_ATTR_DHCPV4].name, iface->name); 717 } 718 719 if ((c = tb[IFACE_ATTR_DHCPV6])) { 720 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 721 iface->dhcpv6 = mode; 722 723 if (iface->dhcpv6 != MODE_DISABLED) 724 iface->ignore = false; 725 } else 726 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 727 iface_attrs[IFACE_ATTR_DHCPV6].name, iface->name); 728 } 729 730 if ((c = tb[IFACE_ATTR_NDP])) { 731 if ((mode = parse_mode(blobmsg_get_string(c))) >= 0) { 732 iface->ndp = mode; 733 734 if (iface->ndp != MODE_DISABLED) 735 iface->ignore = false; 736 } else 737 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 738 iface_attrs[IFACE_ATTR_NDP].name, iface->name); 739 } 740 741 if ((c = tb[IFACE_ATTR_ROUTER])) { 742 struct blob_attr *cur; 743 unsigned rem; 744 745 blobmsg_for_each_attr(cur, c, rem) { 746 struct in_addr addr4; 747 748 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 749 continue; 750 751 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 752 iface->dhcpv4_router = realloc(iface->dhcpv4_router, 753 (++iface->dhcpv4_router_cnt) * sizeof(*iface->dhcpv4_router)); 754 if (!iface->dhcpv4_router) 755 goto err; 756 757 iface->dhcpv4_router[iface->dhcpv4_router_cnt - 1] = addr4; 758 } else 759 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 760 iface_attrs[IFACE_ATTR_ROUTER].name, iface->name); 761 } 762 } 763 764 if ((c = tb[IFACE_ATTR_DNS])) { 765 struct blob_attr *cur; 766 unsigned rem; 767 768 iface->always_rewrite_dns = true; 769 blobmsg_for_each_attr(cur, c, rem) { 770 struct in_addr addr4; 771 struct in6_addr addr6; 772 773 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 774 continue; 775 776 if (inet_pton(AF_INET, blobmsg_get_string(cur), &addr4) == 1) { 777 if (addr4.s_addr == INADDR_ANY) { 778 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 779 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 780 781 continue; 782 } 783 784 iface->dhcpv4_dns = realloc(iface->dhcpv4_dns, 785 (++iface->dhcpv4_dns_cnt) * sizeof(*iface->dhcpv4_dns)); 786 if (!iface->dhcpv4_dns) 787 goto err; 788 789 iface->dhcpv4_dns[iface->dhcpv4_dns_cnt - 1] = addr4; 790 } else if (inet_pton(AF_INET6, blobmsg_get_string(cur), &addr6) == 1) { 791 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { 792 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 793 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 794 795 continue; 796 } 797 798 iface->dns = realloc(iface->dns, 799 (++iface->dns_cnt) * sizeof(*iface->dns)); 800 if (!iface->dns) 801 goto err; 802 803 iface->dns[iface->dns_cnt - 1] = addr6; 804 } else 805 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 806 iface_attrs[IFACE_ATTR_DNS].name, iface->name); 807 } 808 } 809 810 if ((c = tb[IFACE_ATTR_DNS_SERVICE])) 811 iface->dns_service = blobmsg_get_bool(c); 812 813 if ((c = tb[IFACE_ATTR_DOMAIN])) { 814 struct blob_attr *cur; 815 unsigned rem; 816 817 blobmsg_for_each_attr(cur, c, rem) { 818 uint8_t buf[256]; 819 char *domain = blobmsg_get_string(cur); 820 size_t domainlen = strlen(domain); 821 int len; 822 823 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 824 continue; 825 826 domain = blobmsg_get_string(cur); 827 domainlen = strlen(domain); 828 829 if (domainlen > 0 && domain[domainlen - 1] == '.') 830 domain[domainlen - 1] = 0; 831 832 len = dn_comp(domain, buf, sizeof(buf), NULL, NULL); 833 if (len <= 0) { 834 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 835 iface_attrs[IFACE_ATTR_DOMAIN].name, iface->name); 836 837 continue; 838 } 839 840 iface->search = realloc(iface->search, iface->search_len + len); 841 if (!iface->search) 842 goto err; 843 844 memcpy(&iface->search[iface->search_len], buf, len); 845 iface->search_len += len; 846 } 847 } 848 849 if ((c = tb[IFACE_ATTR_FILTER_CLASS])) { 850 iface->filter_class = realloc(iface->filter_class, blobmsg_data_len(c) + 1); 851 memcpy(iface->filter_class, blobmsg_get_string(c), blobmsg_data_len(c) + 1); 852 } 853 854 if ((c = tb[IFACE_ATTR_DHCPV4_FORCERECONF])) 855 iface->dhcpv4_forcereconf = blobmsg_get_bool(c); 856 857 if ((c = tb[IFACE_ATTR_DHCPV6_RAW])) { 858 iface->dhcpv6_raw_len = blobmsg_data_len(c) / 2; 859 iface->dhcpv6_raw = realloc(iface->dhcpv6_raw, iface->dhcpv6_raw_len); 860 odhcpd_unhexlify(iface->dhcpv6_raw, iface->dhcpv6_raw_len, blobmsg_get_string(c)); 861 } 862 863 if ((c = tb[IFACE_ATTR_DHCPV6_ASSIGNALL])) 864 iface->dhcpv6_assignall = blobmsg_get_bool(c); 865 866 if ((c = tb[IFACE_ATTR_DHCPV6_PD])) 867 iface->dhcpv6_pd = blobmsg_get_bool(c); 868 869 if ((c = tb[IFACE_ATTR_DHCPV6_PD_MIN_LEN])) { 870 uint32_t pd_min_len = blobmsg_get_u32(c); 871 if (pd_min_len != 0 && pd_min_len <= PD_MIN_LEN_MAX) 872 iface->dhcpv6_pd_min_len = pd_min_len; 873 else 874 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 875 iface_attrs[IFACE_ATTR_DHCPV6_PD_MIN_LEN].name, iface->name); 876 } 877 878 if ((c = tb[IFACE_ATTR_DHCPV6_NA])) 879 iface->dhcpv6_na = blobmsg_get_bool(c); 880 881 if ((c = tb[IFACE_ATTR_DHCPV6_HOSTID_LEN])) { 882 uint32_t hostid_len = blobmsg_get_u32(c); 883 884 if (hostid_len >= HOSTID_LEN_MIN && hostid_len <= HOSTID_LEN_MAX) 885 iface->dhcpv6_hostid_len = hostid_len; 886 else 887 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 888 iface_attrs[IFACE_ATTR_DHCPV6_HOSTID_LEN].name, iface->name); 889 890 } 891 892 if ((c = tb[IFACE_ATTR_RA_DEFAULT])) 893 iface->default_router = blobmsg_get_u32(c); 894 895 /* IFACE_ATTR_RA_MANAGEMENT aka ra_management is deprecated since 2019 */ 896 if (!tb[IFACE_ATTR_RA_FLAGS] && !tb[IFACE_ATTR_RA_SLAAC] && 897 (c = tb[IFACE_ATTR_RA_MANAGEMENT])) { 898 switch (blobmsg_get_u32(c)) { 899 case 0: 900 iface->ra_flags = ND_RA_FLAG_OTHER; 901 iface->ra_slaac = true; 902 break; 903 case 1: 904 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 905 iface->ra_slaac = true; 906 break; 907 case 2: 908 iface->ra_flags = ND_RA_FLAG_OTHER|ND_RA_FLAG_MANAGED; 909 iface->ra_slaac = false; 910 break; 911 default: 912 break; 913 } 914 } 915 916 if ((c = tb[IFACE_ATTR_RA_FLAGS])) { 917 iface->ra_flags = 0; 918 919 if (parse_ra_flags(&iface->ra_flags, c) < 0) 920 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 921 iface_attrs[IFACE_ATTR_RA_FLAGS].name, iface->name); 922 } 923 924 if ((c = tb[IFACE_ATTR_RA_REACHABLETIME])) { 925 uint32_t ra_reachabletime = blobmsg_get_u32(c); 926 927 if (ra_reachabletime <= 3600000) 928 iface->ra_reachabletime = ra_reachabletime; 929 else 930 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 931 iface_attrs[IFACE_ATTR_RA_REACHABLETIME].name, iface->name); 932 } 933 934 if ((c = tb[IFACE_ATTR_RA_RETRANSTIME])) { 935 uint32_t ra_retranstime = blobmsg_get_u32(c); 936 937 if (ra_retranstime <= 60000) 938 iface->ra_retranstime = ra_retranstime; 939 else 940 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 941 iface_attrs[IFACE_ATTR_RA_RETRANSTIME].name, iface->name); 942 } 943 944 if ((c = tb[IFACE_ATTR_RA_HOPLIMIT])) { 945 uint32_t ra_hoplimit = blobmsg_get_u32(c); 946 947 if (ra_hoplimit <= 255) 948 iface->ra_hoplimit = ra_hoplimit; 949 else 950 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 951 iface_attrs[IFACE_ATTR_RA_HOPLIMIT].name, iface->name); 952 } 953 954 if ((c = tb[IFACE_ATTR_RA_MTU])) { 955 uint32_t ra_mtu = blobmsg_get_u32(c); 956 957 if (ra_mtu >= 1280 || ra_mtu <= 65535) 958 iface->ra_mtu = ra_mtu; 959 else 960 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 961 iface_attrs[IFACE_ATTR_RA_MTU].name, iface->name); 962 } 963 964 if ((c = tb[IFACE_ATTR_RA_SLAAC])) 965 iface->ra_slaac = blobmsg_get_bool(c); 966 967 if ((c = tb[IFACE_ATTR_RA_OFFLINK])) 968 iface->ra_not_onlink = blobmsg_get_bool(c); 969 970 if ((c = tb[IFACE_ATTR_RA_ADVROUTER])) 971 iface->ra_advrouter = blobmsg_get_bool(c); 972 973 if ((c = tb[IFACE_ATTR_RA_MININTERVAL])) 974 iface->ra_mininterval = blobmsg_get_u32(c); 975 976 if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])) 977 iface->ra_maxinterval = blobmsg_get_u32(c); 978 979 if ((c = tb[IFACE_ATTR_RA_LIFETIME])) 980 iface->ra_lifetime = blobmsg_get_u32(c); 981 982 if ((c = tb[IFACE_ATTR_RA_USELEASETIME])) 983 iface->ra_useleasetime = blobmsg_get_bool(c); 984 985 if ((c = tb[IFACE_ATTR_RA_DNS])) 986 iface->ra_dns = blobmsg_get_bool(c); 987 988 if ((c = tb[IFACE_ATTR_RA_PREF64])) { 989 const char *str = blobmsg_get_string(c); 990 char *astr = malloc(strlen(str) + 1); 991 char *delim; 992 int l; 993 994 if (!astr || !strcpy(astr, str) || 995 (delim = strchr(astr, '/')) == NULL || (*(delim++) = 0) || 996 sscanf(delim, "%i", &l) == 0 || l > 128 || 997 inet_pton(AF_INET6, astr, &iface->pref64_addr) == 0) 998 iface->pref64_length = 0; 999 else 1000 iface->pref64_length = l; 1001 1002 if (astr) 1003 free(astr); 1004 } 1005 1006 if ((c = tb[IFACE_ATTR_RA_PREFERENCE])) { 1007 const char *prio = blobmsg_get_string(c); 1008 1009 if (!strcmp(prio, "high")) 1010 iface->route_preference = 1; 1011 else if (!strcmp(prio, "low")) 1012 iface->route_preference = -1; 1013 else if (!strcmp(prio, "medium") || !strcmp(prio, "default")) 1014 iface->route_preference = 0; 1015 else 1016 syslog(LOG_ERR, "Invalid %s mode configured for interface '%s'", 1017 iface_attrs[IFACE_ATTR_RA_PREFERENCE].name, iface->name); 1018 } 1019 1020 if ((c = tb[IFACE_ATTR_PD_MANAGER])) 1021 strncpy(iface->dhcpv6_pd_manager, blobmsg_get_string(c), 1022 sizeof(iface->dhcpv6_pd_manager) - 1); 1023 1024 if ((c = tb[IFACE_ATTR_PD_CER]) && 1025 inet_pton(AF_INET6, blobmsg_get_string(c), &iface->dhcpv6_pd_cer) < 1) 1026 syslog(LOG_ERR, "Invalid %s value configured for interface '%s'", 1027 iface_attrs[IFACE_ATTR_PD_CER].name, iface->name); 1028 1029 if ((c = tb[IFACE_ATTR_NDPROXY_ROUTING])) 1030 iface->learn_routes = blobmsg_get_bool(c); 1031 1032 if ((c = tb[IFACE_ATTR_NDPROXY_SLAVE])) 1033 iface->external = blobmsg_get_bool(c); 1034 1035 if ((c = tb[IFACE_ATTR_PREFIX_FILTER])) { 1036 const char *str = blobmsg_get_string(c); 1037 char *astr = malloc(strlen(str) + 1); 1038 char *delim; 1039 int l; 1040 1041 if (!astr || !strcpy(astr, str) || 1042 (delim = strchr(astr, '/')) == NULL || (*(delim++) = 0) || 1043 sscanf(delim, "%i", &l) == 0 || l > 128 || 1044 inet_pton(AF_INET6, astr, &iface->pio_filter_addr) == 0) 1045 iface->pio_filter_length = 0; 1046 else 1047 iface->pio_filter_length = l; 1048 1049 if (astr) 1050 free(astr); 1051 } 1052 1053 if (overwrite && (c = tb[IFACE_ATTR_NTP])) { 1054 struct blob_attr *cur; 1055 unsigned rem; 1056 1057 blobmsg_for_each_attr(cur, c, rem) { 1058 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING || !blobmsg_check_attr(cur, false)) 1059 continue; 1060 1061 char *str = blobmsg_get_string(cur); 1062 struct in_addr addr4; 1063 struct in6_addr addr6; 1064 1065 if (inet_pton(AF_INET, str, &addr4) == 1) { 1066 if (addr4.s_addr == INADDR_ANY) 1067 goto err; 1068 1069 iface->dhcpv4_ntp = realloc(iface->dhcpv4_ntp, 1070 (++iface->dhcpv4_ntp_cnt) * sizeof(*iface->dhcpv4_ntp)); 1071 if (!iface->dhcpv4_ntp) 1072 goto err; 1073 1074 iface->dhcpv4_ntp[iface->dhcpv4_ntp_cnt - 1] = addr4; 1075 } else if (inet_pton(AF_INET6, str, &addr6) == 1) { 1076 if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) 1077 goto err; 1078 1079 iface->dhcpv6_sntp = realloc(iface->dhcpv6_sntp, 1080 (++iface->dhcpv6_sntp_cnt) * sizeof(*iface->dhcpv6_sntp)); 1081 if (!iface->dhcpv6_sntp) 1082 goto err; 1083 1084 iface->dhcpv6_sntp[iface->dhcpv6_sntp_cnt - 1] = addr6; 1085 1086 if (!parse_ntp_options(&iface->dhcpv6_ntp_len, addr6, &iface->dhcpv6_ntp)) 1087 iface->dhcpv6_ntp_cnt++; 1088 } else { 1089 if (!parse_ntp_fqdn(&iface->dhcpv6_ntp_len, str, &iface->dhcpv6_ntp)) 1090 iface->dhcpv6_ntp_cnt++; 1091 } 1092 } 1093 } 1094 1095 return 0; 1096 1097 err: 1098 close_interface(iface); 1099 return -1; 1100 } 1101 1102 static int set_interface(struct uci_section *s) 1103 { 1104 blob_buf_init(&b, 0); 1105 uci_to_blob(&b, s, &interface_attr_list); 1106 1107 return config_parse_interface(blob_data(b.head), blob_len(b.head), s->e.name, true); 1108 } 1109 1110 static void lease_delete_assignments(struct lease *l, bool v6) 1111 { 1112 struct dhcp_assignment *a, *tmp; 1113 unsigned int flag = v6 ? OAF_DHCPV6 : OAF_DHCPV4; 1114 1115 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) { 1116 if (a->flags & flag) 1117 free_assignment(a); 1118 } 1119 } 1120 1121 static void lease_update_assignments(struct lease *l) 1122 { 1123 struct dhcp_assignment *a; 1124 1125 list_for_each_entry(a, &l->assignments, lease_list) { 1126 if (a->hostname) 1127 free(a->hostname); 1128 a->hostname = NULL; 1129 1130 if (l->hostname) 1131 a->hostname = strdup(l->hostname); 1132 1133 a->leasetime = l->leasetime; 1134 } 1135 } 1136 1137 static int lease_cmp(const void *k1, const void *k2, _unused void *ptr) 1138 { 1139 const struct lease *l1 = k1, *l2 = k2; 1140 int cmp = 0; 1141 1142 if (l1->duid_len != l2->duid_len) 1143 return l1->duid_len - l2->duid_len; 1144 1145 if (l1->duid_len && l2->duid_len) 1146 cmp = memcmp(l1->duid, l2->duid, l1->duid_len); 1147 1148 if (cmp) 1149 return cmp; 1150 1151 return memcmp(l1->mac.ether_addr_octet, l2->mac.ether_addr_octet, 1152 sizeof(l1->mac.ether_addr_octet)); 1153 } 1154 1155 static void lease_change_config(struct lease *l_old, struct lease *l_new) 1156 { 1157 bool update = false; 1158 1159 if ((!!l_new->hostname != !!l_old->hostname) || 1160 (l_new->hostname && strcmp(l_new->hostname, l_old->hostname))) { 1161 free(l_old->hostname); 1162 l_old->hostname = NULL; 1163 1164 if (l_new->hostname) 1165 l_old->hostname = strdup(l_new->hostname); 1166 1167 update = true; 1168 } 1169 1170 if (l_old->leasetime != l_new->leasetime) { 1171 l_old->leasetime = l_new->leasetime; 1172 update = true; 1173 } 1174 1175 if (l_old->ipaddr != l_new->ipaddr) { 1176 l_old->ipaddr = l_new->ipaddr; 1177 lease_delete_assignments(l_old, false); 1178 } 1179 1180 if (l_old->hostid != l_new->hostid) { 1181 l_old->hostid = l_new->hostid; 1182 lease_delete_assignments(l_old, true); 1183 } 1184 1185 if (update) 1186 lease_update_assignments(l_old); 1187 1188 free_lease(l_new); 1189 } 1190 1191 static void lease_delete(struct lease *l) 1192 { 1193 struct dhcp_assignment *a, *tmp; 1194 1195 list_for_each_entry_safe(a, tmp, &l->assignments, lease_list) 1196 free_assignment(a); 1197 1198 free_lease(l); 1199 } 1200 1201 static void lease_update(_unused struct vlist_tree *tree, struct vlist_node *node_new, 1202 struct vlist_node *node_old) 1203 { 1204 struct lease *lease_new = container_of(node_new, struct lease, node); 1205 struct lease *lease_old = container_of(node_old, struct lease, node); 1206 1207 if (node_old && node_new) 1208 lease_change_config(lease_old, lease_new); 1209 else if (node_old) 1210 lease_delete(lease_old); 1211 } 1212 1213 struct lease *config_find_lease_by_duid(const uint8_t *duid, const uint16_t len) 1214 { 1215 struct lease *l; 1216 1217 vlist_for_each_element(&leases, l, node) { 1218 if (l->duid_len == len && !memcmp(l->duid, duid, len)) 1219 return l; 1220 } 1221 1222 return NULL; 1223 } 1224 1225 struct lease *config_find_lease_by_mac(const uint8_t *mac) 1226 { 1227 struct lease *l; 1228 1229 vlist_for_each_element(&leases, l, node) { 1230 if (!memcmp(l->mac.ether_addr_octet, mac, 1231 sizeof(l->mac.ether_addr_octet))) 1232 return l; 1233 } 1234 1235 return NULL; 1236 } 1237 1238 struct lease *config_find_lease_by_hostid(const uint64_t hostid) 1239 { 1240 struct lease *l; 1241 1242 vlist_for_each_element(&leases, l, node) { 1243 if (l->hostid == hostid) 1244 return l; 1245 } 1246 1247 return NULL; 1248 } 1249 1250 struct lease *config_find_lease_by_ipaddr(const uint32_t ipaddr) 1251 { 1252 struct lease *l; 1253 1254 vlist_for_each_element(&leases, l, node) { 1255 if (l->ipaddr == ipaddr) 1256 return l; 1257 } 1258 1259 return NULL; 1260 } 1261 1262 void reload_services(struct interface *iface) 1263 { 1264 if (iface->ifflags & IFF_RUNNING) { 1265 syslog(LOG_DEBUG, "Enabling services with %s running", iface->ifname); 1266 router_setup_interface(iface, iface->ra != MODE_DISABLED); 1267 dhcpv6_setup_interface(iface, iface->dhcpv6 != MODE_DISABLED); 1268 ndp_setup_interface(iface, iface->ndp != MODE_DISABLED); 1269 #ifdef DHCPV4_SUPPORT 1270 dhcpv4_setup_interface(iface, iface->dhcpv4 != MODE_DISABLED); 1271 #endif 1272 } else { 1273 syslog(LOG_DEBUG, "Disabling services with %s not running", iface->ifname); 1274 router_setup_interface(iface, false); 1275 dhcpv6_setup_interface(iface, false); 1276 ndp_setup_interface(iface, false); 1277 #ifdef DHCPV4_SUPPORT 1278 dhcpv4_setup_interface(iface, false); 1279 #endif 1280 } 1281 } 1282 1283 void odhcpd_reload(void) 1284 { 1285 struct uci_context *uci = uci_alloc_context(); 1286 struct interface *master = NULL, *i, *tmp; 1287 1288 if (!uci) 1289 return; 1290 1291 vlist_update(&leases); 1292 avl_for_each_element(&interfaces, i, avl) 1293 clean_interface(i); 1294 1295 struct uci_package *dhcp = NULL; 1296 if (!uci_load(uci, "dhcp", &dhcp)) { 1297 struct uci_element *e; 1298 1299 /* 1. Global settings */ 1300 uci_foreach_element(&dhcp->sections, e) { 1301 struct uci_section *s = uci_to_section(e); 1302 if (!strcmp(s->type, "odhcpd")) 1303 set_config(s); 1304 } 1305 1306 /* 2. DHCP pools */ 1307 uci_foreach_element(&dhcp->sections, e) { 1308 struct uci_section *s = uci_to_section(e); 1309 if (!strcmp(s->type, "dhcp")) 1310 set_interface(s); 1311 } 1312 1313 /* 3. Static leases */ 1314 uci_foreach_element(&dhcp->sections, e) { 1315 struct uci_section* s = uci_to_section(e); 1316 if (!strcmp(s->type, "host")) 1317 set_lease_from_uci(s); 1318 } 1319 } 1320 1321 if (config.dhcp_statefile) { 1322 char *path = strdup(config.dhcp_statefile); 1323 1324 mkdir_p(dirname(path), 0755); 1325 free(path); 1326 } 1327 1328 vlist_flush(&leases); 1329 1330 #ifdef WITH_UBUS 1331 ubus_apply_network(); 1332 #endif 1333 1334 bool any_dhcpv6_slave = false, any_ra_slave = false, any_ndp_slave = false; 1335 1336 /* Test for */ 1337 avl_for_each_element(&interfaces, i, avl) { 1338 if (i->master) 1339 continue; 1340 1341 if (i->dhcpv6 == MODE_HYBRID || i->dhcpv6 == MODE_RELAY) 1342 any_dhcpv6_slave = true; 1343 1344 if (i->ra == MODE_HYBRID || i->ra == MODE_RELAY) 1345 any_ra_slave = true; 1346 1347 if (i->ndp == MODE_HYBRID || i->ndp == MODE_RELAY) 1348 any_ndp_slave = true; 1349 } 1350 1351 /* Evaluate hybrid mode for master */ 1352 avl_for_each_element(&interfaces, i, avl) { 1353 if (!i->master) 1354 continue; 1355 1356 enum odhcpd_mode hybrid_mode = MODE_DISABLED; 1357 #ifdef WITH_UBUS 1358 if (!ubus_has_prefix(i->name, i->ifname)) 1359 hybrid_mode = MODE_RELAY; 1360 #endif 1361 1362 if (i->dhcpv6 == MODE_HYBRID) 1363 i->dhcpv6 = hybrid_mode; 1364 1365 if (i->dhcpv6 == MODE_RELAY && !any_dhcpv6_slave) 1366 i->dhcpv6 = MODE_DISABLED; 1367 1368 if (i->ra == MODE_HYBRID) 1369 i->ra = hybrid_mode; 1370 1371 if (i->ra == MODE_RELAY && !any_ra_slave) 1372 i->ra = MODE_DISABLED; 1373 1374 if (i->ndp == MODE_HYBRID) 1375 i->ndp = hybrid_mode; 1376 1377 if (i->ndp == MODE_RELAY && !any_ndp_slave) 1378 i->ndp = MODE_DISABLED; 1379 1380 if (i->dhcpv6 == MODE_RELAY || i->ra == MODE_RELAY || i->ndp == MODE_RELAY) 1381 master = i; 1382 } 1383 1384 1385 avl_for_each_element_safe(&interfaces, i, avl, tmp) { 1386 if (i->inuse && i->ifflags & IFF_RUNNING) { 1387 /* Resolve hybrid mode */ 1388 if (i->dhcpv6 == MODE_HYBRID) 1389 i->dhcpv6 = (master && master->dhcpv6 == MODE_RELAY) ? 1390 MODE_RELAY : MODE_SERVER; 1391 1392 if (i->ra == MODE_HYBRID) 1393 i->ra = (master && master->ra == MODE_RELAY) ? 1394 MODE_RELAY : MODE_SERVER; 1395 1396 if (i->ndp == MODE_HYBRID) 1397 i->ndp = (master && master->ndp == MODE_RELAY) ? 1398 MODE_RELAY : MODE_DISABLED; 1399 1400 reload_services(i); 1401 } else 1402 close_interface(i); 1403 } 1404 1405 uci_unload(uci, dhcp); 1406 uci_free_context(uci); 1407 } 1408 1409 static void handle_signal(int signal) 1410 { 1411 char b[1] = {0}; 1412 1413 if (signal == SIGHUP) { 1414 if (write(reload_pipe[1], b, sizeof(b)) < 0) {} 1415 } else 1416 uloop_end(); 1417 } 1418 1419 static void reload_cb(struct uloop_fd *u, _unused unsigned int events) 1420 { 1421 char b[512]; 1422 if (read(u->fd, b, sizeof(b)) < 0) {} 1423 1424 odhcpd_reload(); 1425 } 1426 1427 static struct uloop_fd reload_fd = { .fd = -1, .cb = reload_cb }; 1428 1429 void odhcpd_run(void) 1430 { 1431 if (pipe2(reload_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {} 1432 1433 reload_fd.fd = reload_pipe[0]; 1434 uloop_fd_add(&reload_fd, ULOOP_READ); 1435 1436 signal(SIGTERM, handle_signal); 1437 signal(SIGINT, handle_signal); 1438 signal(SIGHUP, handle_signal); 1439 1440 #ifdef WITH_UBUS 1441 while (ubus_init()) 1442 sleep(1); 1443 #endif 1444 1445 odhcpd_reload(); 1446 uloop_run(); 1447 } 1448
This page was automatically generated by LXR 0.3.1. • OpenWrt