ISC DHCP  4.4.1
A reference DHCPv4 and DHCPv6 implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
raw.c
Go to the documentation of this file.
1 /* raw.c
2 
3  BSD raw socket interface code... */
4 
5 /* XXX
6 
7  It's not clear how this should work, and that lack of clarity is
8  terribly detrimental to the NetBSD 1.1 kernel - it crashes and
9  burns.
10 
11  Using raw sockets ought to be a big win over using BPF or something
12  like it, because you don't need to deal with the complexities of
13  the physical layer, but it appears not to be possible with existing
14  raw socket implementations. This may be worth revisiting in the
15  future. For now, this code can probably be considered a curiosity.
16  Sigh. */
17 
18 /*
19  * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
20  * Copyright (c) 1995-2003 by Internet Software Consortium
21  *
22  * This Source Code Form is subject to the terms of the Mozilla Public
23  * License, v. 2.0. If a copy of the MPL was not distributed with this
24  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
27  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
28  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
29  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
30  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
31  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
32  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33  *
34  * Internet Systems Consortium, Inc.
35  * 950 Charter Street
36  * Redwood City, CA 94063
37  * <info@isc.org>
38  * https://www.isc.org/
39  *
40  */
41 
42 #include "dhcpd.h"
43 
44 #if defined (USE_RAW_SEND)
45 #include <sys/uio.h>
46 
47 /* Generic interface registration routine... */
48 void if_register_send (info)
49  struct interface_info *info;
50 {
51  struct sockaddr_in name;
52  int sock;
53  struct socklist *tmp;
54  int flag;
55 
56  /* Set up the address we're going to connect to. */
57  name.sin_family = AF_INET;
58  name.sin_port = relay_port ? relay_port : local_port;
59  name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
60  memset (name.sin_zero, 0, sizeof (name.sin_zero));
61 
62  /* List addresses on which we're listening. */
64  log_info ("Sending on %s, port %d",
65  piaddr (info -> address), htons (name.sin_port));
66  if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
67  log_fatal ("Can't create dhcp socket: %m");
68 
69  /* Set the BROADCAST option so that we can broadcast DHCP responses. */
70  flag = 1;
71  if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
72  &flag, sizeof flag) < 0)
73  log_fatal ("Can't set SO_BROADCAST option on dhcp socket: %m");
74 
75  /* Set the IP_HDRINCL flag so that we can supply our own IP
76  headers... */
77  if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
78  log_fatal ("Can't set IP_HDRINCL flag: %m");
79 
80  info -> wfdesc = sock;
82  log_info ("Sending on Raw/%s%s%s",
83  info -> name,
84  (info -> shared_network ? "/" : ""),
85  (info -> shared_network ?
86  info -> shared_network -> name : ""));
87 }
88 
89 void if_deregister_send (info)
90  struct interface_info *info;
91 {
92  close (info -> wfdesc);
93  info -> wfdesc = -1;
94 
96  log_info ("Disabling output on Raw/%s%s%s",
97  info -> name,
98  (info -> shared_network ? "/" : ""),
99  (info -> shared_network ?
100  info -> shared_network -> name : ""));
101 }
102 
103 size_t send_packet (interface, packet, raw, len, from, to, hto)
104  struct interface_info *interface;
105  struct packet *packet;
106  struct dhcp_packet *raw;
107  size_t len;
108  struct in_addr from;
109  struct sockaddr_in *to;
110  struct hardware *hto;
111 {
112  unsigned char buf [256];
113  int bufp = 0;
114  struct iovec iov [2];
115  int result;
116 
117  /* Assemble the headers... */
118  assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
119  to -> sin_addr.s_addr, to -> sin_port,
120  (unsigned char *)raw, len);
121 
122  /* Fire it off */
123  iov [0].iov_base = (char *)buf;
124  iov [0].iov_len = bufp;
125  iov [1].iov_base = (char *)raw;
126  iov [1].iov_len = len;
127 
128  result = writev(interface -> wfdesc, iov, 2);
129  if (result < 0)
130  log_error ("send_packet: %m");
131  return result;
132 }
133 #endif /* USE_SOCKET_SEND */
void if_register_send(struct interface_info *)
void assemble_udp_ip_header(struct interface_info *, unsigned char *, unsigned *, u_int32_t, u_int32_t, u_int32_t, unsigned char *, unsigned)
const char * piaddr(const struct iaddr addr)
Definition: inet.c:579
int log_error(const char *,...) __attribute__((__format__(__printf__
log_fatal("no memory for uname information.")
void if_deregister_send(struct interface_info *)
u_int16_t local_port
Definition: dhclient.c:94
Definition: dhcpd.h:405
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int int log_info(const char *,...) __attribute__((__format__(__printf__
int quiet_interface_discovery
Definition: discover.c:44
u_int16_t relay_port
Definition: discover.c:47