1 /* $NetBSD: socket.c,v 1.5 2022/04/03 01:10:58 christos Exp $ */ 2 3 /* socket.c 4 5 BSD socket interface code... */ 6 7 /* 8 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1995-2003 by Internet Software Consortium 10 * 11 * This Source Code Form is subject to the terms of the Mozilla Public 12 * License, v. 2.0. If a copy of the MPL was not distributed with this 13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * PO Box 360 25 * Newmarket, NH 03857 USA 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: socket.c,v 1.5 2022/04/03 01:10:58 christos Exp $"); 33 34 /* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu). 35 * This sockopt allows a socket to be bound to a particular interface, 36 * thus enabling the use of DHCPD on a multihomed host. 37 * If SO_BINDTODEVICE is defined in your system header files, the use of 38 * this sockopt will be automatically enabled. 39 * I have implemented it under Linux; other systems should be doable also. 40 */ 41 42 #include "dhcpd.h" 43 #include <isc/util.h> 44 #include <errno.h> 45 #include <sys/ioctl.h> 46 #include <sys/uio.h> 47 #include <sys/uio.h> 48 49 #if defined(sun) && defined(USE_V4_PKTINFO) 50 #include <sys/sysmacros.h> 51 #include <net/if.h> 52 #include <sys/sockio.h> 53 #include <net/if_dl.h> 54 #include <sys/dlpi.h> 55 #endif 56 57 #ifdef USE_SOCKET_FALLBACK 58 # if !defined (USE_SOCKET_SEND) 59 # define if_register_send if_register_fallback 60 # define send_packet send_fallback 61 # define if_reinitialize_send if_reinitialize_fallback 62 # endif 63 #endif 64 65 #if defined(DHCPv6) 66 /* 67 * XXX: this is gross. we need to go back and overhaul the API for socket 68 * handling. 69 */ 70 static int no_global_v6_socket = 0; 71 static unsigned int global_v6_socket_references = 0; 72 static int global_v6_socket = -1; 73 #if defined(RELAY_PORT) 74 static unsigned int relay_port_v6_socket_references = 0; 75 static int relay_port_v6_socket = -1; 76 #endif 77 78 static void if_register_multicast(struct interface_info *info); 79 #endif 80 81 /* 82 * We can use a single socket for AF_INET (similar to AF_INET6) on all 83 * interfaces configured for DHCP if the system has support for IP_PKTINFO 84 * and IP_RECVPKTINFO (for example Solaris 11). 85 */ 86 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 87 static unsigned int global_v4_socket_references = 0; 88 static int global_v4_socket = -1; 89 #endif 90 91 /* 92 * If we can't bind() to a specific interface, then we can only have 93 * a single socket. This variable insures that we don't try to listen 94 * on two sockets. 95 */ 96 #if !defined(SO_BINDTODEVICE) && !defined(USE_FALLBACK) 97 static int once = 0; 98 #endif /* !defined(SO_BINDTODEVICE) && !defined(USE_FALLBACK) */ 99 100 /* Reinitializes the specified interface after an address change. This 101 is not required for packet-filter APIs. */ 102 103 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK) 104 void if_reinitialize_send (info) 105 struct interface_info *info; 106 { 107 #if 0 108 #ifndef USE_SOCKET_RECEIVE 109 once = 0; 110 close (info -> wfdesc); 111 #endif 112 if_register_send (info); 113 #endif 114 } 115 #endif 116 117 #ifdef USE_SOCKET_RECEIVE 118 void if_reinitialize_receive (info) 119 struct interface_info *info; 120 { 121 #if 0 122 once = 0; 123 close (info -> rfdesc); 124 if_register_receive (info); 125 #endif 126 } 127 #endif 128 129 #if defined (USE_SOCKET_SEND) || \ 130 defined (USE_SOCKET_RECEIVE) || \ 131 defined (USE_SOCKET_FALLBACK) 132 /* Generic interface registration routine... */ 133 int 134 if_register_socket(struct interface_info *info, int family, 135 int *do_multicast, struct in6_addr *linklocal6) 136 { 137 struct sockaddr_storage name; 138 int name_len; 139 int sock; 140 int flag; 141 int domain; 142 #ifdef DHCPv6 143 struct sockaddr_in6 *addr6; 144 #endif 145 struct sockaddr_in *addr; 146 147 /* INSIST((family == AF_INET) || (family == AF_INET6)); */ 148 149 #if !defined(SO_BINDTODEVICE) && !defined(USE_FALLBACK) 150 /* Make sure only one interface is registered. */ 151 if (once) { 152 log_fatal ("The standard socket API can only support %s", 153 "hosts with a single network interface."); 154 } 155 once = 1; 156 #endif 157 158 /* 159 * Set up the address we're going to bind to, depending on the 160 * address family. 161 */ 162 memset(&name, 0, sizeof(name)); 163 switch (family) { 164 #ifdef DHCPv6 165 case AF_INET6: 166 addr6 = (struct sockaddr_in6 *)&name; 167 addr6->sin6_family = AF_INET6; 168 addr6->sin6_port = *libdhcp_callbacks.local_port; 169 #if defined(RELAY_PORT) 170 if (relay_port && 171 ((info->flags & INTERFACE_STREAMS) == INTERFACE_UPSTREAM)) 172 addr6->sin6_port = relay_port; 173 #endif 174 /* A server feature */ 175 if (bind_local_address6) { 176 memcpy(&addr6->sin6_addr, 177 &local_address6, 178 sizeof(addr6->sin6_addr)); 179 } 180 /* A client feature */ 181 if (linklocal6) { 182 memcpy(&addr6->sin6_addr, 183 linklocal6, 184 sizeof(addr6->sin6_addr)); 185 } 186 if (IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) { 187 addr6->sin6_scope_id = if_nametoindex(info->name); 188 } 189 #ifdef HAVE_SA_LEN 190 addr6->sin6_len = sizeof(*addr6); 191 #endif 192 name_len = sizeof(*addr6); 193 domain = PF_INET6; 194 if ((info->flags & INTERFACE_STREAMS) == INTERFACE_UPSTREAM) { 195 *do_multicast = 0; 196 } 197 break; 198 #endif /* DHCPv6 */ 199 200 case AF_INET: 201 default: 202 addr = (struct sockaddr_in *)&name; 203 addr->sin_family = AF_INET; 204 addr->sin_port = relay_port ? relay_port : *libdhcp_callbacks.local_port; 205 memcpy(&addr->sin_addr, 206 &local_address, 207 sizeof(addr->sin_addr)); 208 #ifdef HAVE_SA_LEN 209 addr->sin_len = sizeof(*addr); 210 #endif 211 name_len = sizeof(*addr); 212 domain = PF_INET; 213 break; 214 } 215 216 /* Make a socket... */ 217 sock = socket(domain, SOCK_DGRAM, IPPROTO_UDP); 218 if (sock < 0) { 219 log_fatal("Can't create dhcp socket for %s: %m", info->name); 220 } 221 222 /* Set the REUSEADDR option so that we don't fail to start if 223 we're being restarted. */ 224 flag = 1; 225 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 226 (char *)&flag, sizeof(flag)) < 0) { 227 log_fatal("Can't set SO_REUSEADDR on dhcp socket for" 228 " %s: %m", info->name); 229 } 230 231 /* Set the BROADCAST option so that we can broadcast DHCP responses. 232 We shouldn't do this for fallback devices, and we can detect that 233 a device is a fallback because it has no ifp structure. */ 234 if (info->ifp && 235 (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, 236 (char *)&flag, sizeof(flag)) < 0)) { 237 log_fatal("Can't set SO_BROADCAST on dhcp socket for" 238 " %s: %m", info->name); 239 } 240 241 #if defined(DHCPv6) && defined(SO_REUSEPORT) 242 /* 243 * We only set SO_REUSEPORT on AF_INET6 sockets, so that multiple 244 * daemons can bind to their own sockets and get data for their 245 * respective interfaces. This does not (and should not) affect 246 * DHCPv4 sockets; we can't yet support BSD sockets well, much 247 * less multiple sockets. Make sense only with multicast. 248 * RedHat defines SO_REUSEPORT with a kernel which does not support 249 * it and returns ENOPROTOOPT so in this case ignore the error. 250 */ 251 if ((local_family == AF_INET6) && *do_multicast) { 252 flag = 1; 253 if ((setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, 254 (char *)&flag, sizeof(flag)) < 0) && 255 (errno != ENOPROTOOPT)) { 256 log_fatal("Can't set SO_REUSEPORT on dhcp socket for" 257 " %s: %m", info->name); 258 } 259 } 260 #endif 261 262 /* Bind the socket to this interface's IP address. */ 263 if (bind(sock, (struct sockaddr *)&name, name_len) < 0) { 264 log_error("Can't bind to dhcp address: %m"); 265 log_error("Please make sure there is no other dhcp server"); 266 log_error("running and that there's no entry for dhcp or"); 267 log_error("bootp in /etc/inetd.conf. Also make sure you"); 268 log_error("are not running HP JetAdmin software, which"); 269 log_fatal("includes a bootp server."); 270 } 271 272 #if defined(SO_BINDTODEVICE) 273 /* Bind this socket to this interface. */ 274 if ((local_family != AF_INET6) && (info->ifp != NULL) && 275 setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, 276 (char *)(info -> ifp), sizeof(*(info -> ifp))) < 0) { 277 log_fatal("Can't set SO_BINDTODEVICE on dhcp socket for" 278 " %s : %m", (char *)(info->ifp)); 279 } 280 #endif 281 282 /* IP_BROADCAST_IF instructs the kernel which interface to send 283 * IP packets whose destination address is 255.255.255.255. These 284 * will be treated as subnet broadcasts on the interface identified 285 * by ip address (info -> primary_address). This is only known to 286 * be defined in SCO system headers, and may not be defined in all 287 * releases. 288 */ 289 #if defined(SCO) && defined(IP_BROADCAST_IF) 290 if (info->address_count && 291 setsockopt(sock, IPPROTO_IP, IP_BROADCAST_IF, &info->addresses[0], 292 sizeof(info->addresses[0])) < 0) 293 log_fatal("Can't set IP_BROADCAST_IF on dhcp socket for" 294 " %s: %m", info->name); 295 #endif 296 297 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 298 /* 299 * If we turn on IP_RECVPKTINFO we will be able to receive 300 * the interface index information of the received packet. 301 */ 302 if (family == AF_INET) { 303 int on = 1; 304 if (setsockopt(sock, IPPROTO_IP, IP_RECVPKTINFO, 305 &on, sizeof(on)) != 0) { 306 log_fatal("Can't set IP_RECVPTKINFO on dhcp socket for" 307 " %s: %m", info->name); 308 } 309 } 310 #endif 311 312 #ifdef DHCPv6 313 /* 314 * If we turn on IPV6_PKTINFO, we will be able to receive 315 * additional information, such as the destination IP address. 316 * We need this to spot unicast packets. 317 */ 318 if (family == AF_INET6) { 319 int on = 1; 320 #ifdef IPV6_RECVPKTINFO 321 /* RFC3542 */ 322 if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, 323 &on, sizeof(on)) != 0) { 324 log_fatal("setsockopt: IPV6_RECVPKTINFO for %s: %m", 325 info->name); 326 } 327 #else 328 /* RFC2292 */ 329 if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, 330 &on, sizeof(on)) != 0) { 331 log_fatal("setsockopt: IPV6_PKTINFO for %s: %m", 332 info->name); 333 } 334 #endif 335 } 336 337 #endif /* DHCPv6 */ 338 339 return sock; 340 } 341 342 #ifdef DHCPv6 343 void set_multicast_hop_limit(struct interface_info* info, int hop_limit) { 344 if (setsockopt(info->wfdesc, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 345 &hop_limit, sizeof(int)) < 0) { 346 log_fatal("setsockopt: IPV6_MULTICAST_HOPS for %s: %m", 347 info->name); 348 } 349 350 log_debug("Setting hop count limit to %d for interface %s", 351 hop_limit, info->name); 352 353 } 354 #endif /* DHCPv6 */ 355 356 #endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */ 357 358 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK) 359 void if_register_send (info) 360 struct interface_info *info; 361 { 362 #ifndef USE_SOCKET_RECEIVE 363 info->wfdesc = if_register_socket(info, AF_INET, 0, NULL); 364 /* If this is a normal IPv4 address, get the hardware address. */ 365 if (strcmp(info->name, "fallback") != 0) 366 get_hw_addr(info->name, &info->hw_address); 367 #if defined (USE_SOCKET_FALLBACK) 368 /* Fallback only registers for send, but may need to receive as 369 well. */ 370 info->rfdesc = info->wfdesc; 371 #endif 372 #else 373 info->wfdesc = info->rfdesc; 374 #endif 375 if (!quiet_interface_discovery) 376 log_info ("Sending on Socket/%s%s%s", 377 info->name, 378 (info->shared_network ? "/" : ""), 379 (info->shared_network ? 380 info->shared_network->name : "")); 381 } 382 383 #if defined (USE_SOCKET_SEND) 384 void if_deregister_send (info) 385 struct interface_info *info; 386 { 387 #ifndef USE_SOCKET_RECEIVE 388 close (info -> wfdesc); 389 #endif 390 info -> wfdesc = -1; 391 392 if (!quiet_interface_discovery) 393 log_info ("Disabling output on Socket/%s%s%s", 394 info -> name, 395 (info -> shared_network ? "/" : ""), 396 (info -> shared_network ? 397 info -> shared_network -> name : "")); 398 } 399 #endif /* USE_SOCKET_SEND */ 400 #endif /* USE_SOCKET_SEND || USE_SOCKET_FALLBACK */ 401 402 #ifdef USE_SOCKET_RECEIVE 403 void if_register_receive (info) 404 struct interface_info *info; 405 { 406 407 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 408 if (global_v4_socket_references == 0) { 409 global_v4_socket = if_register_socket(info, AF_INET, 0, NULL); 410 if (global_v4_socket < 0) { 411 /* 412 * if_register_socket() fatally logs if it fails to 413 * create a socket, this is just a sanity check. 414 */ 415 log_fatal("Failed to create AF_INET socket %s:%d", 416 MDL); 417 } 418 } 419 420 info->rfdesc = global_v4_socket; 421 global_v4_socket_references++; 422 #else 423 /* If we're using the socket API for sending and receiving, 424 we don't need to register this interface twice. */ 425 info->rfdesc = if_register_socket(info, AF_INET, 0, NULL); 426 #endif /* IP_PKTINFO... */ 427 /* If this is a normal IPv4 address, get the hardware address. */ 428 if (strcmp(info->name, "fallback") != 0) 429 get_hw_addr(info->name, &info->hw_address); 430 431 if (!quiet_interface_discovery) 432 log_info ("Listening on Socket/%s%s%s", 433 info->name, 434 (info->shared_network ? "/" : ""), 435 (info->shared_network ? 436 info->shared_network->name : "")); 437 } 438 439 void if_deregister_receive (info) 440 struct interface_info *info; 441 { 442 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 443 /* Dereference the global v4 socket. */ 444 if ((info->rfdesc == global_v4_socket) && 445 (global_v4_socket_references > 0)) { 446 global_v4_socket_references--; 447 info->rfdesc = -1; 448 } else { 449 log_fatal("Impossible condition at %s:%d", MDL); 450 } 451 452 if (global_v4_socket_references == 0) { 453 close(global_v4_socket); 454 global_v4_socket = -1; 455 } 456 #else 457 close(info->rfdesc); 458 info->rfdesc = -1; 459 #endif /* IP_PKTINFO... */ 460 if (!quiet_interface_discovery) 461 log_info ("Disabling input on Socket/%s%s%s", 462 info -> name, 463 (info -> shared_network ? "/" : ""), 464 (info -> shared_network ? 465 info -> shared_network -> name : "")); 466 } 467 #endif /* USE_SOCKET_RECEIVE */ 468 469 470 #ifdef DHCPv6 471 /* 472 * This function joins the interface to DHCPv6 multicast groups so we will 473 * receive multicast messages. 474 */ 475 static void 476 if_register_multicast(struct interface_info *info) { 477 int sock = info->rfdesc; 478 struct ipv6_mreq mreq; 479 480 if (inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers, 481 &mreq.ipv6mr_multiaddr) <= 0) { 482 log_fatal("inet_pton: unable to convert '%s'", 483 All_DHCP_Relay_Agents_and_Servers); 484 } 485 mreq.ipv6mr_interface = if_nametoindex(info->name); 486 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, 487 &mreq, sizeof(mreq)) < 0) { 488 log_fatal("setsockopt: IPV6_JOIN_GROUP for %s: %m", 489 info->name); 490 } 491 492 /* 493 * The relay agent code sets the streams so you know which way 494 * is up and down. But a relay agent shouldn't join to the 495 * Server address, or else you get fun loops. So up or down 496 * doesn't matter, we're just using that config to sense this is 497 * a relay agent. 498 */ 499 if ((info->flags & INTERFACE_STREAMS) == 0) { 500 if (inet_pton(AF_INET6, All_DHCP_Servers, 501 &mreq.ipv6mr_multiaddr) <= 0) { 502 log_fatal("inet_pton: unable to convert '%s'", 503 All_DHCP_Servers); 504 } 505 mreq.ipv6mr_interface = if_nametoindex(info->name); 506 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, 507 &mreq, sizeof(mreq)) < 0) { 508 log_fatal("setsockopt: IPV6_JOIN_GROUP for %s: %m", 509 info->name); 510 } 511 } 512 } 513 514 void 515 if_register6(struct interface_info *info, int do_multicast) { 516 /* Bounce do_multicast to a stack variable because we may change it. */ 517 int req_multi = do_multicast; 518 519 if (no_global_v6_socket) { 520 log_fatal("Impossible condition at %s:%d", MDL); 521 } 522 523 #if defined(RELAY_PORT) 524 if (!relay_port || 525 ((info->flags & INTERFACE_STREAMS) == INTERFACE_DOWNSTREAM)) { 526 #endif 527 if (global_v6_socket_references == 0) { 528 global_v6_socket = if_register_socket(info, AF_INET6, 529 &req_multi, NULL); 530 if (global_v6_socket < 0) { 531 /* 532 * if_register_socket() fatally logs if it fails to 533 * create a socket, this is just a sanity check. 534 */ 535 log_fatal("Impossible condition at %s:%d", MDL); 536 } else if (bind_local_address6) { 537 char addr6_str[INET6_ADDRSTRLEN]; 538 539 if (inet_ntop(AF_INET6, 540 &local_address6, 541 addr6_str, 542 sizeof(addr6_str)) == NULL) { 543 log_fatal("inet_ntop: unable to convert " 544 "local-address6"); 545 } 546 log_info("Bound to [%s]:%d", 547 addr6_str, 548 (int) ntohs(*libdhcp_callbacks.local_port)); 549 } else { 550 log_info("Bound to *:%d", (int) ntohs(*libdhcp_callbacks.local_port)); 551 } 552 } 553 554 info->rfdesc = global_v6_socket; 555 info->wfdesc = global_v6_socket; 556 global_v6_socket_references++; 557 558 #if defined(RELAY_PORT) 559 } else { 560 /* 561 * If relay port is defined, we need to register one 562 * IPv6 UPD socket to handle upstream server or relay agent 563 * with a non-547 UDP local port. 564 */ 565 if ((relay_port_v6_socket_references == 0) && 566 ((info->flags & INTERFACE_STREAMS) == INTERFACE_UPSTREAM)) { 567 relay_port_v6_socket = if_register_socket(info, AF_INET6, 568 &req_multi, NULL); 569 if (relay_port_v6_socket < 0) { 570 log_fatal("Impossible condition at %s:%d", MDL); 571 } else { 572 log_info("Bound to relay port *:%d", 573 (int) ntohs(relay_port)); 574 } 575 } 576 info->rfdesc = relay_port_v6_socket; 577 info->wfdesc = relay_port_v6_socket; 578 relay_port_v6_socket_references++; 579 } 580 #endif 581 582 if (req_multi) 583 if_register_multicast(info); 584 585 get_hw_addr(info->name, &info->hw_address); 586 587 if (!quiet_interface_discovery) { 588 if (info->shared_network != NULL) { 589 log_info("Listening on Socket/%d/%s/%s", 590 global_v6_socket, info->name, 591 info->shared_network->name); 592 log_info("Sending on Socket/%d/%s/%s", 593 global_v6_socket, info->name, 594 info->shared_network->name); 595 } else { 596 log_info("Listening on Socket/%s", info->name); 597 log_info("Sending on Socket/%s", info->name); 598 } 599 } 600 } 601 602 /* 603 * Register an IPv6 socket bound to the link-local address of 604 * the argument interface (used by clients on a multiple interface box, 605 * vs. a server or a relay using the global IPv6 socket and running 606 * *only* in a single instance). 607 */ 608 void 609 if_register_linklocal6(struct interface_info *info) { 610 int sock; 611 int count; 612 struct in6_addr *addr6 = NULL; 613 int req_multi = 0; 614 615 if (global_v6_socket >= 0) { 616 log_fatal("Impossible condition at %s:%d", MDL); 617 } 618 619 no_global_v6_socket = 1; 620 621 /* get the (?) link-local address */ 622 for (count = 0; count < info->v6address_count; count++) { 623 addr6 = &info->v6addresses[count]; 624 if (IN6_IS_ADDR_LINKLOCAL(addr6)) 625 break; 626 } 627 628 if (!addr6) { 629 log_fatal("no link-local IPv6 address for %s", info->name); 630 } 631 632 sock = if_register_socket(info, AF_INET6, &req_multi, addr6); 633 634 if (sock < 0) { 635 log_fatal("if_register_socket for %s fails", info->name); 636 } 637 638 info->rfdesc = sock; 639 info->wfdesc = sock; 640 641 get_hw_addr(info->name, &info->hw_address); 642 643 if (!quiet_interface_discovery) { 644 if (info->shared_network != NULL) { 645 log_info("Listening on Socket/%d/%s/%s", 646 global_v6_socket, info->name, 647 info->shared_network->name); 648 log_info("Sending on Socket/%d/%s/%s", 649 global_v6_socket, info->name, 650 info->shared_network->name); 651 } else { 652 log_info("Listening on Socket/%s", info->name); 653 log_info("Sending on Socket/%s", info->name); 654 } 655 } 656 } 657 658 void 659 if_deregister6(struct interface_info *info) { 660 /* client case */ 661 if (no_global_v6_socket) { 662 close(info->rfdesc); 663 info->rfdesc = -1; 664 info->wfdesc = -1; 665 } else if ((info->rfdesc == global_v6_socket) && 666 (info->wfdesc == global_v6_socket) && 667 (global_v6_socket_references > 0)) { 668 /* Dereference the global v6 socket. */ 669 global_v6_socket_references--; 670 info->rfdesc = -1; 671 info->wfdesc = -1; 672 #if defined(RELAY_PORT) 673 } else if (relay_port && 674 (info->rfdesc == relay_port_v6_socket) && 675 (info->wfdesc == relay_port_v6_socket) && 676 (relay_port_v6_socket_references > 0)) { 677 /* Dereference the relay port v6 socket. */ 678 relay_port_v6_socket_references--; 679 info->rfdesc = -1; 680 info->wfdesc = -1; 681 #endif 682 } else { 683 log_fatal("Impossible condition at %s:%d", MDL); 684 } 685 686 if (!quiet_interface_discovery) { 687 if (info->shared_network != NULL) { 688 log_info("Disabling input on Socket/%s/%s", info->name, 689 info->shared_network->name); 690 log_info("Disabling output on Socket/%s/%s", info->name, 691 info->shared_network->name); 692 } else { 693 log_info("Disabling input on Socket/%s", info->name); 694 log_info("Disabling output on Socket/%s", info->name); 695 } 696 } 697 698 if (!no_global_v6_socket) { 699 if (global_v6_socket_references == 0) { 700 close(global_v6_socket); 701 global_v6_socket = -1; 702 703 log_info("Unbound from *:%d", 704 (int) ntohs(*libdhcp_callbacks.local_port)); 705 } 706 #if defined(RELAY_PORT) 707 if (relay_port && (relay_port_v6_socket_references == 0)) { 708 close(relay_port_v6_socket); 709 relay_port_v6_socket = -1; 710 711 log_info("Unbound from relay port *:%d", 712 (int) ntohs(relay_port)); 713 } 714 #endif 715 } 716 } 717 #endif /* DHCPv6 */ 718 719 #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK) 720 ssize_t send_packet (interface, packet, raw, len, from, to, hto) 721 struct interface_info *interface; 722 struct packet *packet; 723 struct dhcp_packet *raw; 724 size_t len; 725 struct in_addr from; 726 struct sockaddr_in *to; 727 struct hardware *hto; 728 { 729 int result; 730 #ifdef IGNORE_HOSTUNREACH 731 int retry = 0; 732 do { 733 #endif 734 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 735 struct in_pktinfo pktinfo; 736 737 if (interface->ifp != NULL) { 738 memset(&pktinfo, 0, sizeof (pktinfo)); 739 pktinfo.ipi_ifindex = interface->ifp->ifr_index; 740 if (setsockopt(interface->wfdesc, IPPROTO_IP, 741 IP_PKTINFO, (char *)&pktinfo, 742 sizeof(pktinfo)) < 0) 743 log_fatal("setsockopt: IP_PKTINFO for %s: %m", 744 (char*)(interface->ifp)); 745 } 746 #endif 747 result = sendto (interface -> wfdesc, (char *)raw, len, 0, 748 (struct sockaddr *)to, sizeof *to); 749 #ifdef IGNORE_HOSTUNREACH 750 } while (to -> sin_addr.s_addr == htonl (INADDR_BROADCAST) && 751 result < 0 && 752 (errno == EHOSTUNREACH || 753 errno == ECONNREFUSED) && 754 retry++ < 10); 755 #endif 756 if (result < 0) { 757 log_error ("send_packet: %m"); 758 if (errno == ENETUNREACH) 759 log_error ("send_packet: please consult README file%s", 760 " regarding broadcast address."); 761 } 762 return result; 763 } 764 765 #endif /* USE_SOCKET_SEND || USE_SOCKET_FALLBACK */ 766 767 #ifdef DHCPv6 768 /* 769 * Solaris 9 is missing the CMSG_LEN and CMSG_SPACE macros, so we will 770 * synthesize them (based on the BIND 9 technique). 771 */ 772 773 #ifndef CMSG_LEN 774 static size_t CMSG_LEN(size_t len) { 775 size_t hdrlen; 776 /* 777 * Cast NULL so that any pointer arithmetic performed by CMSG_DATA 778 * is correct. 779 */ 780 hdrlen = (size_t)CMSG_DATA(((struct cmsghdr *)NULL)); 781 return hdrlen + len; 782 } 783 #endif /* !CMSG_LEN */ 784 785 #ifndef CMSG_SPACE 786 static size_t CMSG_SPACE(size_t len) { 787 struct msghdr msg; 788 struct cmsghdr *cmsgp; 789 790 /* 791 * XXX: The buffer length is an ad-hoc value, but should be enough 792 * in a practical sense. 793 */ 794 union { 795 struct cmsghdr cmsg_sizer; 796 u_int8_t pktinfo_sizer[sizeof(struct cmsghdr) + 1024]; 797 } dummybuf; 798 799 memset(&msg, 0, sizeof(msg)); 800 msg.msg_control = &dummybuf; 801 msg.msg_controllen = sizeof(dummybuf); 802 803 cmsgp = (struct cmsghdr *)&dummybuf; 804 cmsgp->cmsg_len = CMSG_LEN(len); 805 806 cmsgp = CMSG_NXTHDR(&msg, cmsgp); 807 if (cmsgp != NULL) { 808 return (char *)cmsgp - (char *)msg.msg_control; 809 } else { 810 return 0; 811 } 812 } 813 #endif /* !CMSG_SPACE */ 814 815 #endif /* DHCPv6 */ 816 817 #if defined(DHCPv6) || \ 818 (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && \ 819 defined(USE_V4_PKTINFO)) 820 /* 821 * For both send_packet6() and receive_packet6() we need to allocate 822 * space for the cmsg header information. We do this once and reuse 823 * the buffer. We also need the control buf for send_packet() and 824 * receive_packet() when we use a single socket and IP_PKTINFO to 825 * send the packet out the correct interface. 826 */ 827 static void *control_buf = NULL; 828 static size_t control_buf_len = 0; 829 830 static void 831 allocate_cmsg_cbuf(void) { 832 control_buf_len = CMSG_SPACE(sizeof(struct in6_pktinfo)); 833 control_buf = dmalloc(control_buf_len, MDL); 834 return; 835 } 836 #endif /* DHCPv6, IP_PKTINFO ... */ 837 838 #ifdef DHCPv6 839 /* 840 * For both send_packet6() and receive_packet6() we need to use the 841 * sendmsg()/recvmsg() functions rather than the simpler send()/recv() 842 * functions. 843 * 844 * In the case of send_packet6(), we need to do this in order to insure 845 * that the reply packet leaves on the same interface that it arrived 846 * on. 847 * 848 * In the case of receive_packet6(), we need to do this in order to 849 * get the IP address the packet was sent to. This is used to identify 850 * whether a packet is multicast or unicast. 851 * 852 * Helpful man pages: recvmsg, readv (talks about the iovec stuff), cmsg. 853 * 854 * Also see the sections in RFC 3542 about IPV6_PKTINFO. 855 */ 856 857 /* Send an IPv6 packet */ 858 ssize_t send_packet6(struct interface_info *interface, 859 const unsigned char *raw, size_t len, 860 struct sockaddr_in6 *to) { 861 struct msghdr m; 862 struct iovec v; 863 struct sockaddr_in6 dst; 864 int result; 865 struct in6_pktinfo *pktinfo; 866 struct cmsghdr *cmsg; 867 unsigned int ifindex; 868 869 /* 870 * If necessary allocate space for the control message header. 871 * The space is common between send and receive. 872 */ 873 874 if (control_buf == NULL) { 875 allocate_cmsg_cbuf(); 876 if (control_buf == NULL) { 877 log_error("send_packet6: unable to allocate cmsg header"); 878 return(ENOMEM); 879 } 880 } 881 memset(control_buf, 0, control_buf_len); 882 883 /* 884 * Initialize our message header structure. 885 */ 886 memset(&m, 0, sizeof(m)); 887 888 /* 889 * Set the target address we're sending to. 890 * Enforce the scope ID for bogus BSDs. 891 */ 892 memcpy(&dst, to, sizeof(dst)); 893 m.msg_name = &dst; 894 m.msg_namelen = sizeof(dst); 895 ifindex = if_nametoindex(interface->name); 896 897 // Per OpenBSD patch-common_socket_c,v 1.7 2018/03/06 08:37:39 sthen Exp 898 // always set the scope id. We'll leave the test for no global socket 899 // in place for all others. 900 #ifndef __OpenBSD__ 901 if (no_global_v6_socket) 902 #endif 903 dst.sin6_scope_id = ifindex; 904 905 /* 906 * Set the data buffer we're sending. (Using this wacky 907 * "scatter-gather" stuff... we only have a single chunk 908 * of data to send, so we declare a single vector entry.) 909 */ 910 v.iov_base = (char *)raw; 911 v.iov_len = len; 912 m.msg_iov = &v; 913 m.msg_iovlen = 1; 914 915 /* 916 * Setting the interface is a bit more involved. 917 * 918 * We have to create a "control message", and set that to 919 * define the IPv6 packet information. We could set the 920 * source address if we wanted, but we can safely let the 921 * kernel decide what that should be. 922 */ 923 m.msg_control = control_buf; 924 m.msg_controllen = control_buf_len; 925 cmsg = CMSG_FIRSTHDR(&m); 926 INSIST(cmsg != NULL); 927 cmsg->cmsg_level = IPPROTO_IPV6; 928 cmsg->cmsg_type = IPV6_PKTINFO; 929 cmsg->cmsg_len = CMSG_LEN(sizeof(*pktinfo)); 930 pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); 931 memset(pktinfo, 0, sizeof(*pktinfo)); 932 pktinfo->ipi6_addr = local_address6; 933 pktinfo->ipi6_ifindex = ifindex; 934 935 result = sendmsg(interface->wfdesc, &m, 0); 936 if (result < 0) { 937 log_error("send_packet6: %m"); 938 } 939 return result; 940 } 941 #endif /* DHCPv6 */ 942 943 #ifdef USE_SOCKET_RECEIVE 944 ssize_t receive_packet (interface, buf, len, from, hfrom) 945 struct interface_info *interface; 946 unsigned char *buf; 947 size_t len; 948 struct sockaddr_in *from; 949 struct hardware *hfrom; 950 { 951 #if !(defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)) 952 SOCKLEN_T flen = sizeof *from; 953 #endif 954 int result; 955 956 /* 957 * The normal Berkeley socket interface doesn't give us any way 958 * to know what hardware interface we received the message on, 959 * but we should at least make sure the structure is emptied. 960 */ 961 memset(hfrom, 0, sizeof(*hfrom)); 962 963 #ifdef IGNORE_HOSTUNREACH 964 int retry = 0; 965 do { 966 #endif 967 968 #if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO) 969 struct msghdr m; 970 struct iovec v; 971 struct cmsghdr *cmsg; 972 struct in_pktinfo *pktinfo; 973 unsigned int ifindex; 974 975 /* 976 * If necessary allocate space for the control message header. 977 * The space is common between send and receive. 978 */ 979 if (control_buf == NULL) { 980 allocate_cmsg_cbuf(); 981 if (control_buf == NULL) { 982 log_error("receive_packet: unable to allocate cmsg " 983 "header"); 984 return(ENOMEM); 985 } 986 } 987 memset(control_buf, 0, control_buf_len); 988 989 /* 990 * Initialize our message header structure. 991 */ 992 memset(&m, 0, sizeof(m)); 993 994 /* 995 * Point so we can get the from address. 996 */ 997 m.msg_name = from; 998 m.msg_namelen = sizeof(*from); 999 1000 /* 1001 * Set the data buffer we're receiving. (Using this wacky 1002 * "scatter-gather" stuff... but we that doesn't really make 1003 * sense for us, so we use a single vector entry.) 1004 */ 1005 v.iov_base = buf; 1006 v.iov_len = len; 1007 m.msg_iov = &v; 1008 m.msg_iovlen = 1; 1009 1010 /* 1011 * Getting the interface is a bit more involved. 1012 * 1013 * We set up some space for a "control message". We have 1014 * previously asked the kernel to give us packet 1015 * information (when we initialized the interface), so we 1016 * should get the interface index from that. 1017 */ 1018 m.msg_control = control_buf; 1019 m.msg_controllen = control_buf_len; 1020 1021 result = recvmsg(interface->rfdesc, &m, 0); 1022 1023 if (result >= 0) { 1024 /* 1025 * If we did read successfully, then we need to loop 1026 * through the control messages we received and 1027 * find the one with our inteface index. 1028 */ 1029 cmsg = CMSG_FIRSTHDR(&m); 1030 while (cmsg != NULL) { 1031 if ((cmsg->cmsg_level == IPPROTO_IP) && 1032 (cmsg->cmsg_type == IP_PKTINFO)) { 1033 pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); 1034 ifindex = pktinfo->ipi_ifindex; 1035 /* 1036 * We pass the ifindex back to the caller 1037 * using the unused hfrom parameter avoiding 1038 * interface changes between sockets and 1039 * the discover code. 1040 */ 1041 memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex)); 1042 return (result); 1043 } 1044 cmsg = CMSG_NXTHDR(&m, cmsg); 1045 } 1046 1047 /* 1048 * We didn't find the necessary control message 1049 * flag it as an error 1050 */ 1051 result = -1; 1052 errno = EIO; 1053 } 1054 #else 1055 result = recvfrom(interface -> rfdesc, (char *)buf, len, 0, 1056 (struct sockaddr *)from, &flen); 1057 #endif /* IP_PKTINFO ... */ 1058 #ifdef IGNORE_HOSTUNREACH 1059 } while (result < 0 && 1060 (errno == EHOSTUNREACH || 1061 errno == ECONNREFUSED) && 1062 retry++ < 10); 1063 #endif 1064 return (result); 1065 } 1066 1067 #endif /* USE_SOCKET_RECEIVE */ 1068 1069 #ifdef DHCPv6 1070 ssize_t 1071 receive_packet6(struct interface_info *interface, 1072 unsigned char *buf, size_t len, 1073 struct sockaddr_in6 *from, struct in6_addr *to_addr, 1074 unsigned int *if_idx) 1075 { 1076 struct msghdr m; 1077 struct iovec v; 1078 int result; 1079 struct cmsghdr *cmsg; 1080 struct in6_pktinfo *pktinfo; 1081 1082 /* 1083 * If necessary allocate space for the control message header. 1084 * The space is common between send and receive. 1085 */ 1086 if (control_buf == NULL) { 1087 allocate_cmsg_cbuf(); 1088 if (control_buf == NULL) { 1089 log_error("receive_packet6: unable to allocate cmsg " 1090 "header"); 1091 return(ENOMEM); 1092 } 1093 } 1094 memset(control_buf, 0, control_buf_len); 1095 1096 /* 1097 * Initialize our message header structure. 1098 */ 1099 memset(&m, 0, sizeof(m)); 1100 1101 /* 1102 * Point so we can get the from address. 1103 */ 1104 m.msg_name = from; 1105 m.msg_namelen = sizeof(*from); 1106 1107 /* 1108 * Set the data buffer we're receiving. (Using this wacky 1109 * "scatter-gather" stuff... but we that doesn't really make 1110 * sense for us, so we use a single vector entry.) 1111 */ 1112 v.iov_base = buf; 1113 v.iov_len = len; 1114 m.msg_iov = &v; 1115 m.msg_iovlen = 1; 1116 1117 /* 1118 * Getting the interface is a bit more involved. 1119 * 1120 * We set up some space for a "control message". We have 1121 * previously asked the kernel to give us packet 1122 * information (when we initialized the interface), so we 1123 * should get the destination address from that. 1124 */ 1125 m.msg_control = control_buf; 1126 m.msg_controllen = control_buf_len; 1127 1128 result = recvmsg(interface->rfdesc, &m, 0); 1129 1130 if (result >= 0) { 1131 /* 1132 * If we did read successfully, then we need to loop 1133 * through the control messages we received and 1134 * find the one with our destination address. 1135 */ 1136 cmsg = CMSG_FIRSTHDR(&m); 1137 while (cmsg != NULL) { 1138 if ((cmsg->cmsg_level == IPPROTO_IPV6) && 1139 (cmsg->cmsg_type == IPV6_PKTINFO)) { 1140 pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); 1141 *to_addr = pktinfo->ipi6_addr; 1142 *if_idx = pktinfo->ipi6_ifindex; 1143 1144 return (result); 1145 } 1146 cmsg = CMSG_NXTHDR(&m, cmsg); 1147 } 1148 1149 /* 1150 * We didn't find the necessary control message 1151 * flag is as an error 1152 */ 1153 result = -1; 1154 errno = EIO; 1155 } 1156 1157 return (result); 1158 } 1159 #endif /* DHCPv6 */ 1160 1161 #if defined (USE_SOCKET_FALLBACK) 1162 /* This just reads in a packet and silently discards it. */ 1163 1164 isc_result_t fallback_discard (object) 1165 omapi_object_t *object; 1166 { 1167 char buf [1540]; 1168 struct sockaddr_in from; 1169 SOCKLEN_T flen = sizeof from; 1170 int status; 1171 struct interface_info *interface; 1172 1173 if (object -> type != dhcp_type_interface) 1174 return DHCP_R_INVALIDARG; 1175 interface = (struct interface_info *)object; 1176 1177 status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0, 1178 (struct sockaddr *)&from, &flen); 1179 #if defined (DEBUG) 1180 /* Only report fallback discard errors if we're debugging. */ 1181 if (status < 0) { 1182 log_error ("fallback_discard: %m"); 1183 return ISC_R_UNEXPECTED; 1184 } 1185 #else 1186 /* ignore the fact that status value is never used */ 1187 IGNORE_UNUSED(status); 1188 #endif 1189 return ISC_R_SUCCESS; 1190 } 1191 #endif /* USE_SOCKET_FALLBACK */ 1192 1193 #if defined (USE_SOCKET_SEND) 1194 int can_unicast_without_arp (ip) 1195 struct interface_info *ip; 1196 { 1197 return 0; 1198 } 1199 1200 int can_receive_unicast_unconfigured (ip) 1201 struct interface_info *ip; 1202 { 1203 #if defined (SOCKET_CAN_RECEIVE_UNICAST_UNCONFIGURED) 1204 return 1; 1205 #else 1206 return 0; 1207 #endif 1208 } 1209 1210 int supports_multiple_interfaces (ip) 1211 struct interface_info *ip; 1212 { 1213 #if defined(SO_BINDTODEVICE) || \ 1214 (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && \ 1215 defined(USE_V4_PKTINFO)) 1216 return(1); 1217 #else 1218 return(0); 1219 #endif 1220 } 1221 1222 /* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise, 1223 do not. */ 1224 1225 void maybe_setup_fallback () 1226 { 1227 #if defined (USE_SOCKET_FALLBACK) 1228 isc_result_t status; 1229 struct interface_info *fbi = (struct interface_info *)0; 1230 if (setup_fallback (&fbi, MDL)) { 1231 fbi -> wfdesc = if_register_socket (fbi, AF_INET, 0, NULL); 1232 fbi -> rfdesc = fbi -> wfdesc; 1233 log_info ("Sending on Socket/%s%s%s", 1234 fbi -> name, 1235 (fbi -> shared_network ? "/" : ""), 1236 (fbi -> shared_network ? 1237 fbi -> shared_network -> name : "")); 1238 1239 status = omapi_register_io_object ((omapi_object_t *)fbi, 1240 if_readsocket, 0, 1241 fallback_discard, 0, 0); 1242 if (status != ISC_R_SUCCESS) 1243 log_fatal ("Can't register I/O handle for %s: %s", 1244 fbi -> name, isc_result_totext (status)); 1245 interface_dereference (&fbi, MDL); 1246 } 1247 #endif 1248 } 1249 1250 1251 #if defined(sun) && defined(USE_V4_PKTINFO) 1252 /* This code assumes the existence of SIOCGLIFHWADDR */ 1253 void 1254 get_hw_addr(const char *name, struct hardware *hw) { 1255 struct sockaddr_dl *dladdrp; 1256 int sock, i; 1257 struct lifreq lifr; 1258 1259 memset(&lifr, 0, sizeof (lifr)); 1260 (void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name)); 1261 /* 1262 * Check if the interface is a virtual or IPMP interface - in those 1263 * cases it has no hw address, so generate a random one. 1264 */ 1265 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 || 1266 ioctl(sock, SIOCGLIFFLAGS, &lifr) < 0) { 1267 if (sock != -1) 1268 (void) close(sock); 1269 1270 #ifdef DHCPv6 1271 /* 1272 * If approrpriate try this with an IPv6 socket 1273 */ 1274 if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) >= 0 && 1275 ioctl(sock, SIOCGLIFFLAGS, &lifr) >= 0) { 1276 goto flag_check; 1277 } 1278 if (sock != -1) 1279 (void) close(sock); 1280 #endif 1281 log_fatal("Couldn't get interface flags for %s: %m", name); 1282 1283 } 1284 1285 flag_check: 1286 if (lifr.lifr_flags & (IFF_VIRTUAL|IFF_IPMP)) { 1287 hw->hlen = sizeof (hw->hbuf); 1288 srandom((long)gethrtime()); 1289 1290 hw->hbuf[0] = HTYPE_IPMP; 1291 for (i = 1; i < hw->hlen; ++i) { 1292 hw->hbuf[i] = random() % 256; 1293 } 1294 1295 if (sock != -1) 1296 (void) close(sock); 1297 return; 1298 } 1299 1300 if (ioctl(sock, SIOCGLIFHWADDR, &lifr) < 0) 1301 log_fatal("Couldn't get interface hardware address for %s: %m", 1302 name); 1303 dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr; 1304 hw->hlen = dladdrp->sdl_alen+1; 1305 switch (dladdrp->sdl_type) { 1306 case DL_CSMACD: /* IEEE 802.3 */ 1307 case DL_ETHER: 1308 hw->hbuf[0] = HTYPE_ETHER; 1309 break; 1310 case DL_TPR: 1311 hw->hbuf[0] = HTYPE_IEEE802; 1312 break; 1313 case DL_FDDI: 1314 hw->hbuf[0] = HTYPE_FDDI; 1315 break; 1316 case DL_IB: 1317 hw->hbuf[0] = HTYPE_INFINIBAND; 1318 break; 1319 default: 1320 log_fatal("%s: unsupported DLPI MAC type %lu", name, 1321 (unsigned long)dladdrp->sdl_type); 1322 } 1323 1324 memcpy(hw->hbuf+1, LLADDR(dladdrp), hw->hlen-1); 1325 1326 if (sock != -1) 1327 (void) close(sock); 1328 } 1329 #endif /* defined(sun) */ 1330 1331 #endif /* USE_SOCKET_SEND */ 1332