Annotation of embedaddon/dhcp/omapip/mrtrace.c, revision 1.1.1.1
1.1 misho 1: /* mrtrace.c
2:
3: Subroutines that support minires tracing... */
4:
5: /*
6: * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
7: * Copyright (c) 2001-2003 by Internet Software Consortium
8: *
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.
12: *
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.
20: *
21: * Internet Systems Consortium, Inc.
22: * 950 Charter Street
23: * Redwood City, CA 94063
24: * <info@isc.org>
25: * https://www.isc.org/
26: *
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 https://www.isc.org/. To
30: * learn more about Nominum, Inc., see ``http://www.nominum.com''.
31: */
32:
33: #include "dhcpd.h"
34: #include <omapip/omapip_p.h>
35:
36: #include "minires/minires.h"
37: #include "arpa/nameser.h"
38:
39: #include <errno.h>
40:
41: #if defined(TRACING)
42: static void trace_mr_output_input (trace_type_t *, unsigned, char *);
43: static void trace_mr_output_stop (trace_type_t *);
44: static void trace_mr_input_input (trace_type_t *, unsigned, char *);
45: static void trace_mr_input_stop (trace_type_t *);
46: static void trace_mr_statp_input (trace_type_t *, unsigned, char *);
47: static void trace_mr_statp_stop (trace_type_t *);
48: static void trace_mr_randomid_input (trace_type_t *, unsigned, char *);
49: static void trace_mr_randomid_stop (trace_type_t *);
50: #endif /* TRACING */
51: trace_type_t *trace_mr_output;
52: trace_type_t *trace_mr_input;
53: trace_type_t *trace_mr_statp;
54: trace_type_t *trace_mr_randomid;
55: ssize_t trace_mr_send (int, void *, size_t, int);
56: ssize_t trace_mr_read_playback (struct sockaddr_in *, void *, size_t);
57: void trace_mr_read_record (struct sockaddr_in *, void *, ssize_t);
58: ssize_t trace_mr_recvfrom (int s, void *, size_t, int,
59: struct sockaddr *, SOCKLEN_T *);
60: ssize_t trace_mr_read (int, void *, size_t);
61: int trace_mr_connect (int s, struct sockaddr *, SOCKLEN_T);
62: int trace_mr_socket (int, int, int);
63: int trace_mr_bind (int, struct sockaddr *, SOCKLEN_T);
64: int trace_mr_close (int);
65: time_t trace_mr_time (time_t *);
66: int trace_mr_select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
67: unsigned int trace_mr_res_randomid (unsigned int);
68:
69: #if defined (TRACING)
70: void trace_mr_init ()
71: {
72: trace_mr_output = trace_type_register ("mr-output", (void *)0,
73: trace_mr_output_input,
74: trace_mr_output_stop, MDL);
75: trace_mr_input = trace_type_register ("mr-input", (void *)0,
76: trace_mr_input_input,
77: trace_mr_input_stop, MDL);
78: trace_mr_statp = trace_type_register ("mr-statp", (void *)0,
79: trace_mr_statp_input,
80: trace_mr_statp_stop, MDL);
81: trace_mr_randomid = trace_type_register ("mr-randomid", (void *)0,
82: trace_mr_randomid_input,
83: trace_mr_randomid_stop, MDL);
84: }
85:
86: void trace_mr_statp_setup (res_state statp)
87: {
88: unsigned buflen = 0;
89: char *buf = (char *)0;
90: isc_result_t status;
91: int i;
92:
93: if (trace_playback ()) {
94: int nscount;
95: status = trace_get_packet (&trace_mr_statp, &buflen, &buf);
96: if (status != ISC_R_SUCCESS) {
97: log_error ("trace_mr_statp: no statp packet found.");
98: return;
99: }
100: nscount = buflen / sizeof (struct in_addr);
101: if (nscount * (sizeof (struct in_addr)) != buflen ||
102: nscount < 1) {
103: log_error ("trace_mr_statp: bogus length: %d",
104: buflen);
105: return;
106: }
107: if (nscount > MAXNS)
108: nscount = MAXNS;
109: for (i = 0; i < nscount; i++) {
110: #if defined (HAVE_SA_LEN)
111: statp -> nsaddr_list [i].sin_len =
112: sizeof (struct sockaddr_in);
113: #endif
114: memset (&statp -> nsaddr_list [i].sin_zero, 0,
115: sizeof statp -> nsaddr_list [i].sin_zero);
116: statp -> nsaddr_list [i].sin_port = htons (53); /*XXX*/
117: statp -> nsaddr_list [i].sin_family = AF_INET;
118: memcpy (&statp -> nsaddr_list [i].sin_addr,
119: (buf + i * (sizeof (struct in_addr))),
120: sizeof (struct in_addr));
121: }
122: statp -> nscount = nscount;
123: dfree (buf, MDL);
124: buf = (char *)0;
125: }
126: if (trace_record ()) {
127: trace_iov_t *iov;
128: iov = dmalloc ((statp -> nscount *
129: sizeof (trace_iov_t)), MDL);
130: if (!iov) {
131: trace_stop ();
132: log_error ("No memory for statp iov.");
133: return;
134: }
135: for (i = 0; i < statp -> nscount; i++) {
136: iov [i].buf =
137: (char *)&statp -> nsaddr_list [i].sin_addr;
138: iov [i].len = sizeof (struct in_addr);
139: }
140: trace_write_packet_iov (trace_mr_statp, i, iov, MDL);
141: dfree (iov, MDL);
142: }
143: }
144: #endif
145:
146: ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags)
147: {
148: ssize_t rv;
149: #if defined (TRACING)
150: isc_result_t status;
151: unsigned buflen = 0;
152: char *inbuf = (char *)0;
153: u_int32_t result;
154: u_int32_t sflags;
155:
156: if (trace_playback()) {
157: status = trace_get_packet (&trace_mr_output, &buflen, &inbuf);
158: if (status != ISC_R_SUCCESS) {
159: log_error ("trace_mr_recvfrom: no input found.");
160: errno = ECONNREFUSED;
161: return -1;
162: }
163: if (buflen < sizeof result) {
164: log_error ("trace_mr_recvfrom: data too short.");
165: errno = ECONNREFUSED;
166: dfree (inbuf, MDL);
167: return -1;
168: }
169: memcpy (&result, inbuf, sizeof result);
170: rv = ntohl (result);
171: dfree (inbuf, MDL);
172: } else
173: #endif
174: rv = send (fd, msg, len, flags);
175: #if defined (TRACING)
176: if (trace_record ()) {
177: trace_iov_t iov [3];
178: result = htonl (rv);
179: sflags = htonl (flags);
180: iov [0].len = sizeof result;
181: iov [0].buf = (char *)&result;
182: iov [1].len = sizeof sflags;
183: iov [1].buf = (char *)&flags;
184: iov [2].len = len;
185: iov [2].buf = msg;
186: trace_write_packet_iov (trace_mr_output, 3, iov, MDL);
187: }
188: #endif
189: return rv;
190: }
191:
192: #if defined (TRACING)
193: ssize_t trace_mr_read_playback (struct sockaddr_in *from,
194: void *buf, size_t nbytes)
195: {
196: isc_result_t status;
197: unsigned buflen = 0, left;
198: char *inbuf = (char *)0;
199: char *bufp;
200: u_int32_t result;
201:
202: status = trace_get_packet (&trace_mr_input, &buflen, &inbuf);
203: if (status != ISC_R_SUCCESS) {
204: log_error ("trace_mr_recvfrom: no input found.");
205: errno = ECONNREFUSED;
206: return -1;
207: }
208: if (buflen < sizeof result) {
209: log_error ("trace_mr_recvfrom: data too short.");
210: errno = ECONNREFUSED;
211: dfree (inbuf, MDL);
212: return -1;
213: }
214: bufp = inbuf;
215: left = buflen;
216: memcpy (&result, bufp, sizeof result);
217: result = ntohl (result);
218: bufp += sizeof result;
219: left -= sizeof result;
220: if (result == 0) {
221: if (left < ((sizeof from -> sin_port) +
222: sizeof (from -> sin_addr))) {
223: log_error ("trace_mr_recvfrom: data too short.");
224: errno = ECONNREFUSED;
225: dfree (inbuf, MDL);
226: return -1;
227: }
228: if (from)
229: memcpy (&from -> sin_addr, bufp,
230: sizeof from -> sin_addr);
231: bufp += sizeof from -> sin_addr;
232: left -= sizeof from -> sin_addr;
233: if (from)
234: memcpy (&from -> sin_port, bufp,
235: sizeof from -> sin_port);
236: bufp += sizeof from -> sin_port;
237: left -= sizeof from -> sin_port;
238: if (from) {
239: from -> sin_family = AF_INET;
240: #if defined(HAVE_SA_LEN)
241: from -> sin_len = sizeof (struct sockaddr_in);
242: #endif
243: memset (from -> sin_zero, 0, sizeof from -> sin_zero);
244: }
245: if (left > nbytes) {
246: log_error ("trace_mr_recvfrom: too much%s",
247: " data.");
248: errno = ECONNREFUSED;
249: dfree (inbuf, MDL);
250: return -1;
251: }
252: memcpy (buf, bufp, left);
253: dfree (inbuf, MDL);
254: return left;
255: }
256: errno = ECONNREFUSED;
257: return -1;
258: }
259:
260: void trace_mr_read_record (struct sockaddr_in *from, void *buf, ssize_t rv)
261: {
262: trace_iov_t iov [4];
263: u_int32_t result;
264: int iolen = 0;
265: static char zero [4] = { 0, 0, 0, 0 };
266:
267: if (rv < 0)
268: result = htonl (errno); /* XXX */
269: else
270: result = 0;
271: iov [iolen].buf = (char *)&result;
272: iov [iolen++].len = sizeof result;
273: if (rv > 0) {
274: if (from) {
275: iov [iolen].buf = (char *)&from -> sin_addr;
276: iov [iolen++].len = sizeof from -> sin_addr;
277: iov [iolen].buf = (char *)&from -> sin_port;
278: iov [iolen++].len = sizeof from -> sin_port;
279: } else {
280: iov [iolen].buf = zero;
281: iov [iolen++].len = sizeof from -> sin_addr;
282: iov [iolen].buf = zero;
283: iov [iolen++].len = sizeof from -> sin_port;
284: }
285:
286: iov [iolen].buf = buf;
287: iov [iolen++].len = rv;
288: }
289: trace_write_packet_iov (trace_mr_input, iolen, iov, MDL);
290: }
291: #endif
292:
293: ssize_t trace_mr_recvfrom (int s, void *buf, size_t len, int flags,
294: struct sockaddr *from, SOCKLEN_T *fromlen)
295: {
296: ssize_t rv;
297:
298: #if defined (TRACING)
299: if (trace_playback ())
300: rv = trace_mr_read_playback ((struct sockaddr_in *)from,
301: buf, len);
302: else
303: #endif
304: rv = recvfrom (s, buf, len, flags, from, fromlen);
305: #if defined (TRACING)
306: if (trace_record ()) {
307: trace_mr_read_record ((struct sockaddr_in *)from, buf, rv);
308: }
309: #endif
310: return rv;
311: }
312:
313: ssize_t trace_mr_read (int d, void *buf, size_t nbytes)
314: {
315: ssize_t rv;
316:
317: #if defined (TRACING)
318: if (trace_playback ())
319: rv = trace_mr_read_playback ((struct sockaddr_in *)0,
320: buf, nbytes);
321: else
322: #endif
323: rv = read (d, buf, nbytes);
324: #if defined (TRACING)
325: if (trace_record ()) {
326: trace_mr_read_record ((struct sockaddr_in *)0, buf, rv);
327: }
328: #endif
329: return rv;
330: }
331:
332: int trace_mr_connect (int s, struct sockaddr *name, SOCKLEN_T namelen)
333: {
334: #if defined (TRACING)
335: if (!trace_playback ())
336: #endif
337: return connect (s, name, namelen);
338: #if defined (TRACING)
339: return 0;
340: #endif
341: }
342:
343: int trace_mr_socket (int domain, int type, int protocol)
344: {
345: #if defined (TRACING)
346: if (!trace_playback ())
347: #endif
348: return socket (domain, type, protocol);
349: #if defined (TRACING)
350: return 100;
351: #endif
352: }
353:
354: int trace_mr_bind (int s, struct sockaddr *name, SOCKLEN_T namelen)
355: {
356: #if defined (TRACING)
357: if (!trace_playback ())
358: #endif
359: return bind (s, name, namelen);
360: #if defined (TRACING)
361: return 0;
362: #endif
363: }
364:
365: int trace_mr_close (int s)
366: {
367: #if defined (TRACING)
368: if (!trace_playback ())
369: #endif
370: return close (s);
371: #if defined (TRACING)
372: return 0;
373: #endif
374: }
375:
376: time_t trace_mr_time (time_t *tp)
377: {
378: #if defined (TRACING)
379: if (trace_playback ()) {
380: if (tp)
381: *tp = cur_time;
382: return cur_time;
383: }
384: #endif
385: return time (tp);
386: }
387:
388: int trace_mr_select (int s, fd_set *r, fd_set *w, fd_set *x, struct timeval *t)
389: {
390: #if defined (TRACING)
391: trace_type_t *ttp = (trace_type_t *)0;
392:
393: if (trace_playback ()) {
394: time_t nct = trace_snoop_time (&ttp);
395: time_t secr = t -> tv_sec;
396: t -> tv_sec = nct - cur_time;
397: if (t -> tv_sec > secr)
398: return 0;
399: if (ttp == trace_mr_input)
400: return 1;
401: return 0;
402: }
403: #endif
404: return select (s, r, w, x, t);
405: }
406:
407: unsigned int trace_mr_res_randomid (unsigned int oldid)
408: {
409: int rid = oldid;
410: #if defined (TRACING)
411: u_int32_t id;
412: unsigned buflen = 0;
413: char *buf = (char *)0;
414: isc_result_t status;
415:
416: if (trace_playback ()) {
417: status = trace_get_packet (&trace_mr_randomid, &buflen, &buf);
418: if (status != ISC_R_SUCCESS) {
419: log_error ("trace_mr_statp: no statp packet found.");
420: return oldid;
421: }
422: if (buflen != sizeof id) {
423: log_error ("trace_mr_randomid: bogus length: %d",
424: buflen);
425: return oldid;
426: }
427: memcpy (&id, buf, sizeof id);
428: dfree (buf, MDL);
429: buf = (char *)0;
430: rid = ntohl (id);
431: }
432: if (trace_record ()) {
433: id = htonl (rid);
434: trace_write_packet (trace_mr_randomid,
435: sizeof id, (char *)&id, MDL);
436: }
437: #endif
438: return rid;
439: }
440:
441: #if defined (TRACING)
442: static void trace_mr_output_input (trace_type_t *ttype,
443: unsigned length, char *buf)
444: {
445: }
446:
447: static void trace_mr_output_stop (trace_type_t *ttype)
448: {
449: }
450:
451: static void trace_mr_input_input (trace_type_t *ttype,
452: unsigned length, char *buf)
453: {
454: log_error ("unaccounted-for minires input.");
455: }
456:
457: static void trace_mr_input_stop (trace_type_t *ttype)
458: {
459: }
460:
461: static void trace_mr_statp_input (trace_type_t *ttype,
462: unsigned length, char *buf)
463: {
464: log_error ("unaccounted-for minires statp input.");
465: }
466:
467: static void trace_mr_statp_stop (trace_type_t *ttype)
468: {
469: }
470:
471: static void trace_mr_randomid_input (trace_type_t *ttype,
472: unsigned length, char *buf)
473: {
474: log_error ("unaccounted-for minires randomid input.");
475: }
476:
477: static void trace_mr_randomid_stop (trace_type_t *ttype)
478: {
479: }
480: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>