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