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;
91 if (trace_playback ()) {
93 status
= trace_get_packet (&trace_mr_statp
, &buflen
, &buf
);
94 if (status
!= ISC_R_SUCCESS
) {
95 log_error ("trace_mr_statp: no statp packet found.");
98 nscount
= buflen
/ sizeof (struct in_addr
);
99 if (nscount
* (sizeof (struct in_addr
)) != buflen
||
101 log_error ("trace_mr_statp: bogus length: %d",
107 for (i
= 0; i
< nscount
; i
++) {
108 #if defined (HAVE_SA_LEN)
109 statp
-> nsaddr_list
[i
].sin_len
=
110 sizeof (struct sockaddr_in
);
112 memset (&statp
-> nsaddr_list
[i
].sin_zero
, 0,
113 sizeof statp
-> nsaddr_list
[i
].sin_zero
);
114 statp
-> nsaddr_list
[i
].sin_port
= htons (53); /*XXX*/
115 statp
-> nsaddr_list
[i
].sin_family
= AF_INET
;
116 memcpy (&statp
-> nsaddr_list
[i
].sin_addr
,
117 (buf
+ i
* (sizeof (struct in_addr
))),
118 sizeof (struct in_addr
));
120 statp
-> nscount
= nscount
;
124 if (trace_record ()) {
126 iov
= dmalloc ((statp
-> nscount
*
127 sizeof (trace_iov_t
)), MDL
);
130 log_error ("No memory for statp iov.");
133 for (i
= 0; i
< statp
-> nscount
; i
++) {
135 (char *)&statp
-> nsaddr_list
[i
].sin_addr
;
136 iov
[i
].len
= sizeof (struct in_addr
);
138 trace_write_packet_iov (trace_mr_statp
, i
, iov
, MDL
);
144 ssize_t
trace_mr_send (int fd
, void *msg
, size_t len
, int flags
)
147 #if defined (TRACING)
150 char *inbuf
= (char *)0;
154 if (trace_playback()) {
155 status
= trace_get_packet (&trace_mr_output
, &buflen
, &inbuf
);
156 if (status
!= ISC_R_SUCCESS
) {
157 log_error ("trace_mr_recvfrom: no input found.");
158 errno
= ECONNREFUSED
;
161 if (buflen
< sizeof result
) {
162 log_error ("trace_mr_recvfrom: data too short.");
163 errno
= ECONNREFUSED
;
167 memcpy (&result
, inbuf
, sizeof result
);
172 rv
= send (fd
, msg
, len
, flags
);
173 #if defined (TRACING)
174 if (trace_record ()) {
177 sflags
= htonl (flags
);
178 iov
[0].len
= sizeof result
;
179 iov
[0].buf
= (char *)&result
;
180 iov
[1].len
= sizeof sflags
;
181 iov
[1].buf
= (char *)&flags
;
184 trace_write_packet_iov (trace_mr_output
, 3, iov
, MDL
);
190 #if defined (TRACING)
191 ssize_t
trace_mr_read_playback (struct sockaddr_in
*from
,
192 void *buf
, size_t nbytes
)
195 unsigned buflen
= 0, left
;
196 char *inbuf
= (char *)0;
200 status
= trace_get_packet (&trace_mr_input
, &buflen
, &inbuf
);
201 if (status
!= ISC_R_SUCCESS
) {
202 log_error ("trace_mr_recvfrom: no input found.");
203 errno
= ECONNREFUSED
;
206 if (buflen
< sizeof result
) {
207 log_error ("trace_mr_recvfrom: data too short.");
208 errno
= ECONNREFUSED
;
214 memcpy (&result
, bufp
, sizeof result
);
215 result
= ntohl (result
);
216 bufp
+= sizeof result
;
217 left
-= sizeof result
;
219 if (left
< ((sizeof from
-> sin_port
) +
220 sizeof (from
-> sin_addr
))) {
221 log_error ("trace_mr_recvfrom: data too short.");
222 errno
= ECONNREFUSED
;
227 memcpy (&from
-> sin_addr
, bufp
,
228 sizeof from
-> sin_addr
);
229 bufp
+= sizeof from
-> sin_addr
;
230 left
-= sizeof from
-> sin_addr
;
232 memcpy (&from
-> sin_port
, bufp
,
233 sizeof from
-> sin_port
);
234 bufp
+= sizeof from
-> sin_port
;
235 left
-= sizeof from
-> sin_port
;
237 from
-> sin_family
= AF_INET
;
238 #if defined(HAVE_SA_LEN)
239 from
-> sin_len
= sizeof (struct sockaddr_in
);
241 memset (from
-> sin_zero
, 0, sizeof from
-> sin_zero
);
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 ())
368 #ifdef SOCKET_IS_NOT_A_FILE
369 return CloseSocket (s
);
373 #if defined (TRACING)
378 time_t trace_mr_time (time_t *tp
)
380 #if defined (TRACING)
381 if (trace_playback ()) {
390 int trace_mr_select (int s
, fd_set
*r
, fd_set
*w
, fd_set
*x
, struct timeval
*t
)
392 #if defined (TRACING)
393 trace_type_t
*ttp
= (trace_type_t
*)0;
395 if (trace_playback ()) {
396 time_t nct
= trace_snoop_time (&ttp
);
397 time_t secr
= t
-> tv_sec
;
398 t
-> tv_sec
= nct
- cur_time
;
399 if (t
-> tv_sec
> secr
)
401 if (ttp
== trace_mr_input
)
406 return select (s
, r
, w
, x
, t
);
409 unsigned int trace_mr_res_randomid (unsigned int oldid
)
413 #if defined (TRACING)
415 char *buf
= (char *)0;
418 if (trace_playback ()) {
420 status
= trace_get_packet (&trace_mr_randomid
, &buflen
, &buf
);
421 if (status
!= ISC_R_SUCCESS
) {
422 log_error ("trace_mr_statp: no statp packet found.");
425 if (buflen
!= sizeof id
) {
426 log_error ("trace_mr_randomid: bogus length: %d",
430 memcpy (&id
, buf
, sizeof id
);
435 if (trace_record ()) {
437 trace_write_packet (trace_mr_randomid
,
438 sizeof id
, (char *)&id
, MDL
);
444 #if defined (TRACING)
445 static void trace_mr_output_input (trace_type_t
*ttype
,
446 unsigned length
, char *buf
)
450 static void trace_mr_output_stop (trace_type_t
*ttype
)
454 static void trace_mr_input_input (trace_type_t
*ttype
,
455 unsigned length
, char *buf
)
457 log_error ("unaccounted-for minires input.");
460 static void trace_mr_input_stop (trace_type_t
*ttype
)
464 static void trace_mr_statp_input (trace_type_t
*ttype
,
465 unsigned length
, char *buf
)
467 log_error ("unaccounted-for minires statp input.");
470 static void trace_mr_statp_stop (trace_type_t
*ttype
)
474 static void trace_mr_randomid_input (trace_type_t
*ttype
,
475 unsigned length
, char *buf
)
477 log_error ("unaccounted-for minires randomid input.");
480 static void trace_mr_randomid_stop (trace_type_t
*ttype
)