diff options
author | Francis Dupont <fdupont@isc.org> | 2016-02-23 10:49:25 +0100 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2016-02-23 10:49:25 +0100 |
commit | 52fac07044c76b97994eab51daf66bbdd256a03d (patch) | |
tree | ddff9704b50fb6eb32f6170b741dd5d94814bd4a /common | |
parent | 785c1a519e88bfebb70bd3384589de36bee02dd2 (diff) | |
download | isc-dhcp-52fac07044c76b97994eab51daf66bbdd256a03d.tar.gz |
Merged rt35711c (DHCPv4-over-DHCPv6 support) (new files)
Diffstat (limited to 'common')
-rw-r--r-- | common/dhcp4o6.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/common/dhcp4o6.c b/common/dhcp4o6.c new file mode 100644 index 00000000..4bd074c6 --- /dev/null +++ b/common/dhcp4o6.c @@ -0,0 +1,116 @@ +/* dhcp4o6.c + + DHCPv4 over DHCPv6 shared code... */ + +/* + * Copyright (c) 2016 by Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * <info@isc.org> + * https://www.isc.org/ + * + */ + +#include "dhcpd.h" + +#ifdef DHCP4o6 + +int dhcp4o6_fd = -1; +omapi_object_t *dhcp4o6_object = NULL; +omapi_object_type_t *dhcp4o6_type = NULL; + +static int dhcp4o6_readsocket(omapi_object_t *); + +/* + * DHCPv4 over DHCPv6 Inter Process Communication setup + * + * A UDP socket is created between ::1 port and ::1 port + 1 + * (port is given in network order, the DHCPv6 side is bound to port, + * the DHCPv4 side to port + 1. The socket descriptor is stored into + * dhcp4o6_fd and an OMAPI handler is registered. Any failure is fatal.) + */ +void dhcp4o6_setup(u_int16_t port) { + struct sockaddr_in6 local6, remote6; + int flag; + isc_result_t status; + + /* Register DHCPv4 over DHCPv6 forwarding. */ + memset(&local6, 0, sizeof(local6)); + local6.sin6_family = AF_INET6; + if (local_family == AF_INET6) + local6.sin6_port = port; + else + local6.sin6_port = htons(ntohs(port) + 1); + local6.sin6_addr.s6_addr[15] = 1; +#ifdef HAVE_SA_LEN + local6.sin6_len = sizeof(local6); +#endif + memset(&remote6, 0, sizeof(remote6)); + remote6.sin6_family = AF_INET6; + if (local_family == AF_INET6) + remote6.sin6_port = htons(ntohs(port) + 1); + else + remote6.sin6_port = port; + remote6.sin6_addr.s6_addr[15] = 1; +#ifdef HAVE_SA_LEN + remote6.sin6_len = sizeof(remote6); +#endif + + dhcp4o6_fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (dhcp4o6_fd < 0) + log_fatal("Can't create dhcp4o6 socket: %m"); + flag = 1; + if (setsockopt(dhcp4o6_fd, SOL_SOCKET, SO_REUSEADDR, + (char *)&flag, sizeof(flag)) < 0) + log_fatal("Can't set SO_REUSEADDR option " + "on dhcp4o6 socket: %m"); + if (bind(dhcp4o6_fd, + (struct sockaddr *)&local6, + sizeof(local6)) < 0) + log_fatal("Can't bind dhcp4o6 socket: %m"); + if (connect(dhcp4o6_fd, + (struct sockaddr *)&remote6, + sizeof(remote6)) < 0) + log_fatal("Can't connect dhcp4o6 socket: %m"); + + /* Omapi stuff. */ + /* TODO: add tracing support. */ + status = omapi_object_type_register(&dhcp4o6_type, + "dhcp4o6", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + sizeof(*dhcp4o6_object), + 0, RC_MISC); + if (status != ISC_R_SUCCESS) + log_fatal("Can't register dhcp4o6 type: %s", + isc_result_totext(status)); + status = omapi_object_allocate(&dhcp4o6_object, dhcp4o6_type, 0, MDL); + if (status != ISC_R_SUCCESS) + log_fatal("Can't allocate dhcp4o6 object: %s", + isc_result_totext(status)); + status = omapi_register_io_object(dhcp4o6_object, + dhcp4o6_readsocket, 0, + dhcpv4o6_handler, 0, 0); + if (status != ISC_R_SUCCESS) + log_fatal("Can't register dhcp4o6 handle: %s", + isc_result_totext(status)); +} + +static int dhcp4o6_readsocket(omapi_object_t *h) { + IGNORE_UNUSED(h); + return dhcp4o6_fd; +} +#endif /* DHCP4o6 */ |