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