Home | History | Annotate | Line # | Download | only in common
      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 (at) 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 
     37 int dhcp4o6_fd = -1;
     38 omapi_object_t *dhcp4o6_object = NULL;
     39 omapi_object_type_t *dhcp4o6_type = NULL;
     40 
     41 static 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  */
     51 void 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 
    117 static int dhcp4o6_readsocket(omapi_object_t *h) {
    118 	IGNORE_UNUSED(h);
    119 	return dhcp4o6_fd;
    120 }
    121 #endif /* DHCP4o6 */
    122