From: Ted Lemon Date: Thu, 22 Feb 2001 07:28:58 +0000 (+0000) Subject: Add support for logging random ID and fix various bugs in minires tracing. X-Git-Tag: V3-BETA-2-PATCH-18~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dd952dd18a0df6a9932de0a6de18363c4761eeef;p=thirdparty%2Fdhcp.git Add support for logging random ID and fix various bugs in minires tracing. --- diff --git a/omapip/mrtrace.c b/omapip/mrtrace.c index ce19d3bcc..0fb67a692 100644 --- a/omapip/mrtrace.c +++ b/omapip/mrtrace.c @@ -44,19 +44,21 @@ #include "minires/minires.h" #include "arpa/nameser.h" -#if defined (TRACING) static void trace_mr_output_input (trace_type_t *, unsigned, char *); static void trace_mr_output_stop (trace_type_t *); static void trace_mr_input_input (trace_type_t *, unsigned, char *); static void trace_mr_input_stop (trace_type_t *); static void trace_mr_statp_input (trace_type_t *, unsigned, char *); static void trace_mr_statp_stop (trace_type_t *); +static void trace_mr_randomid_input (trace_type_t *, unsigned, char *); +static void trace_mr_randomid_stop (trace_type_t *); trace_type_t *trace_mr_output; trace_type_t *trace_mr_input; trace_type_t *trace_mr_statp; +trace_type_t *trace_mr_randomid; ssize_t trace_mr_send (int, void *, size_t, int); -ssize_t trace_mr_read_playback (void *, size_t); -void trace_mr_read_record (void *, ssize_t); +ssize_t trace_mr_read_playback (struct sockaddr_in *, void *, size_t); +void trace_mr_read_record (struct sockaddr_in *, void *, ssize_t); ssize_t trace_mr_recvfrom (int s, void *, size_t, int, struct sockaddr *, SOCKLEN_T *); ssize_t trace_mr_read (int, void *, size_t); @@ -66,9 +68,11 @@ int trace_mr_bind (int, const struct sockaddr *, SOCKLEN_T); int trace_mr_close (int); time_t trace_mr_time (time_t *); int trace_mr_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); +unsigned int trace_mr_res_randomid (unsigned int); extern time_t cur_time; +#if defined (TRACING) void trace_mr_init () { trace_mr_output = trace_type_register ("mr-output", (void *)0, @@ -80,6 +84,9 @@ void trace_mr_init () trace_mr_statp = trace_type_register ("mr-statp", (void *)0, trace_mr_statp_input, trace_mr_statp_stop, MDL); + trace_mr_randomid = trace_type_register ("mr-randomid", (void *)0, + trace_mr_randomid_input, + trace_mr_randomid_stop, MDL); } void trace_mr_statp_setup (res_state statp) @@ -87,6 +94,8 @@ void trace_mr_statp_setup (res_state statp) unsigned buflen = 0; char *buf = (char *)0; isc_result_t status; + u_int32_t id; + int i; if (trace_playback ()) { int nscount; @@ -95,40 +104,107 @@ void trace_mr_statp_setup (res_state statp) log_error ("trace_mr_statp: no statp packet found."); return; } - nscount = buflen / sizeof (struct sockaddr_in); - if (nscount * (sizeof (struct sockaddr_in)) != buflen) { + nscount = buflen / sizeof (struct in_addr); + if (nscount * (sizeof (struct in_addr)) != buflen || + nscount < 1) { log_error ("trace_mr_statp: bogus length: %d", buflen); return; } if (nscount > MAXNS) nscount = MAXNS; - memcpy (statp, buf, nscount * sizeof (struct sockaddr_in)); + for (i = 0; i < nscount; i++) { +#if defined (HAVE_SA_LEN) + statp -> nsaddr_list [i].sin_len = + sizeof (struct sockaddr_in); +#endif + memset (&statp -> nsaddr_list [i].sin_zero, 0, + sizeof statp -> nsaddr_list [i].sin_zero); + statp -> nsaddr_list [i].sin_port = htons (53); /*XXX*/ + statp -> nsaddr_list [i].sin_family = AF_INET; + memcpy (&statp -> nsaddr_list [i].sin_addr, + (buf + i * (sizeof (struct in_addr))), + sizeof (struct in_addr)); + } + statp -> nscount = nscount; dfree (buf, MDL); buf = (char *)0; } if (trace_record ()) { - trace_write_packet (trace_mr_statp, - statp -> nscount * sizeof (struct sockaddr_in), - (char *)statp -> nsaddr_list, MDL); + trace_iov_t *iov; + iov = dmalloc ((statp -> nscount * + sizeof (struct in_addr)), MDL); + if (!iov) { + trace_stop (); + log_error ("No memory for statp iov."); + return; + } + for (i = 0; i < statp -> nscount; i++) { + iov [i].buf = + (char *)&statp -> nsaddr_list [i].sin_addr; + iov [i].len = sizeof (struct in_addr); + } + trace_write_packet_iov (trace_mr_statp, i, iov, MDL); + dfree (iov, MDL); } } - +#endif ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags) { - if (trace_record ()) - trace_write_packet (trace_mr_output, len, msg, MDL); - return send (fd, msg, len, flags); + ssize_t rv; +#if defined (TRACING) + isc_result_t status; + unsigned buflen = 0; + char *inbuf = (char *)0; + u_int32_t result; + u_int32_t sflags; + + if (trace_playback()) { + status = trace_get_packet (&trace_mr_output, &buflen, &inbuf); + if (status != ISC_R_SUCCESS) { + log_error ("trace_mr_recvfrom: no input found."); + errno = ECONNREFUSED; + return -1; + } + if (buflen < sizeof result) { + log_error ("trace_mr_recvfrom: data too short."); + errno = ECONNREFUSED; + dfree (inbuf, MDL); + return -1; + } + memcpy (&result, inbuf, sizeof result); + rv = ntohl (result); + dfree (inbuf, MDL); + } else +#endif + rv = send (fd, msg, len, flags); +#if defined (TRACING) + if (trace_record ()) { + trace_iov_t iov [3]; + result = htonl (rv); + sflags = htonl (flags); + iov [0].len = sizeof result; + iov [0].buf = (char *)&result; + iov [1].len = sizeof sflags; + iov [1].buf = (char *)&flags; + iov [2].len = len; + iov [2].buf = msg; + trace_write_packet_iov (trace_mr_output, 2, iov, MDL); + } +#endif + return rv; } -ssize_t trace_mr_read_playback (void *buf, size_t nbytes) +#if defined (TRACING) +ssize_t trace_mr_read_playback (struct sockaddr_in *from, + void *buf, size_t nbytes) { isc_result_t status; - unsigned buflen = 0; + unsigned buflen = 0, left; char *inbuf = (char *)0; + char *bufp; u_int32_t result; - ssize_t rv; status = trace_get_packet (&trace_mr_input, &buflen, &inbuf); if (status != ISC_R_SUCCESS) { @@ -139,56 +215,105 @@ ssize_t trace_mr_read_playback (void *buf, size_t nbytes) if (buflen < sizeof result) { log_error ("trace_mr_recvfrom: data too short."); errno = ECONNREFUSED; - dfree (buf, MDL); + dfree (inbuf, MDL); return -1; } - memcpy (&result, inbuf, sizeof result); + bufp = inbuf; + left = buflen; + memcpy (&result, bufp, sizeof result); result = ntohl (result); + bufp += sizeof result; + left -= sizeof result; if (result == 0) { - rv = buflen - sizeof result; - if (rv > nbytes) { + if (left < ((sizeof from -> sin_port) + + sizeof (from -> sin_addr))) { + log_error ("trace_mr_recvfrom: data too short."); + errno = ECONNREFUSED; + dfree (inbuf, MDL); + return -1; + } + if (from) + memcpy (&from -> sin_addr, bufp, + sizeof from -> sin_addr); + bufp += sizeof from -> sin_addr; + left -= sizeof from -> sin_addr; + if (from) + memcpy (&from -> sin_port, bufp, + sizeof from -> sin_port); + bufp += sizeof from -> sin_port; + left -= sizeof from -> sin_port; + if (from) { + from -> sin_family = AF_INET; +#if defined(HAVE_SA_LEN) + from -> sin_len = sizeof (struct sockaddr_in); +#endif + memset (from -> sin_zero, 0, sizeof from -> sin_zero); + } + if (left > nbytes) { log_error ("trace_mr_recvfrom: too much%s", " data."); errno = ECONNREFUSED; - dfree (buf, MDL); + dfree (inbuf, MDL); return -1; } - memcpy (buf, inbuf, (unsigned)rv); - return rv; + memcpy (buf, bufp, left); + dfree (inbuf, MDL); + return left; } errno = ECONNREFUSED; return -1; } -void trace_mr_read_record (void *buf, ssize_t rv) +void trace_mr_read_record (struct sockaddr_in *from, void *buf, ssize_t rv) { - trace_iov_t iov [2]; + trace_iov_t iov [4]; u_int32_t result; + int iolen = 0; + static char zero [4] = { 0, 0, 0, 0 }; - result = htonl (rv); - iov [0].buf = (char *)&result; - iov [0].len = sizeof result; + if (rv < 0) + result = htonl (errno); /* XXX */ + else + result = 0; + iov [iolen].buf = (char *)&result; + iov [iolen++].len = sizeof result; if (rv > 0) { - iov [1].buf = buf; - iov [1].len = rv; + if (from) { + iov [iolen].buf = (char *)&from -> sin_addr; + iov [iolen++].len = sizeof from -> sin_addr; + iov [iolen].buf = (char *)&from -> sin_port; + iov [iolen++].len = sizeof from -> sin_port; + } else { + iov [iolen].buf = zero; + iov [iolen++].len = sizeof from -> sin_addr; + iov [iolen].buf = zero; + iov [iolen++].len = sizeof from -> sin_port; + } + + iov [iolen].buf = buf; + iov [iolen++].len = rv; } - trace_write_packet_iov (trace_mr_input, - rv > 0 ? 2 : 1, iov, MDL); + trace_write_packet_iov (trace_mr_input, iolen, iov, MDL); } +#endif ssize_t trace_mr_recvfrom (int s, void *buf, size_t len, int flags, struct sockaddr *from, SOCKLEN_T *fromlen) { ssize_t rv; - if (trace_playback ()) { - trace_mr_read_playback (buf, len); - } else { +#if defined (TRACING) + if (trace_playback ()) + rv = trace_mr_read_playback ((struct sockaddr_in *)from, + buf, len); + else +#endif rv = recvfrom (s, buf, len, flags, from, fromlen); - if (trace_record ()) { - trace_mr_read_record (buf, rv); - } +#if defined (TRACING) + if (trace_record ()) { + trace_mr_read_record ((struct sockaddr_in *)from, buf, rv); } +#endif return rv; } @@ -196,68 +321,132 @@ ssize_t trace_mr_read (int d, void *buf, size_t nbytes) { ssize_t rv; - if (trace_playback ()) { - trace_mr_read_playback (buf, nbytes); - } else { +#if defined (TRACING) + if (trace_playback ()) + rv = trace_mr_read_playback ((struct sockaddr_in *)0, + buf, nbytes); + else +#endif rv = read (d, buf, nbytes); - if (trace_record ()) { - trace_mr_read_record (buf, rv); - } +#if defined (TRACING) + if (trace_record ()) { + trace_mr_read_record ((struct sockaddr_in *)0, buf, rv); } +#endif return rv; } int trace_mr_connect (int s, const struct sockaddr *name, SOCKLEN_T namelen) { +#if defined (TRACING) if (!trace_playback ()) +#endif return connect (s, name, namelen); - return 1000; +#if defined (TRACING) + return 0; +#endif } int trace_mr_socket (int domain, int type, int protocol) { +#if defined (TRACING) if (!trace_playback ()) +#endif return socket (domain, type, protocol); - return 1000; +#if defined (TRACING) + return 100; +#endif } int trace_mr_bind (int s, const struct sockaddr *name, SOCKLEN_T namelen) { +#if defined (TRACING) if (!trace_playback ()) +#endif return bind (s, name, namelen); +#if defined (TRACING) return 0; +#endif } int trace_mr_close (int s) { +#if defined (TRACING) if (!trace_playback ()) +#endif return close (s); +#if defined (TRACING) return 0; +#endif } time_t trace_mr_time (time_t *tp) { +#if defined (TRACING) if (trace_playback ()) { if (tp) *tp = cur_time; return cur_time; } +#endif return time (tp); } int trace_mr_select (int s, fd_set *r, fd_set *w, fd_set *x, struct timeval *t) { +#if defined (TRACING) + trace_type_t *ttp = (trace_type_t *)0; + if (trace_playback ()) { - time_t nct = trace_snoop_time (); + time_t nct = trace_snoop_time (&ttp); time_t secr = t -> tv_sec; t -> tv_sec = nct - cur_time; if (t -> tv_sec > secr) return 0; - return 1; + if (ttp == trace_mr_input) + return 1; + return 0; } +#endif return select (s, r, w, x, t); } +unsigned int trace_mr_res_randomid (unsigned int oldid) +{ + u_int32_t id; + int rid = oldid; +#if defined (TRACING) + unsigned buflen = 0; + char *buf = (char *)0; + isc_result_t status; + + if (trace_playback ()) { + int nscount; + status = trace_get_packet (&trace_mr_randomid, &buflen, &buf); + if (status != ISC_R_SUCCESS) { + log_error ("trace_mr_statp: no statp packet found."); + return oldid; + } + if (buflen != sizeof id) { + log_error ("trace_mr_randomid: bogus length: %d", + buflen); + return oldid; + } + memcpy (&id, buf, sizeof id); + dfree (buf, MDL); + buf = (char *)0; + rid = ntohl (id); + } + if (trace_record ()) { + id = htonl (rid); + trace_write_packet (trace_mr_randomid, + sizeof id, (char *)&id, MDL); + } +#endif + return rid; +} + +#if defined (TRACING) static void trace_mr_output_input (trace_type_t *ttype, unsigned length, char *buf) { @@ -287,5 +476,13 @@ static void trace_mr_statp_stop (trace_type_t *ttype) { } +static void trace_mr_randomid_input (trace_type_t *ttype, + unsigned length, char *buf) +{ + log_error ("unaccounted-for minires randomid input."); +} +static void trace_mr_randomid_stop (trace_type_t *ttype) +{ +} #endif