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