1/* $NetBSD: dhcp4o6.c,v 1.3 2022/04/03 01:10:58 christos Exp $ */ 2 3/* dhcp4o6.c 4 5 DHCPv4 over DHCPv6 shared code... */ 6 7/* 8 * Copyright (C) 2016-2022 Internet Systems Consortium, Inc. ("ISC") 9 * 10 * This Source Code Form is subject to the terms of the Mozilla Public 11 * License, v. 2.0. If a copy of the MPL was not distributed with this 12 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 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 * PO Box 360 24 * Newmarket, NH 03857 USA 25 * <info@isc.org> 26 * https://www.isc.org/ 27 * 28 */ 29 30#include <sys/cdefs.h> 31__RCSID("$NetBSD: dhcp4o6.c,v 1.3 2022/04/03 01:10:58 christos Exp $"); 32 33#include "dhcpd.h" 34 35#ifdef DHCP4o6 36 37int dhcp4o6_fd = -1; 38omapi_object_t *dhcp4o6_object = NULL; 39omapi_object_type_t *dhcp4o6_type = NULL; 40 41static int dhcp4o6_readsocket(omapi_object_t *); 42 43/* 44 * DHCPv4 over DHCPv6 Inter Process Communication setup 45 * 46 * A UDP socket is created between ::1 port and ::1 port + 1 47 * (port is given in network order, the DHCPv6 side is bound to port, 48 * the DHCPv4 side to port + 1. The socket descriptor is stored into 49 * dhcp4o6_fd and an OMAPI handler is registered. Any failure is fatal.) 50 */ 51void dhcp4o6_setup(u_int16_t port) { 52 struct sockaddr_in6 local6, remote6; 53 int flag; 54 isc_result_t status; 55 56 /* Register DHCPv4 over DHCPv6 forwarding. */ 57 memset(&local6, 0, sizeof(local6)); 58 local6.sin6_family = AF_INET6; 59 if (local_family == AF_INET6) 60 local6.sin6_port = port; 61 else 62 local6.sin6_port = htons(ntohs(port) + 1); 63 local6.sin6_addr.s6_addr[15] = 1; 64#ifdef HAVE_SA_LEN 65 local6.sin6_len = sizeof(local6); 66#endif 67 memset(&remote6, 0, sizeof(remote6)); 68 remote6.sin6_family = AF_INET6; 69 if (local_family == AF_INET6) 70 remote6.sin6_port = htons(ntohs(port) + 1); 71 else 72 remote6.sin6_port = port; 73 remote6.sin6_addr.s6_addr[15] = 1; 74#ifdef HAVE_SA_LEN 75 remote6.sin6_len = sizeof(remote6); 76#endif 77 78 dhcp4o6_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); 79 if (dhcp4o6_fd < 0) 80 log_fatal("Can't create dhcp4o6 socket: %m"); 81 flag = 1; 82 if (setsockopt(dhcp4o6_fd, SOL_SOCKET, SO_REUSEADDR, 83 (char *)&flag, sizeof(flag)) < 0) 84 log_fatal("Can't set SO_REUSEADDR option " 85 "on dhcp4o6 socket: %m"); 86 if (bind(dhcp4o6_fd, 87 (struct sockaddr *)&local6, 88 sizeof(local6)) < 0) 89 log_fatal("Can't bind dhcp4o6 socket: %m"); 90 if (connect(dhcp4o6_fd, 91 (struct sockaddr *)&remote6, 92 sizeof(remote6)) < 0) 93 log_fatal("Can't connect dhcp4o6 socket: %m"); 94 95 /* Omapi stuff. */ 96 /* TODO: add tracing support. */ 97 status = omapi_object_type_register(&dhcp4o6_type, 98 "dhcp4o6", 99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100 sizeof(*dhcp4o6_object), 101 0, RC_MISC); 102 if (status != ISC_R_SUCCESS) 103 log_fatal("Can't register dhcp4o6 type: %s", 104 isc_result_totext(status)); 105 status = omapi_object_allocate(&dhcp4o6_object, dhcp4o6_type, 0, MDL); 106 if (status != ISC_R_SUCCESS) 107 log_fatal("Can't allocate dhcp4o6 object: %s", 108 isc_result_totext(status)); 109 status = omapi_register_io_object(dhcp4o6_object, 110 dhcp4o6_readsocket, 0, 111 dhcpv4o6_handler, 0, 0); 112 if (status != ISC_R_SUCCESS) 113 log_fatal("Can't register dhcp4o6 handle: %s", 114 isc_result_totext(status)); 115} 116 117static int dhcp4o6_readsocket(omapi_object_t *h) { 118 IGNORE_UNUSED(h); 119 return dhcp4o6_fd; 120} 121#endif /* DHCP4o6 */ 122