3 Subroutines that support minires tracing... */
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 2001-2003 by Internet Software Consortium
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.
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.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon, as part of a project for Nominum, Inc. To learn more
29 * about Internet Systems Consortium, see http://www.isc.org/. To
30 * learn more about Nominum, Inc., see ``http://www.nominum.com''.
33 #include <omapip/omapip_p.h>
35 #include "minires/minires.h"
36 #include "arpa/nameser.h"
38 static void trace_mr_output_input (trace_type_t
*, unsigned, char *);
39 static void trace_mr_output_stop (trace_type_t
*);
40 static void trace_mr_input_input (trace_type_t
*, unsigned, char *);
41 static void trace_mr_input_stop (trace_type_t
*);
42 static void trace_mr_statp_input (trace_type_t
*, unsigned, char *);
43 static void trace_mr_statp_stop (trace_type_t
*);
44 static void trace_mr_randomid_input (trace_type_t
*, unsigned, char *);
45 static void trace_mr_randomid_stop (trace_type_t
*);
46 trace_type_t
*trace_mr_output
;
47 trace_type_t
*trace_mr_input
;
48 trace_type_t
*trace_mr_statp
;
49 trace_type_t
*trace_mr_randomid
;
50 ssize_t
trace_mr_send (int, void *, size_t, int);
51 ssize_t
trace_mr_read_playback (struct sockaddr_in
*, void *, size_t);
52 void trace_mr_read_record (struct sockaddr_in
*, void *, ssize_t
);
53 ssize_t
trace_mr_recvfrom (int s
, void *, size_t, int,
54 struct sockaddr
*, SOCKLEN_T
*);
55 ssize_t
trace_mr_read (int, void *, size_t);
56 int trace_mr_connect (int s
, struct sockaddr
*, SOCKLEN_T
);
57 int trace_mr_socket (int, int, int);
58 int trace_mr_bind (int, struct sockaddr
*, SOCKLEN_T
);
59 int trace_mr_close (int);
60 time_t trace_mr_time (time_t *);
61 int trace_mr_select (int, fd_set
*, fd_set
*, fd_set
*, struct timeval
*);
62 unsigned int trace_mr_res_randomid (unsigned int);
69 trace_mr_output
= trace_type_register ("mr-output", (void *)0,
70 trace_mr_output_input
,
71 trace_mr_output_stop
, MDL
);
72 trace_mr_input
= trace_type_register ("mr-input", (void *)0,
74 trace_mr_input_stop
, MDL
);
75 trace_mr_statp
= trace_type_register ("mr-statp", (void *)0,
77 trace_mr_statp_stop
, MDL
);
78 trace_mr_randomid
= trace_type_register ("mr-randomid", (void *)0,
79 trace_mr_randomid_input
,
80 trace_mr_randomid_stop
, MDL
);
83 void trace_mr_statp_setup (res_state statp
)
86 char *buf
= (char *)0;
90 if (trace_playback ()) {
92 status
= trace_get_packet (&trace_mr_statp
, &buflen
, &buf
);
93 if (status
!= ISC_R_SUCCESS
) {
94 log_error ("trace_mr_statp: no statp packet found.");
97 nscount
= buflen
/ sizeof (struct in_addr
);
98 if (nscount
* (sizeof (struct in_addr
)) != buflen
||
100 log_error ("trace_mr_statp: bogus length: %d",
106 for (i
= 0; i
< nscount
; i
++) {
107 #if defined (HAVE_SA_LEN)
108 statp
-> nsaddr_list
[i
].sin_len
=
109 sizeof (struct sockaddr_in
);
111 memset (&statp
-> nsaddr_list
[i
], 0,
112 sizeof statp
-> nsaddr_list
[i
]);
113 statp
-> nsaddr_list
[i
].sin_port
= htons (53); /*XXX*/
114 statp
-> nsaddr_list
[i
].sin_family
= AF_INET
;
115 memcpy (&statp
-> nsaddr_list
[i
].sin_addr
,
116 (buf
+ i
* (sizeof (struct in_addr
))),
117 sizeof (struct in_addr
));
119 statp
-> nscount
= nscount
;
123 if (trace_record ()) {
125 iov
= dmalloc ((statp
-> nscount
*
126 sizeof (trace_iov_t
)), MDL
);
129 log_error ("No memory for statp iov.");
132 for (i
= 0; i
< statp
-> nscount
; i
++) {
134 (char *)&statp
-> nsaddr_list
[i
].sin_addr
;
135 iov
[i
].len
= sizeof (struct in_addr
);
137 trace_write_packet_iov (trace_mr_statp
, i
, iov
, MDL
);
143 ssize_t
trace_mr_send (int fd
, void *msg
, size_t len
, int flags
)
146 #if defined (TRACING)
149 char *inbuf
= (char *)0;
153 if (trace_playback()) {
154 status
= trace_get_packet (&trace_mr_output
, &buflen
, &inbuf
);
155 if (status
!= ISC_R_SUCCESS
) {
156 log_error ("trace_mr_recvfrom: no input found.");
157 errno
= ECONNREFUSED
;
160 if (buflen
< sizeof result
) {
161 log_error ("trace_mr_recvfrom: data too short.");
162 errno
= ECONNREFUSED
;
166 memcpy (&result
, inbuf
, sizeof result
);
171 rv
= send (fd
, msg
, len
, flags
);
172 #if defined (TRACING)
173 if (trace_record ()) {
176 sflags
= htonl (flags
);
177 iov
[0].len
= sizeof result
;
178 iov
[0].buf
= (char *)&result
;
179 iov
[1].len
= sizeof sflags
;
180 iov
[1].buf
= (char *)&flags
;
183 trace_write_packet_iov (trace_mr_output
, 3, iov
, MDL
);
189 #if defined (TRACING)
190 ssize_t
trace_mr_read_playback (struct sockaddr_in
*from
,
191 void *buf
, size_t nbytes
)
194 unsigned buflen
= 0, left
;
195 char *inbuf
= (char *)0;
199 status
= trace_get_packet (&trace_mr_input
, &buflen
, &inbuf
);
200 if (status
!= ISC_R_SUCCESS
) {
201 log_error ("trace_mr_recvfrom: no input found.");
202 errno
= ECONNREFUSED
;
205 if (buflen
< sizeof result
) {
206 log_error ("trace_mr_recvfrom: data too short.");
207 errno
= ECONNREFUSED
;
213 memcpy (&result
, bufp
, sizeof result
);
214 result
= ntohl (result
);
215 bufp
+= sizeof result
;
216 left
-= sizeof result
;
218 if (left
< ((sizeof from
-> sin_port
) +
219 sizeof (from
-> sin_addr
))) {
220 log_error ("trace_mr_recvfrom: data too short.");
221 errno
= ECONNREFUSED
;
226 memset (from
, 0, sizeof *from
);
228 memcpy (&from
-> sin_addr
, bufp
,
229 sizeof from
-> sin_addr
);
230 bufp
+= sizeof from
-> sin_addr
;
231 left
-= sizeof from
-> sin_addr
;
233 memcpy (&from
-> sin_port
, bufp
,
234 sizeof from
-> sin_port
);
235 bufp
+= sizeof from
-> sin_port
;
236 left
-= sizeof from
-> sin_port
;
238 from
-> sin_family
= AF_INET
;
239 #if defined(HAVE_SA_LEN)
240 from
-> sin_len
= sizeof (struct sockaddr_in
);
244 log_error ("trace_mr_recvfrom: too much%s",
246 errno
= ECONNREFUSED
;
250 memcpy (buf
, bufp
, left
);
254 errno
= ECONNREFUSED
;
258 void trace_mr_read_record (struct sockaddr_in
*from
, void *buf
, ssize_t rv
)
263 static char zero
[4] = { 0, 0, 0, 0 };
266 result
= htonl (errno
); /* XXX */
269 iov
[iolen
].buf
= (char *)&result
;
270 iov
[iolen
++].len
= sizeof result
;
273 iov
[iolen
].buf
= (char *)&from
-> sin_addr
;
274 iov
[iolen
++].len
= sizeof from
-> sin_addr
;
275 iov
[iolen
].buf
= (char *)&from
-> sin_port
;
276 iov
[iolen
++].len
= sizeof from
-> sin_port
;
278 iov
[iolen
].buf
= zero
;
279 iov
[iolen
++].len
= sizeof from
-> sin_addr
;
280 iov
[iolen
].buf
= zero
;
281 iov
[iolen
++].len
= sizeof from
-> sin_port
;
284 iov
[iolen
].buf
= buf
;
285 iov
[iolen
++].len
= rv
;
287 trace_write_packet_iov (trace_mr_input
, iolen
, iov
, MDL
);
291 ssize_t
trace_mr_recvfrom (int s
, void *buf
, size_t len
, int flags
,
292 struct sockaddr
*from
, SOCKLEN_T
*fromlen
)
296 #if defined (TRACING)
297 if (trace_playback ())
298 rv
= trace_mr_read_playback ((struct sockaddr_in
*)from
,
302 rv
= recvfrom (s
, buf
, len
, flags
, from
, fromlen
);
303 #if defined (TRACING)
304 if (trace_record ()) {
305 trace_mr_read_record ((struct sockaddr_in
*)from
, buf
, rv
);
311 ssize_t
trace_mr_read (int d
, void *buf
, size_t nbytes
)
315 #if defined (TRACING)
316 if (trace_playback ())
317 rv
= trace_mr_read_playback ((struct sockaddr_in
*)0,
321 rv
= read (d
, buf
, nbytes
);
322 #if defined (TRACING)
323 if (trace_record ()) {
324 trace_mr_read_record ((struct sockaddr_in
*)0, buf
, rv
);
330 int trace_mr_connect (int s
, struct sockaddr
*name
, SOCKLEN_T namelen
)
332 #if defined (TRACING)
333 if (!trace_playback ())
335 return connect (s
, name
, namelen
);
336 #if defined (TRACING)
341 int trace_mr_socket (int domain
, int type
, int protocol
)
343 #if defined (TRACING)
344 if (!trace_playback ())
346 return socket (domain
, type
, protocol
);
347 #if defined (TRACING)
352 int trace_mr_bind (int s
, struct sockaddr
*name
, SOCKLEN_T namelen
)
354 #if defined (TRACING)
355 if (!trace_playback ())
357 return bind (s
, name
, namelen
);
358 #if defined (TRACING)
363 int trace_mr_close (int s
)
365 #if defined (TRACING)
366 if (!trace_playback ())
369 #if defined (TRACING)
374 time_t trace_mr_time (time_t *tp
)
376 #if defined (TRACING)
377 if (trace_playback ()) {
386 int trace_mr_select (int s
, fd_set
*r
, fd_set
*w
, fd_set
*x
, struct timeval
*t
)
388 #if defined (TRACING)
389 trace_type_t
*ttp
= (trace_type_t
*)0;
391 if (trace_playback ()) {
392 time_t nct
= trace_snoop_time (&ttp
);
393 time_t secr
= t
-> tv_sec
;
394 t
-> tv_sec
= nct
- cur_time
;
395 if (t
-> tv_sec
> secr
)
397 if (ttp
== trace_mr_input
)
402 return select (s
, r
, w
, x
, t
);
405 unsigned int trace_mr_res_randomid (unsigned int oldid
)
409 #if defined (TRACING)
411 char *buf
= (char *)0;
414 if (trace_playback ()) {
415 status
= trace_get_packet (&trace_mr_randomid
, &buflen
, &buf
);
416 if (status
!= ISC_R_SUCCESS
) {
417 log_error ("trace_mr_statp: no statp packet found.");
420 if (buflen
!= sizeof id
) {
421 log_error ("trace_mr_randomid: bogus length: %d",
425 memcpy (&id
, buf
, sizeof id
);
430 if (trace_record ()) {
432 trace_write_packet (trace_mr_randomid
,
433 sizeof id
, (char *)&id
, MDL
);
439 #if defined (TRACING)
440 static void trace_mr_output_input (trace_type_t
*ttype
,
441 unsigned length
, char *buf
)
445 static void trace_mr_output_stop (trace_type_t
*ttype
)
449 static void trace_mr_input_input (trace_type_t
*ttype
,
450 unsigned length
, char *buf
)
452 log_error ("unaccounted-for minires input.");
455 static void trace_mr_input_stop (trace_type_t
*ttype
)
459 static void trace_mr_statp_input (trace_type_t
*ttype
,
460 unsigned length
, char *buf
)
462 log_error ("unaccounted-for minires statp input.");
465 static void trace_mr_statp_stop (trace_type_t
*ttype
)
469 static void trace_mr_randomid_input (trace_type_t
*ttype
,
470 unsigned length
, char *buf
)
472 log_error ("unaccounted-for minires randomid input.");
475 static void trace_mr_randomid_stop (trace_type_t
*ttype
)