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