1 /* $NetBSD: ctrace.c,v 1.1.1.2 2014/07/12 11:57:40 spz Exp $ */
4 Subroutines that support dhcp tracing... */
7 * Copyright (c) 2004,2007,2009,2014 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 2001-2003 by Internet Software Consortium
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 * Internet Systems Consortium, Inc.
24 * Redwood City, CA 94063
26 * https://www.isc.org/
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: ctrace.c,v 1.1.1.2 2014/07/12 11:57:40 spz Exp $");
36 void trace_interface_register (trace_type_t
*ttype
, struct interface_info
*ip
)
38 trace_interface_packet_t tipkt
;
40 if (trace_record ()) {
41 memset (&tipkt
, 0, sizeof tipkt
);
42 memcpy (&tipkt
.hw_address
,
43 &ip
-> hw_address
, sizeof ip
-> hw_address
);
44 if (ip
->address_count
)
45 memcpy(&tipkt
.primary_address
,
46 ip
->addresses
, sizeof(*ip
->addresses
));
47 memcpy (tipkt
.name
, ip
-> name
, sizeof ip
-> name
);
48 tipkt
.index
= htonl (ip
-> index
);
50 trace_write_packet (ttype
, sizeof tipkt
, (char *)&tipkt
, MDL
);
54 void trace_interface_input (trace_type_t
*ttype
, unsigned len
, char *buf
)
56 trace_interface_packet_t
*tipkt
;
57 struct interface_info
*ip
;
58 struct sockaddr_in
*sin
;
62 if (len
!= sizeof *tipkt
) {
63 log_error ("trace interface packet size mismatch: %ld != %d",
64 (long)(sizeof *tipkt
), len
);
67 tipkt
= (trace_interface_packet_t
*)buf
;
69 ip
= (struct interface_info
*)0;
70 status
= interface_allocate (&ip
, MDL
);
71 if (status
!= ISC_R_SUCCESS
) {
73 log_error ("trace_interface_input: %s.",
74 isc_result_totext (status
));
77 ip
-> ifp
= dmalloc (sizeof *(ip
-> ifp
), MDL
);
79 interface_dereference (&ip
, MDL
);
80 status
= ISC_R_NOMEMORY
;
84 memcpy (&ip
-> hw_address
, &tipkt
-> hw_address
,
85 sizeof ip
-> hw_address
);
86 /* XXX: Without the full addresses state it's not quite a full
89 ip
->address_count
= ip
->address_max
= 1;
90 ip
->addresses
= dmalloc(sizeof(*ip
->addresses
), MDL
);
91 memcpy(ip
->addresses
, &tipkt
->primary_address
, sizeof(*ip
->addresses
));
92 memcpy (ip
-> name
, tipkt
-> name
, sizeof ip
-> name
);
93 ip
-> index
= ntohl (tipkt
-> index
);
95 interface_snorf (ip
, 0);
96 if (dhcp_interface_discovery_hook
)
97 (*dhcp_interface_discovery_hook
) (ip
);
100 memcpy (ip
-> ifp
-> ifr_name
, ip
-> name
, sizeof ip
-> name
);
102 ip
-> ifp
-> ifr_addr
.sa_len
= sizeof (struct sockaddr_in
);
104 sin
= (struct sockaddr_in
*)&ip
-> ifp
-> ifr_addr
;
105 sin
->sin_addr
= ip
->addresses
[0];
108 memcpy (addr
.iabuf
, &sin
-> sin_addr
.s_addr
, addr
.len
);
109 if (dhcp_interface_setup_hook
)
110 (*dhcp_interface_setup_hook
) (ip
, &addr
);
111 interface_stash (ip
);
113 if (!quiet_interface_discovery
) {
114 log_info ("Listening on Trace/%s/%s%s%s",
116 print_hw_addr (ip
-> hw_address
.hbuf
[0],
117 ip
-> hw_address
.hlen
- 1,
118 &ip
-> hw_address
.hbuf
[1]),
119 (ip
-> shared_network
? "/" : ""),
120 (ip
-> shared_network
?
121 ip
-> shared_network
-> name
: ""));
122 if (strcmp (ip
-> name
, "fallback")) {
123 log_info ("Sending on Trace/%s/%s%s%s",
125 print_hw_addr (ip
-> hw_address
.hbuf
[0],
126 ip
-> hw_address
.hlen
- 1,
127 &ip
-> hw_address
.hbuf
[1]),
128 (ip
-> shared_network
? "/" : ""),
129 (ip
-> shared_network
?
130 ip
-> shared_network
-> name
: ""));
133 interface_dereference (&ip
, MDL
);
136 void trace_interface_stop (trace_type_t
*ttype
) {
140 void trace_inpacket_stash (struct interface_info
*interface
,
141 struct dhcp_packet
*packet
,
143 unsigned int from_port
,
145 struct hardware
*hfrom
)
147 trace_inpacket_t tip
;
150 if (!trace_record ())
152 tip
.from_port
= from_port
;
154 tip
.from
.len
= htonl (tip
.from
.len
);
159 memset (&tip
.hfrom
, 0, sizeof tip
.hfrom
);
162 tip
.index
= htonl (interface
-> index
);
164 iov
[0].buf
= (char *)&tip
;
165 iov
[0].len
= sizeof tip
;
166 iov
[1].buf
= (char *)packet
;
168 trace_write_packet_iov (inpacket_trace
, 2, iov
, MDL
);
171 void trace_inpacket_input (trace_type_t
*ttype
, unsigned len
, char *buf
)
173 trace_inpacket_t
*tip
;
176 if (len
< sizeof *tip
) {
177 log_error ("trace_input_packet: too short - %d", len
);
180 tip
= (trace_inpacket_t
*)buf
;
181 index
= ntohl (tip
-> index
);
182 tip
-> from
.len
= ntohl (tip
-> from
.len
);
184 if (index
> interface_count
||
186 !interface_vector
[index
]) {
187 log_error ("trace_input_packet: unknown interface index %d",
192 if (!bootp_packet_handler
) {
193 log_error ("trace_input_packet: no bootp packet handler.");
197 (*bootp_packet_handler
) (interface_vector
[index
],
198 (struct dhcp_packet
*)(tip
+ 1),
204 : (struct hardware
*)0));
207 void trace_inpacket_stop (trace_type_t
*ttype
) { }
209 ssize_t
trace_packet_send (struct interface_info
*interface
,
210 struct packet
*packet
,
211 struct dhcp_packet
*raw
,
214 struct sockaddr_in
*to
,
215 struct hardware
*hto
)
217 trace_outpacket_t tip
;
220 if (trace_record ()) {
225 memset (&tip
.hto
, 0, sizeof tip
.hto
);
229 memcpy (tip
.from
.iabuf
, &from
, 4);
231 memcpy (tip
.to
.iabuf
, &to
-> sin_addr
, 4);
232 tip
.to_port
= to
-> sin_port
;
233 tip
.index
= htonl (interface
-> index
);
235 iov
[0].buf
= (char *)&tip
;
236 iov
[0].len
= sizeof tip
;
237 iov
[1].buf
= (char *)raw
;
239 trace_write_packet_iov (outpacket_trace
, 2, iov
, MDL
);
241 if (!trace_playback ()) {
242 return send_packet (interface
, packet
, raw
, len
,
248 void trace_outpacket_input (trace_type_t
*ttype
, unsigned len
, char *buf
)
250 trace_outpacket_t
*tip
;
253 if (len
< sizeof *tip
) {
254 log_error ("trace_input_packet: too short - %d", len
);
257 tip
= (trace_outpacket_t
*)buf
;
258 index
= ntohl (tip
-> index
);
260 if (index
> interface_count
||
262 !interface_vector
[index
]) {
263 log_error ("trace_input_packet: unknown interface index %d",
268 /* XXX would be nice to somehow take notice of these. */
271 void trace_outpacket_stop (trace_type_t
*ttype
) { }
273 void trace_seed_stash (trace_type_t
*ttype
, unsigned seed
)
276 if (!trace_record ())
278 outseed
= htonl (seed
);
279 trace_write_packet (ttype
, sizeof outseed
, (char *)&outseed
, MDL
);
283 void trace_seed_input (trace_type_t
*ttype
, unsigned length
, char *buf
)
287 if (length
!= sizeof seed
) {
288 log_error ("trace_seed_input: wrong size (%d)", length
);
290 seed
= (u_int32_t
*)buf
;
291 srandom (ntohl (*seed
));
294 void trace_seed_stop (trace_type_t
*ttype
) { }