aboutsummaryrefslogtreecommitdiff
path: root/common/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/raw.c')
-rw-r--r--common/raw.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/common/raw.c b/common/raw.c
new file mode 100644
index 0000000..4730e8e
--- /dev/null
+++ b/common/raw.c
@@ -0,0 +1,139 @@
+/* raw.c
+
+ BSD raw socket interface code... */
+
+/* XXX
+
+ It's not clear how this should work, and that lack of clarity is
+ terribly detrimental to the NetBSD 1.1 kernel - it crashes and
+ burns.
+
+ Using raw sockets ought to be a big win over using BPF or something
+ like it, because you don't need to deal with the complexities of
+ the physical layer, but it appears not to be possible with existing
+ raw socket implementations. This may be worth revisiting in the
+ future. For now, this code can probably be considered a curiosity.
+ Sigh. */
+
+/*
+ * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * 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/
+ *
+ * This software has been written for Internet Systems Consortium
+ * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
+ * To learn more about Internet Systems Consortium, see
+ * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
+ * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
+ * ``http://www.nominum.com''.
+ */
+
+#include "dhcpd.h"
+
+#if defined (USE_RAW_SEND)
+#include <sys/uio.h>
+
+/* Generic interface registration routine... */
+void if_register_send (info)
+ struct interface_info *info;
+{
+ struct sockaddr_in name;
+ int sock;
+ struct socklist *tmp;
+ int flag;
+
+ /* Set up the address we're going to connect to. */
+ name.sin_family = AF_INET;
+ name.sin_port = local_port;
+ name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
+ memset (name.sin_zero, 0, sizeof (name.sin_zero));
+
+ /* List addresses on which we're listening. */
+ if (!quiet_interface_discovery)
+ log_info ("Sending on %s, port %d",
+ piaddr (info -> address), htons (local_port));
+ if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
+ log_fatal ("Can't create dhcp socket: %m");
+
+ /* Set the BROADCAST option so that we can broadcast DHCP responses. */
+ flag = 1;
+ if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
+ &flag, sizeof flag) < 0)
+ log_fatal ("Can't set SO_BROADCAST option on dhcp socket: %m");
+
+ /* Set the IP_HDRINCL flag so that we can supply our own IP
+ headers... */
+ if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
+ log_fatal ("Can't set IP_HDRINCL flag: %m");
+
+ info -> wfdesc = sock;
+ if (!quiet_interface_discovery)
+ log_info ("Sending on Raw/%s%s%s",
+ info -> name,
+ (info -> shared_network ? "/" : ""),
+ (info -> shared_network ?
+ info -> shared_network -> name : ""));
+}
+
+void if_deregister_send (info)
+ struct interface_info *info;
+{
+ close (info -> wfdesc);
+ info -> wfdesc = -1;
+
+ if (!quiet_interface_discovery)
+ log_info ("Disabling output on Raw/%s%s%s",
+ info -> name,
+ (info -> shared_network ? "/" : ""),
+ (info -> shared_network ?
+ info -> shared_network -> name : ""));
+}
+
+size_t send_packet (interface, packet, raw, len, from, to, hto)
+ struct interface_info *interface;
+ struct packet *packet;
+ struct dhcp_packet *raw;
+ size_t len;
+ struct in_addr from;
+ struct sockaddr_in *to;
+ struct hardware *hto;
+{
+ unsigned char buf [256];
+ int bufp = 0;
+ struct iovec iov [2];
+ int result;
+
+ /* Assemble the headers... */
+ assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
+ to -> sin_addr.s_addr, to -> sin_port,
+ (unsigned char *)raw, len);
+
+ /* Fire it off */
+ iov [0].iov_base = (char *)buf;
+ iov [0].iov_len = bufp;
+ iov [1].iov_base = (char *)raw;
+ iov [1].iov_len = len;
+
+ result = writev(interface -> wfdesc, iov, 2);
+ if (result < 0)
+ log_error ("send_packet: %m");
+ return result;
+}
+#endif /* USE_SOCKET_SEND */