]> git.ipfire.org Git - thirdparty/dhcp.git/blame - common/ctrace.c
[master] Corrected several potential null references identified by static analysis
[thirdparty/dhcp.git] / common / ctrace.c
CommitLineData
a568b5bc
TL
1/* trace.c
2
3 Subroutines that support dhcp tracing... */
4
5/*
edad9be5 6 * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 2001-2003 by Internet Software Consortium
a568b5bc 8 *
98311e4b
DH
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
a568b5bc 12 *
98311e4b
DH
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
a568b5bc 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
2c85ac9b 25 * https://www.isc.org/
a568b5bc 26 *
a568b5bc
TL
27 */
28
29#include "dhcpd.h"
30
31#if defined (TRACING)
32void trace_interface_register (trace_type_t *ttype, struct interface_info *ip)
33{
34 trace_interface_packet_t tipkt;
35
36 if (trace_record ()) {
37 memset (&tipkt, 0, sizeof tipkt);
38 memcpy (&tipkt.hw_address,
39 &ip -> hw_address, sizeof ip -> hw_address);
98bd7ca0
DH
40 if (ip->address_count)
41 memcpy(&tipkt.primary_address,
42 ip->addresses, sizeof(*ip->addresses));
a568b5bc
TL
43 memcpy (tipkt.name, ip -> name, sizeof ip -> name);
44 tipkt.index = htonl (ip -> index);
45
46 trace_write_packet (ttype, sizeof tipkt, (char *)&tipkt, MDL);
47 }
48}
49
50void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
51{
52 trace_interface_packet_t *tipkt;
53 struct interface_info *ip;
54 struct sockaddr_in *sin;
55 struct iaddr addr;
56 isc_result_t status;
57
58 if (len != sizeof *tipkt) {
c4661845
TL
59 log_error ("trace interface packet size mismatch: %ld != %d",
60 (long)(sizeof *tipkt), len);
a568b5bc
TL
61 return;
62 }
63 tipkt = (trace_interface_packet_t *)buf;
64
65 ip = (struct interface_info *)0;
66 status = interface_allocate (&ip, MDL);
67 if (status != ISC_R_SUCCESS) {
68 foo:
69 log_error ("trace_interface_input: %s.",
70 isc_result_totext (status));
71 return;
72 }
73 ip -> ifp = dmalloc (sizeof *(ip -> ifp), MDL);
74 if (!ip -> ifp) {
75 interface_dereference (&ip, MDL);
76 status = ISC_R_NOMEMORY;
77 goto foo;
78 }
79
80 memcpy (&ip -> hw_address, &tipkt -> hw_address,
81 sizeof ip -> hw_address);
98bd7ca0
DH
82 /* XXX: Without the full addresses state it's not quite a full
83 * trace.
84 */
85 ip->address_count = ip->address_max = 1;
86 ip->addresses = dmalloc(sizeof(*ip->addresses), MDL);
88c3ff5d
TM
87 if (!ip->addresses) {
88 dfree(ip->ifp, MDL);
89 ip->ifp = NULL;
90 interface_dereference (&ip, MDL);
91 status = ISC_R_NOMEMORY;
92 goto foo;
93 }
98bd7ca0 94 memcpy(ip->addresses, &tipkt->primary_address, sizeof(*ip->addresses));
a568b5bc
TL
95 memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
96 ip -> index = ntohl (tipkt -> index);
97
98 interface_snorf (ip, 0);
99 if (dhcp_interface_discovery_hook)
100 (*dhcp_interface_discovery_hook) (ip);
101
102 /* Fake up an ifp. */
103 memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
104#ifdef HAVE_SA_LEN
105 ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
106#endif
107 sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
98bd7ca0 108 sin->sin_addr = ip->addresses[0];
a568b5bc
TL
109
110 addr.len = 4;
111 memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
112 if (dhcp_interface_setup_hook)
113 (*dhcp_interface_setup_hook) (ip, &addr);
114 interface_stash (ip);
115
116 if (!quiet_interface_discovery) {
117 log_info ("Listening on Trace/%s/%s%s%s",
118 ip -> name,
119 print_hw_addr (ip -> hw_address.hbuf [0],
120 ip -> hw_address.hlen - 1,
121 &ip -> hw_address.hbuf [1]),
122 (ip -> shared_network ? "/" : ""),
123 (ip -> shared_network ?
124 ip -> shared_network -> name : ""));
125 if (strcmp (ip -> name, "fallback")) {
126 log_info ("Sending on Trace/%s/%s%s%s",
127 ip -> name,
128 print_hw_addr (ip -> hw_address.hbuf [0],
129 ip -> hw_address.hlen - 1,
130 &ip -> hw_address.hbuf [1]),
131 (ip -> shared_network ? "/" : ""),
132 (ip -> shared_network ?
133 ip -> shared_network -> name : ""));
134 }
135 }
136 interface_dereference (&ip, MDL);
137}
138
139void trace_interface_stop (trace_type_t *ttype) {
140 /* XXX */
141}
142
143void trace_inpacket_stash (struct interface_info *interface,
144 struct dhcp_packet *packet,
145 unsigned len,
146 unsigned int from_port,
147 struct iaddr from,
148 struct hardware *hfrom)
149{
150 trace_inpacket_t tip;
151 trace_iov_t iov [2];
152
153 if (!trace_record ())
154 return;
155 tip.from_port = from_port;
156 tip.from = from;
98311e4b 157 tip.from.len = htonl (tip.from.len);
a568b5bc
TL
158 if (hfrom) {
159 tip.hfrom = *hfrom;
160 tip.havehfrom = 1;
161 } else {
162 memset (&tip.hfrom, 0, sizeof tip.hfrom);
163 tip.havehfrom = 0;
164 }
165 tip.index = htonl (interface -> index);
166
167 iov [0].buf = (char *)&tip;
168 iov [0].len = sizeof tip;
169 iov [1].buf = (char *)packet;
170 iov [1].len = len;
171 trace_write_packet_iov (inpacket_trace, 2, iov, MDL);
172}
173
174void trace_inpacket_input (trace_type_t *ttype, unsigned len, char *buf)
175{
176 trace_inpacket_t *tip;
177 int index;
178
179 if (len < sizeof *tip) {
180 log_error ("trace_input_packet: too short - %d", len);
181 return;
182 }
183 tip = (trace_inpacket_t *)buf;
184 index = ntohl (tip -> index);
98311e4b 185 tip -> from.len = ntohl (tip -> from.len);
a568b5bc
TL
186
187 if (index > interface_count ||
188 index < 0 ||
189 !interface_vector [index]) {
190 log_error ("trace_input_packet: unknown interface index %d",
191 index);
192 return;
193 }
194
195 if (!bootp_packet_handler) {
196 log_error ("trace_input_packet: no bootp packet handler.");
197 return;
198 }
199
200 (*bootp_packet_handler) (interface_vector [index],
201 (struct dhcp_packet *)(tip + 1),
202 len - sizeof *tip,
203 tip -> from_port,
204 tip -> from,
205 (tip -> havehfrom ?
206 &tip -> hfrom
207 : (struct hardware *)0));
208}
209
210void trace_inpacket_stop (trace_type_t *ttype) { }
211
212ssize_t trace_packet_send (struct interface_info *interface,
213 struct packet *packet,
214 struct dhcp_packet *raw,
215 size_t len,
216 struct in_addr from,
217 struct sockaddr_in *to,
218 struct hardware *hto)
219{
220 trace_outpacket_t tip;
221 trace_iov_t iov [2];
222
223 if (trace_record ()) {
224 if (hto) {
225 tip.hto = *hto;
226 tip.havehto = 1;
227 } else {
228 memset (&tip.hto, 0, sizeof tip.hto);
229 tip.havehto = 0;
230 }
231 tip.from.len = 4;
232 memcpy (tip.from.iabuf, &from, 4);
233 tip.to.len = 4;
234 memcpy (tip.to.iabuf, &to -> sin_addr, 4);
235 tip.to_port = to -> sin_port;
236 tip.index = htonl (interface -> index);
237
238 iov [0].buf = (char *)&tip;
239 iov [0].len = sizeof tip;
240 iov [1].buf = (char *)raw;
241 iov [1].len = len;
242 trace_write_packet_iov (outpacket_trace, 2, iov, MDL);
243 }
244 if (!trace_playback ()) {
245 return send_packet (interface, packet, raw, len,
246 from, to, hto);
247 }
248 return len;
249}
250
251void trace_outpacket_input (trace_type_t *ttype, unsigned len, char *buf)
252{
253 trace_outpacket_t *tip;
254 int index;
255
256 if (len < sizeof *tip) {
257 log_error ("trace_input_packet: too short - %d", len);
258 return;
259 }
260 tip = (trace_outpacket_t *)buf;
261 index = ntohl (tip -> index);
262
263 if (index > interface_count ||
264 index < 0 ||
265 !interface_vector [index]) {
266 log_error ("trace_input_packet: unknown interface index %d",
267 index);
268 return;
269 }
270
271 /* XXX would be nice to somehow take notice of these. */
272}
273
274void trace_outpacket_stop (trace_type_t *ttype) { }
275
276void trace_seed_stash (trace_type_t *ttype, unsigned seed)
277{
278 u_int32_t outseed;
279 if (!trace_record ())
280 return;
281 outseed = htonl (seed);
282 trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
283 return;
284}
285
286void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf)
287{
288 u_int32_t *seed;
289
290 if (length != sizeof seed) {
291 log_error ("trace_seed_input: wrong size (%d)", length);
292 }
80ff6258
TL
293 seed = (u_int32_t *)buf;
294 srandom (ntohl (*seed));
a568b5bc
TL
295}
296
297void trace_seed_stop (trace_type_t *ttype) { }
298#endif /* TRACING */