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