1/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 dated June, 1991, or 6 (at your option) version 3 dated 29 June, 2007. 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 You should have received a copy of the GNU General Public License 14 along with this program. If not, see <http://www.gnu.org/licenses/>. 15*/ 16 17#include "dnsmasq.h" 18 19#ifdef HAVE_DHCP 20 21struct iface_param { 22 struct in_addr relay, primary; 23 struct dhcp_context *current; 24 int ind; 25}; 26 27static int complete_context(struct in_addr local, int if_index, 28 struct in_addr netmask, struct in_addr broadcast, void *vparam); 29 30void dhcp_init(void) 31{ 32 int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 33 struct sockaddr_in saddr; 34 int oneopt = 1; 35#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 36 int mtu = IP_PMTUDISC_DONT; 37#endif 38 39 if (fd == -1) 40 die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET); 41 42 if (!fix_fd(fd) || 43#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) 44 setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 || 45#endif 46#if defined(HAVE_LINUX_NETWORK) 47 setsockopt(fd, SOL_IP, IP_PKTINFO, &oneopt, sizeof(oneopt)) == -1 || 48#else 49 setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 || 50#endif 51 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1) 52 die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET); 53 54 /* When bind-interfaces is set, there might be more than one dnmsasq 55 instance binding port 67. That's OK if they serve different networks. 56 Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */ 57 if (daemon->options & OPT_NOWILD) 58 { 59#ifdef SO_REUSEPORT 60 int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt)); 61#else 62 int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt)); 63#endif 64 if (rc == -1) 65 die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET); 66 } 67 68 memset(&saddr, 0, sizeof(saddr)); 69 saddr.sin_family = AF_INET; 70 saddr.sin_port = htons(daemon->dhcp_server_port); 71 saddr.sin_addr.s_addr = INADDR_ANY; 72#ifdef HAVE_SOCKADDR_SA_LEN 73 saddr.sin_len = sizeof(struct sockaddr_in); 74#endif 75 76 if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in))) 77 die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET); 78 79 daemon->dhcpfd = fd; 80 81#if defined(HAVE_BSD_NETWORK) 82 /* When we're not using capabilities, we need to do this here before 83 we drop root. Also, set buffer size small, to avoid wasting 84 kernel buffers */ 85 86 if (daemon->options & OPT_NO_PING) 87 daemon->dhcp_icmp_fd = -1; 88 else if ((daemon->dhcp_icmp_fd = make_icmp_sock()) == -1 || 89 setsockopt(daemon->dhcp_icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) == -1 ) 90 die(_("cannot create ICMP raw socket: %s."), NULL, EC_BADNET); 91 92 /* Make BPF raw send socket */ 93 init_bpf(); 94#endif 95 96 check_dhcp_hosts(1); 97 98 daemon->dhcp_packet.iov_len = sizeof(struct dhcp_packet); 99 daemon->dhcp_packet.iov_base = safe_malloc(daemon->dhcp_packet.iov_len); 100} 101 102void dhcp_packet(time_t now) 103{ 104 struct dhcp_packet *mess; 105 struct dhcp_context *context; 106 struct iname *tmp; 107 struct ifreq ifr; 108 struct msghdr msg; 109 struct sockaddr_in dest; 110 struct cmsghdr *cmptr; 111 struct iovec iov; 112 ssize_t sz; 113 int iface_index = 0, unicast_dest = 0, is_inform = 0; 114 struct in_addr iface_addr, *addrp = NULL; 115 struct iface_param parm; 116 117 union { 118 struct cmsghdr align; /* this ensures alignment */ 119#if defined(HAVE_LINUX_NETWORK) 120 char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; 121#elif defined(HAVE_SOLARIS_NETWORK) 122 char control[CMSG_SPACE(sizeof(unsigned int))]; 123#elif defined(HAVE_BSD_NETWORK) 124 char control[CMSG_SPACE(sizeof(struct sockaddr_dl))]; 125#endif 126 } control_u; 127 128 msg.msg_control = NULL; 129 msg.msg_controllen = 0; 130 msg.msg_name = NULL; 131 msg.msg_namelen = 0; 132 msg.msg_iov = &daemon->dhcp_packet; 133 msg.msg_iovlen = 1; 134 135 while (1) 136 { 137 msg.msg_flags = 0; 138 while ((sz = recvmsg(daemon->dhcpfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR); 139 140 if (sz == -1) 141 return; 142 143 if (!(msg.msg_flags & MSG_TRUNC)) 144 break; 145 146 /* Very new Linux kernels return the actual size needed, 147 older ones always return truncated size */ 148 if ((size_t)sz == daemon->dhcp_packet.iov_len) 149 { 150 if (!expand_buf(&daemon->dhcp_packet, sz + 100)) 151 return; 152 } 153 else 154 { 155 expand_buf(&daemon->dhcp_packet, sz); 156 break; 157 } 158 } 159 160 /* expand_buf may have moved buffer */ 161 mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base; 162 msg.msg_controllen = sizeof(control_u); 163 msg.msg_control = control_u.control; 164 msg.msg_flags = 0; 165 msg.msg_name = &dest; 166 msg.msg_namelen = sizeof(dest); 167 168 while ((sz = recvmsg(daemon->dhcpfd, &msg, 0)) == -1 && errno == EINTR); 169 170 if ((msg.msg_flags & MSG_TRUNC) || sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options))) 171 return; 172 173#if defined (HAVE_LINUX_NETWORK) 174 if (msg.msg_controllen >= sizeof(struct cmsghdr)) 175 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 176 if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) 177 { 178 iface_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex; 179 if (((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_addr.s_addr != INADDR_BROADCAST) 180 unicast_dest = 1; 181 } 182 183#elif defined(HAVE_BSD_NETWORK) 184 if (msg.msg_controllen >= sizeof(struct cmsghdr)) 185 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 186 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) 187 iface_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index; 188 189 190#elif defined(HAVE_SOLARIS_NETWORK) 191 if (msg.msg_controllen >= sizeof(struct cmsghdr)) 192 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 193 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) 194 iface_index = *((unsigned int *)CMSG_DATA(cmptr)); 195 196#endif 197 198 if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name)) 199 return; 200 201#ifdef MSG_BCAST 202 /* OpenBSD tells us when a packet was broadcast */ 203 if (!(msg.msg_flags & MSG_BCAST)) 204 unicast_dest = 1; 205#endif 206 207 ifr.ifr_addr.sa_family = AF_INET; 208 if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 ) 209 { 210 addrp = &iface_addr; 211 iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; 212 } 213 214 if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, &iface_index)) 215 return; 216 217 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) 218 if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) 219 return; 220 221 /* interface may have been changed by alias in iface_check */ 222 if (!addrp) 223 { 224 if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) == -1) 225 { 226 my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name); 227 return; 228 } 229 else 230 iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; 231 } 232 233 /* unlinked contexts are marked by context->current == context */ 234 for (context = daemon->dhcp; context; context = context->next) 235 context->current = context; 236 237 parm.relay = mess->giaddr; 238 parm.primary = iface_addr; 239 parm.current = NULL; 240 parm.ind = iface_index; 241 242 if (!iface_enumerate(&parm, complete_context, NULL)) 243 return; 244 lease_prune(NULL, now); /* lose any expired leases */ 245 iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, 246 now, unicast_dest, &is_inform); 247 lease_update_file(now); 248 lease_update_dns(); 249 250 if (iov.iov_len == 0) 251 return; 252 253 msg.msg_name = &dest; 254 msg.msg_namelen = sizeof(dest); 255 msg.msg_control = NULL; 256 msg.msg_controllen = 0; 257 msg.msg_iov = &iov; 258 iov.iov_base = daemon->dhcp_packet.iov_base; 259 260 /* packet buffer may have moved */ 261 mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base; 262 263#ifdef HAVE_SOCKADDR_SA_LEN 264 dest.sin_len = sizeof(struct sockaddr_in); 265#endif 266 267 if (mess->giaddr.s_addr) 268 { 269 /* Send to BOOTP relay */ 270 dest.sin_port = htons(daemon->dhcp_server_port); 271 dest.sin_addr = mess->giaddr; 272 } 273 else if (mess->ciaddr.s_addr) 274 { 275 /* If the client's idea of its own address tallys with 276 the source address in the request packet, we believe the 277 source port too, and send back to that. If we're replying 278 to a DHCPINFORM, trust the source address always. */ 279 if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) || 280 dest.sin_port == 0 || dest.sin_addr.s_addr == 0) 281 { 282 dest.sin_port = htons(daemon->dhcp_client_port); 283 dest.sin_addr = mess->ciaddr; 284 } 285 } 286#if defined(HAVE_LINUX_NETWORK) 287 else if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 || 288 mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0) 289 { 290 /* broadcast to 255.255.255.255 (or mac address invalid) */ 291 struct in_pktinfo *pkt; 292 msg.msg_control = control_u.control; 293 msg.msg_controllen = sizeof(control_u); 294 cmptr = CMSG_FIRSTHDR(&msg); 295 pkt = (struct in_pktinfo *)CMSG_DATA(cmptr); 296 pkt->ipi_ifindex = iface_index; 297 pkt->ipi_spec_dst.s_addr = 0; 298 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 299 cmptr->cmsg_level = SOL_IP; 300 cmptr->cmsg_type = IP_PKTINFO; 301 dest.sin_addr.s_addr = INADDR_BROADCAST; 302 dest.sin_port = htons(daemon->dhcp_client_port); 303 } 304 else 305 { 306 /* unicast to unconfigured client. Inject mac address direct into ARP cache. 307 struct sockaddr limits size to 14 bytes. */ 308 struct arpreq req; 309 dest.sin_addr = mess->yiaddr; 310 dest.sin_port = htons(daemon->dhcp_client_port); 311 *((struct sockaddr_in *)&req.arp_pa) = dest; 312 req.arp_ha.sa_family = mess->htype; 313 memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen); 314 strncpy(req.arp_dev, ifr.ifr_name, 16); 315 req.arp_flags = ATF_COM; 316 ioctl(daemon->dhcpfd, SIOCSARP, &req); 317 } 318#elif defined(HAVE_SOLARIS_NETWORK) 319 else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER) 320 { 321 /* broadcast to 255.255.255.255 (or mac address invalid) */ 322 dest.sin_addr.s_addr = INADDR_BROADCAST; 323 dest.sin_port = htons(daemon->dhcp_client_port); 324 /* note that we don't specify the interface here: that's done by the 325 IP_BOUND_IF sockopt lower down. */ 326 } 327 else 328 { 329 /* unicast to unconfigured client. Inject mac address direct into ARP cache. 330 Note that this only works for ethernet on solaris, because we use SIOCSARP 331 and not SIOCSXARP, which would be perfect, except that it returns ENXIO 332 mysteriously. Bah. Fall back to broadcast for other net types. */ 333 struct arpreq req; 334 dest.sin_addr = mess->yiaddr; 335 dest.sin_port = htons(daemon->dhcp_client_port); 336 *((struct sockaddr_in *)&req.arp_pa) = dest; 337 req.arp_ha.sa_family = AF_UNSPEC; 338 memcpy(req.arp_ha.sa_data, mess->chaddr, mess->hlen); 339 req.arp_flags = ATF_COM; 340 ioctl(daemon->dhcpfd, SIOCSARP, &req); 341 } 342#elif defined(HAVE_BSD_NETWORK) 343 else 344 { 345 send_via_bpf(mess, iov.iov_len, iface_addr, &ifr); 346 return; 347 } 348#endif 349 350#ifdef HAVE_SOLARIS_NETWORK 351 setsockopt(daemon->dhcpfd, IPPROTO_IP, IP_BOUND_IF, &iface_index, sizeof(iface_index)); 352#endif 353 354 while(sendmsg(daemon->dhcpfd, &msg, 0) == -1 && retry_send()); 355} 356 357/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple 358 of each interface (and any relay address) and does the following things: 359 360 1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived. 361 2) Fills in any netmask and broadcast addresses which have not been explicitly configured. 362 3) Fills in local (this host) and router (this host or relay) addresses. 363 4) Links contexts which are valid for hosts directly connected to the arrival interface on ->current. 364 365 Note that the current chain may be superceded later for configured hosts or those coming via gateways. */ 366 367static int complete_context(struct in_addr local, int if_index, 368 struct in_addr netmask, struct in_addr broadcast, void *vparam) 369{ 370 struct dhcp_context *context; 371 struct iface_param *param = vparam; 372 373 for (context = daemon->dhcp; context; context = context->next) 374 { 375 if (!(context->flags & CONTEXT_NETMASK) && 376 (is_same_net(local, context->start, netmask) || 377 is_same_net(local, context->end, netmask))) 378 { 379 if (context->netmask.s_addr != netmask.s_addr && 380 !(is_same_net(local, context->start, netmask) && 381 is_same_net(local, context->end, netmask))) 382 { 383 strcpy(daemon->dhcp_buff, inet_ntoa(context->start)); 384 strcpy(daemon->dhcp_buff2, inet_ntoa(context->end)); 385 my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"), 386 daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask)); 387 } 388 context->netmask = netmask; 389 } 390 391 if (context->netmask.s_addr) 392 { 393 if (is_same_net(local, context->start, context->netmask) && 394 is_same_net(local, context->end, context->netmask)) 395 { 396 /* link it onto the current chain if we've not seen it before */ 397 if (if_index == param->ind && context->current == context) 398 { 399 context->router = local; 400 context->local = local; 401 context->current = param->current; 402 param->current = context; 403 } 404 405 if (!(context->flags & CONTEXT_BRDCAST)) 406 { 407 if (is_same_net(broadcast, context->start, context->netmask)) 408 context->broadcast = broadcast; 409 else 410 context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr; 411 } 412 } 413 else if (param->relay.s_addr && is_same_net(param->relay, context->start, context->netmask)) 414 { 415 context->router = param->relay; 416 context->local = param->primary; 417 /* fill in missing broadcast addresses for relayed ranges */ 418 if (!(context->flags & CONTEXT_BRDCAST)) 419 context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr; 420 } 421 422 } 423 } 424 425 return 1; 426} 427 428struct dhcp_context *address_available(struct dhcp_context *context, 429 struct in_addr taddr, 430 struct dhcp_netid *netids) 431{ 432 /* Check is an address is OK for this network, check all 433 possible ranges. Make sure that the address isn't in use 434 by the server itself. */ 435 436 unsigned int start, end, addr = ntohl(taddr.s_addr); 437 struct dhcp_context *tmp; 438 439 for (tmp = context; tmp; tmp = tmp->current) 440 if (taddr.s_addr == context->router.s_addr) 441 return NULL; 442 443 for (tmp = context; tmp; tmp = tmp->current) 444 { 445 start = ntohl(tmp->start.s_addr); 446 end = ntohl(tmp->end.s_addr); 447 448 if (!(tmp->flags & CONTEXT_STATIC) && 449 addr >= start && 450 addr <= end && 451 match_netid(tmp->filter, netids, 1)) 452 return tmp; 453 } 454 455 return NULL; 456} 457 458struct dhcp_context *narrow_context(struct dhcp_context *context, 459 struct in_addr taddr, 460 struct dhcp_netid *netids) 461{ 462 /* We start of with a set of possible contexts, all on the current physical interface. 463 These are chained on ->current. 464 Here we have an address, and return the actual context correponding to that 465 address. Note that none may fit, if the address came a dhcp-host and is outside 466 any dhcp-range. In that case we return a static range if possible, or failing that, 467 any context on the correct subnet. (If there's more than one, this is a dodgy 468 configuration: maybe there should be a warning.) */ 469 470 struct dhcp_context *tmp; 471 472 if (!(tmp = address_available(context, taddr, netids))) 473 { 474 for (tmp = context; tmp; tmp = tmp->current) 475 if (is_same_net(taddr, tmp->start, tmp->netmask) && 476 (tmp->flags & CONTEXT_STATIC)) 477 break; 478 479 if (!tmp) 480 for (tmp = context; tmp; tmp = tmp->current) 481 if (is_same_net(taddr, tmp->start, tmp->netmask)) 482 break; 483 } 484 485 /* Only one context allowed now */ 486 if (tmp) 487 tmp->current = NULL; 488 489 return tmp; 490} 491 492struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr) 493{ 494 struct dhcp_config *config; 495 496 for (config = configs; config; config = config->next) 497 if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr) 498 return config; 499 500 return NULL; 501} 502 503/* Is every member of check matched by a member of pool? 504 If tagnotneeded, untagged is OK */ 505int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int tagnotneeded) 506{ 507 struct dhcp_netid *tmp1; 508 509 if (!check && !tagnotneeded) 510 return 0; 511 512 for (; check; check = check->next) 513 { 514 if (check->net[0] != '#') 515 { 516 for (tmp1 = pool; tmp1; tmp1 = tmp1->next) 517 if (strcmp(check->net, tmp1->net) == 0) 518 break; 519 if (!tmp1) 520 return 0; 521 } 522 else 523 for (tmp1 = pool; tmp1; tmp1 = tmp1->next) 524 if (strcmp((check->net)+1, tmp1->net) == 0) 525 return 0; 526 } 527 return 1; 528} 529 530int address_allocate(struct dhcp_context *context, 531 struct in_addr *addrp, unsigned char *hwaddr, int hw_len, 532 struct dhcp_netid *netids, time_t now) 533{ 534 /* Find a free address: exclude anything in use and anything allocated to 535 a particular hwaddr/clientid/hostname in our configuration. 536 Try to return from contexts which match netids first. */ 537 538 struct in_addr start, addr; 539 struct dhcp_context *c, *d; 540 int i, pass; 541 unsigned int j; 542 543 /* hash hwaddr */ 544 for (j = 0, i = 0; i < hw_len; i++) 545 j += hwaddr[i] + (hwaddr[i] << 8) + (hwaddr[i] << 16); 546 547 for (pass = 0; pass <= 1; pass++) 548 for (c = context; c; c = c->current) 549 if (c->flags & CONTEXT_STATIC) 550 continue; 551 else if (!match_netid(c->filter, netids, pass)) 552 continue; 553 else 554 { 555 /* pick a seed based on hwaddr then iterate until we find a free address. */ 556 start.s_addr = addr.s_addr = 557 htonl(ntohl(c->start.s_addr) + 558 ((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr)))); 559 560 do { 561 /* eliminate addresses in use by the server. */ 562 for (d = context; d; d = d->current) 563 if (addr.s_addr == d->router.s_addr) 564 break; 565 566 /* Addresses which end in .255 and .0 are broken in Windows even when using 567 supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0 568 then 192.168.0.255 is a valid IP address, but not for Windows as it's 569 in the class C range. See KB281579. We therefore don't allocate these 570 addresses to avoid hard-to-diagnose problems. Thanks Bill. */ 571 if (!d && 572 !lease_find_by_addr(addr) && 573 !config_find_by_address(daemon->dhcp_conf, addr) && 574 (!IN_CLASSC(ntohl(addr.s_addr)) || 575 ((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0)))) 576 { 577 struct ping_result *r, *victim = NULL; 578 int count, max = (int)(0.6 * (((float)PING_CACHE_TIME)/ 579 ((float)PING_WAIT))); 580 581 *addrp = addr; 582 583 if (daemon->options & OPT_NO_PING) 584 return 1; 585 586 /* check if we failed to ping addr sometime in the last 587 PING_CACHE_TIME seconds. If so, assume the same situation still exists. 588 This avoids problems when a stupid client bangs 589 on us repeatedly. As a final check, if we did more 590 than 60% of the possible ping checks in the last 591 PING_CACHE_TIME, we are in high-load mode, so don't do any more. */ 592 for (count = 0, r = daemon->ping_results; r; r = r->next) 593 if (difftime(now, r->time) > (float)PING_CACHE_TIME) 594 victim = r; /* old record */ 595 else if (++count == max || r->addr.s_addr == addr.s_addr) 596 return 1; 597 598 if (icmp_ping(addr)) 599 /* address in use: perturb address selection so that we are 600 less likely to try this address again. */ 601 c->addr_epoch++; 602 else 603 { 604 /* at this point victim may hold an expired record */ 605 if (!victim) 606 { 607 if ((victim = whine_malloc(sizeof(struct ping_result)))) 608 { 609 victim->next = daemon->ping_results; 610 daemon->ping_results = victim; 611 } 612 } 613 614 /* record that this address is OK for 30s 615 without more ping checks */ 616 if (victim) 617 { 618 victim->addr = addr; 619 victim->time = now; 620 } 621 return 1; 622 } 623 } 624 625 addr.s_addr = htonl(ntohl(addr.s_addr) + 1); 626 627 if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1)) 628 addr = c->start; 629 630 } while (addr.s_addr != start.s_addr); 631 } 632 return 0; 633} 634 635static int is_addr_in_context(struct dhcp_context *context, struct dhcp_config *config) 636{ 637 if (!context) /* called via find_config() from lease_update_from_configs() */ 638 return 1; 639 if (!(config->flags & CONFIG_ADDR)) 640 return 1; 641 for (; context; context = context->current) 642 if (is_same_net(config->addr, context->start, context->netmask)) 643 return 1; 644 645 return 0; 646} 647 648int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type) 649{ 650 struct hwaddr_config *conf_addr; 651 652 for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next) 653 if (conf_addr->wildcard_mask == 0 && 654 conf_addr->hwaddr_len == len && 655 (conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) && 656 memcmp(conf_addr->hwaddr, hwaddr, len) == 0) 657 return 1; 658 659 return 0; 660} 661 662struct dhcp_config *find_config(struct dhcp_config *configs, 663 struct dhcp_context *context, 664 unsigned char *clid, int clid_len, 665 unsigned char *hwaddr, int hw_len, 666 int hw_type, char *hostname) 667{ 668 int count, new; 669 struct dhcp_config *config, *candidate; 670 struct hwaddr_config *conf_addr; 671 672 if (clid) 673 for (config = configs; config; config = config->next) 674 if (config->flags & CONFIG_CLID) 675 { 676 if (config->clid_len == clid_len && 677 memcmp(config->clid, clid, clid_len) == 0 && 678 is_addr_in_context(context, config)) 679 return config; 680 681 /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and 682 cope with that here */ 683 if (*clid == 0 && config->clid_len == clid_len-1 && 684 memcmp(config->clid, clid+1, clid_len-1) == 0 && 685 is_addr_in_context(context, config)) 686 return config; 687 } 688 689 690 for (config = configs; config; config = config->next) 691 if (config_has_mac(config, hwaddr, hw_len, hw_type) && 692 is_addr_in_context(context, config)) 693 return config; 694 695 if (hostname && context) 696 for (config = configs; config; config = config->next) 697 if ((config->flags & CONFIG_NAME) && 698 hostname_isequal(config->hostname, hostname) && 699 is_addr_in_context(context, config)) 700 return config; 701 702 /* use match with fewest wildcast octets */ 703 for (candidate = NULL, count = 0, config = configs; config; config = config->next) 704 if (is_addr_in_context(context, config)) 705 for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next) 706 if (conf_addr->wildcard_mask != 0 && 707 conf_addr->hwaddr_len == hw_len && 708 (conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) && 709 (new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wildcard_mask)) > count) 710 { 711 count = new; 712 candidate = config; 713 } 714 715 return candidate; 716} 717 718void dhcp_read_ethers(void) 719{ 720 FILE *f = fopen(ETHERSFILE, "r"); 721 unsigned int flags; 722 char *buff = daemon->namebuff; 723 char *ip, *cp; 724 struct in_addr addr; 725 unsigned char hwaddr[ETHER_ADDR_LEN]; 726 struct dhcp_config **up, *tmp; 727 struct dhcp_config *config; 728 int count = 0, lineno = 0; 729 730 addr.s_addr = 0; /* eliminate warning */ 731 732 if (!f) 733 { 734 my_syslog(MS_DHCP | LOG_ERR, _("failed to read %s: %s"), ETHERSFILE, strerror(errno)); 735 return; 736 } 737 738 /* This can be called again on SIGHUP, so remove entries created last time round. */ 739 for (up = &daemon->dhcp_conf, config = daemon->dhcp_conf; config; config = tmp) 740 { 741 tmp = config->next; 742 if (config->flags & CONFIG_FROM_ETHERS) 743 { 744 *up = tmp; 745 /* cannot have a clid */ 746 if (config->flags & CONFIG_NAME) 747 free(config->hostname); 748 free(config->hwaddr); 749 free(config); 750 } 751 else 752 up = &config->next; 753 } 754 755 while (fgets(buff, MAXDNAME, f)) 756 { 757 char *host = NULL; 758 759 lineno++; 760 761 while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1])) 762 buff[strlen(buff)-1] = 0; 763 764 if ((*buff == '#') || (*buff == '+') || (*buff == 0)) 765 continue; 766 767 for (ip = buff; *ip && !isspace((int)*ip); ip++); 768 for(; *ip && isspace((int)*ip); ip++) 769 *ip = 0; 770 if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN) 771 { 772 my_syslog(MS_DHCP | LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno); 773 continue; 774 } 775 776 /* check for name or dotted-quad */ 777 for (cp = ip; *cp; cp++) 778 if (!(*cp == '.' || (*cp >='0' && *cp <= '9'))) 779 break; 780 781 if (!*cp) 782 { 783 if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1) 784 { 785 my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno); 786 continue; 787 } 788 789 flags = CONFIG_ADDR; 790 791 for (config = daemon->dhcp_conf; config; config = config->next) 792 if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr) 793 break; 794 } 795 else 796 { 797 int nomem; 798 if (!(host = canonicalise(ip, &nomem)) || !legal_hostname(host)) 799 { 800 if (!nomem) 801 my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno); 802 free(host); 803 continue; 804 } 805 806 flags = CONFIG_NAME; 807 808 for (config = daemon->dhcp_conf; config; config = config->next) 809 if ((config->flags & CONFIG_NAME) && hostname_isequal(config->hostname, host)) 810 break; 811 } 812 813 if (config && (config->flags & CONFIG_FROM_ETHERS)) 814 { 815 my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno); 816 continue; 817 } 818 819 if (!config) 820 { 821 for (config = daemon->dhcp_conf; config; config = config->next) 822 { 823 struct hwaddr_config *conf_addr = config->hwaddr; 824 if (conf_addr && 825 conf_addr->next == NULL && 826 conf_addr->wildcard_mask == 0 && 827 conf_addr->hwaddr_len == ETHER_ADDR_LEN && 828 (conf_addr->hwaddr_type == ARPHRD_ETHER || conf_addr->hwaddr_type == 0) && 829 memcmp(conf_addr->hwaddr, hwaddr, ETHER_ADDR_LEN) == 0) 830 break; 831 } 832 833 if (!config) 834 { 835 if (!(config = whine_malloc(sizeof(struct dhcp_config)))) 836 continue; 837 config->flags = CONFIG_FROM_ETHERS; 838 config->hwaddr = NULL; 839 config->domain = NULL; 840 config->next = daemon->dhcp_conf; 841 daemon->dhcp_conf = config; 842 } 843 844 config->flags |= flags; 845 846 if (flags & CONFIG_NAME) 847 { 848 config->hostname = host; 849 host = NULL; 850 } 851 852 if (flags & CONFIG_ADDR) 853 config->addr = addr; 854 } 855 856 config->flags |= CONFIG_NOCLID; 857 if (!config->hwaddr) 858 config->hwaddr = whine_malloc(sizeof(struct hwaddr_config)); 859 if (config->hwaddr) 860 { 861 memcpy(config->hwaddr->hwaddr, hwaddr, ETHER_ADDR_LEN); 862 config->hwaddr->hwaddr_len = ETHER_ADDR_LEN; 863 config->hwaddr->hwaddr_type = ARPHRD_ETHER; 864 config->hwaddr->wildcard_mask = 0; 865 config->hwaddr->next = NULL; 866 } 867 count++; 868 869 free(host); 870 871 } 872 873 fclose(f); 874 875 my_syslog(MS_DHCP | LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count); 876} 877 878void check_dhcp_hosts(int fatal) 879{ 880 /* If the same IP appears in more than one host config, then DISCOVER 881 for one of the hosts will get the address, but REQUEST will be NAKed, 882 since the address is reserved by the other one -> protocol loop. 883 Also check that FQDNs match the domain we are using. */ 884 885 struct dhcp_config *configs, *cp; 886 887 for (configs = daemon->dhcp_conf; configs; configs = configs->next) 888 { 889 char *domain; 890 891 if ((configs->flags & DHOPT_BANK) || fatal) 892 { 893 for (cp = configs->next; cp; cp = cp->next) 894 if ((configs->flags & cp->flags & CONFIG_ADDR) && configs->addr.s_addr == cp->addr.s_addr) 895 { 896 if (fatal) 897 die(_("duplicate IP address %s in dhcp-config directive."), 898 inet_ntoa(cp->addr), EC_BADCONF); 899 else 900 my_syslog(MS_DHCP | LOG_ERR, _("duplicate IP address %s in %s."), 901 inet_ntoa(cp->addr), daemon->dhcp_hosts_file); 902 configs->flags &= ~CONFIG_ADDR; 903 } 904 905 /* split off domain part */ 906 if ((configs->flags & CONFIG_NAME) && (domain = strip_hostname(configs->hostname))) 907 configs->domain = domain; 908 } 909 } 910} 911 912void dhcp_update_configs(struct dhcp_config *configs) 913{ 914 /* Some people like to keep all static IP addresses in /etc/hosts. 915 This goes through /etc/hosts and sets static addresses for any DHCP config 916 records which don't have an address and whose name matches. 917 We take care to maintain the invariant that any IP address can appear 918 in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP, 919 restore the status-quo ante first. */ 920 921 struct dhcp_config *config; 922 struct crec *crec; 923 924 for (config = configs; config; config = config->next) 925 if (config->flags & CONFIG_ADDR_HOSTS) 926 config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS); 927 928 929 if (daemon->port != 0) 930 for (config = configs; config; config = config->next) 931 if (!(config->flags & CONFIG_ADDR) && 932 (config->flags & CONFIG_NAME) && 933 (crec = cache_find_by_name(NULL, config->hostname, 0, F_IPV4)) && 934 (crec->flags & F_HOSTS)) 935 { 936 if (cache_find_by_name(crec, config->hostname, 0, F_IPV4)) 937 { 938 /* use primary (first) address */ 939 while (crec && !(crec->flags & F_REVERSE)) 940 crec = cache_find_by_name(crec, config->hostname, 0, F_IPV4); 941 if (!crec) 942 continue; /* should be never */ 943 my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"), 944 config->hostname, inet_ntoa(crec->addr.addr.addr.addr4)); 945 } 946 947 if (config_find_by_address(configs, crec->addr.addr.addr.addr4)) 948 my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"), 949 inet_ntoa(crec->addr.addr.addr.addr4), config->hostname); 950 else 951 { 952 config->addr = crec->addr.addr.addr.addr4; 953 config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS; 954 } 955 } 956} 957 958/* If we've not found a hostname any other way, try and see if there's one in /etc/hosts 959 for this address. If it has a domain part, that must match the set domain and 960 it gets stripped. The set of legal domain names is bigger than the set of legal hostnames 961 so check here that the domain name is legal as a hostname. */ 962char *host_from_dns(struct in_addr addr) 963{ 964 struct crec *lookup; 965 char *hostname = NULL; 966 char *d1, *d2; 967 968 if (daemon->port == 0) 969 return NULL; /* DNS disabled. */ 970 971 lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4); 972 if (lookup && (lookup->flags & F_HOSTS)) 973 { 974 hostname = daemon->dhcp_buff; 975 strncpy(hostname, cache_get_name(lookup), 256); 976 hostname[255] = 0; 977 d1 = strip_hostname(hostname); 978 d2 = get_domain(addr); 979 if (!legal_hostname(hostname) || (d1 && (!d2 || !hostname_isequal(d1, d2)))) 980 hostname = NULL; 981 } 982 983 return hostname; 984} 985 986/* return domain or NULL if none. */ 987char *strip_hostname(char *hostname) 988{ 989 char *dot = strchr(hostname, '.'); 990 991 if (!dot) 992 return NULL; 993 994 *dot = 0; /* truncate */ 995 if (strlen(dot+1) != 0) 996 return dot+1; 997 998 return NULL; 999} 1000 1001#endif 1002 1003