cleanup .changes
[profile/ivi/dhcp.git] / common / raw.c
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,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
20  * Copyright (c) 1995-2003 by Internet Software Consortium
21  *
22  * Permission to use, copy, modify, and distribute this software for any
23  * purpose with or without fee is hereby granted, provided that the above
24  * copyright notice and this permission notice appear in all copies.
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  * This software has been written for Internet Systems Consortium
41  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
42  * To learn more about Internet Systems Consortium, see
43  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
44  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
45  * ``http://www.nominum.com''.
46  */
47
48 #include "dhcpd.h"
49
50 #if defined (USE_RAW_SEND)
51 #include <sys/uio.h>
52
53 /* Generic interface registration routine... */
54 void if_register_send (info)
55         struct interface_info *info;
56 {
57         struct sockaddr_in name;
58         int sock;
59         struct socklist *tmp;
60         int flag;
61
62         /* Set up the address we're going to connect to. */
63         name.sin_family = AF_INET;
64         name.sin_port = local_port;
65         name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
66         memset (name.sin_zero, 0, sizeof (name.sin_zero));
67
68         /* List addresses on which we're listening. */
69         if (!quiet_interface_discovery)
70                 log_info ("Sending on %s, port %d",
71                       piaddr (info -> address), htons (local_port));
72         if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
73                 log_fatal ("Can't create dhcp socket: %m");
74
75         /* Set the BROADCAST option so that we can broadcast DHCP responses. */
76         flag = 1;
77         if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
78                         &flag, sizeof flag) < 0)
79                 log_fatal ("Can't set SO_BROADCAST option on dhcp socket: %m");
80
81         /* Set the IP_HDRINCL flag so that we can supply our own IP
82            headers... */
83         if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
84                 log_fatal ("Can't set IP_HDRINCL flag: %m");
85
86         info -> wfdesc = sock;
87         if (!quiet_interface_discovery)
88                 log_info ("Sending on   Raw/%s%s%s",
89                       info -> name,
90                       (info -> shared_network ? "/" : ""),
91                       (info -> shared_network ?
92                        info -> shared_network -> name : ""));
93 }
94
95 void if_deregister_send (info)
96         struct interface_info *info;
97 {
98         close (info -> wfdesc);
99         info -> wfdesc = -1;
100
101         if (!quiet_interface_discovery)
102                 log_info ("Disabling output on Raw/%s%s%s",
103                       info -> name,
104                       (info -> shared_network ? "/" : ""),
105                       (info -> shared_network ?
106                        info -> shared_network -> name : ""));
107 }
108
109 size_t send_packet (interface, packet, raw, len, from, to, hto)
110         struct interface_info *interface;
111         struct packet *packet;
112         struct dhcp_packet *raw;
113         size_t len;
114         struct in_addr from;
115         struct sockaddr_in *to;
116         struct hardware *hto;
117 {
118         unsigned char buf [256];
119         int bufp = 0;
120         struct iovec iov [2];
121         int result;
122
123         /* Assemble the headers... */
124         assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
125                                 to -> sin_addr.s_addr, to -> sin_port,
126                                 (unsigned char *)raw, len);
127
128         /* Fire it off */
129         iov [0].iov_base = (char *)buf;
130         iov [0].iov_len = bufp;
131         iov [1].iov_base = (char *)raw;
132         iov [1].iov_len = len;
133
134         result = writev(interface -> wfdesc, iov, 2);
135         if (result < 0)
136                 log_error ("send_packet: %m");
137         return result;
138 }
139 #endif /* USE_SOCKET_SEND */