xref: /netbsd/external/mpl/dhcp/dist/common/dhcp4o6.c (revision 13df4856)
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 
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  */
dhcp4o6_setup(u_int16_t port)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 
dhcp4o6_readsocket(omapi_object_t * h)117 static int dhcp4o6_readsocket(omapi_object_t *h) {
118 	IGNORE_UNUSED(h);
119 	return dhcp4o6_fd;
120 }
121 #endif /* DHCP4o6 */
122