3 BSD raw socket interface code... */
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
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.
19 * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
20 * Copyright (c) 1995-2003 by Internet Software Consortium
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/.
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.
34 * Internet Systems Consortium, Inc.
36 * Newmarket, NH 03857 USA
38 * https://www.isc.org/
44 #if defined (USE_RAW_SEND)
47 /* Generic interface registration routine... */
48 void if_register_send (info
)
49 struct interface_info
*info
;
51 struct sockaddr_in name
;
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
));
62 /* List addresses on which we're listening. */
63 if (!quiet_interface_discovery
)
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");
69 /* Set the BROADCAST option so that we can broadcast DHCP responses. */
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");
75 /* Set the IP_HDRINCL flag so that we can supply our own IP
77 if (setsockopt (sock
, IPPROTO_IP
, IP_HDRINCL
, &flag
, sizeof flag
) < 0)
78 log_fatal ("Can't set IP_HDRINCL flag: %m");
80 info
-> wfdesc
= sock
;
81 if (!quiet_interface_discovery
)
82 log_info ("Sending on Raw/%s%s%s",
84 (info
-> shared_network
? "/" : ""),
85 (info
-> shared_network
?
86 info
-> shared_network
-> name
: ""));
89 void if_deregister_send (info
)
90 struct interface_info
*info
;
92 close (info
-> wfdesc
);
95 if (!quiet_interface_discovery
)
96 log_info ("Disabling output on Raw/%s%s%s",
98 (info
-> shared_network
? "/" : ""),
99 (info
-> shared_network
?
100 info
-> shared_network
-> name
: ""));
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
;
109 struct sockaddr_in
*to
;
110 struct hardware
*hto
;
112 unsigned char buf
[256];
114 struct iovec iov
[2];
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
);
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
;
128 result
= writev(interface
-> wfdesc
, iov
, 2);
130 log_error ("send_packet: %m");
133 #endif /* USE_SOCKET_SEND */