2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-29 05:17:57 +00:00

Add support for logging random ID and fix various bugs in minires tracing.

This commit is contained in:
Ted Lemon 2001-02-22 07:28:58 +00:00
parent e3fb86fbe0
commit dd952dd18a

View File

@ -44,19 +44,21 @@
#include "minires/minires.h" #include "minires/minires.h"
#include "arpa/nameser.h" #include "arpa/nameser.h"
#if defined (TRACING)
static void trace_mr_output_input (trace_type_t *, unsigned, char *); static void trace_mr_output_input (trace_type_t *, unsigned, char *);
static void trace_mr_output_stop (trace_type_t *); 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_input (trace_type_t *, unsigned, char *);
static void trace_mr_input_stop (trace_type_t *); 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_input (trace_type_t *, unsigned, char *);
static void trace_mr_statp_stop (trace_type_t *); 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_output;
trace_type_t *trace_mr_input; trace_type_t *trace_mr_input;
trace_type_t *trace_mr_statp; 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_send (int, void *, size_t, int);
ssize_t trace_mr_read_playback (void *, size_t); ssize_t trace_mr_read_playback (struct sockaddr_in *, void *, size_t);
void trace_mr_read_record (void *, ssize_t); void trace_mr_read_record (struct sockaddr_in *, void *, ssize_t);
ssize_t trace_mr_recvfrom (int s, void *, size_t, int, ssize_t trace_mr_recvfrom (int s, void *, size_t, int,
struct sockaddr *, SOCKLEN_T *); struct sockaddr *, SOCKLEN_T *);
ssize_t trace_mr_read (int, void *, size_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); int trace_mr_close (int);
time_t trace_mr_time (time_t *); time_t trace_mr_time (time_t *);
int trace_mr_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); 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; extern time_t cur_time;
#if defined (TRACING)
void trace_mr_init () void trace_mr_init ()
{ {
trace_mr_output = trace_type_register ("mr-output", (void *)0, 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 = trace_type_register ("mr-statp", (void *)0,
trace_mr_statp_input, trace_mr_statp_input,
trace_mr_statp_stop, MDL); 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) void trace_mr_statp_setup (res_state statp)
@ -87,6 +94,8 @@ void trace_mr_statp_setup (res_state statp)
unsigned buflen = 0; unsigned buflen = 0;
char *buf = (char *)0; char *buf = (char *)0;
isc_result_t status; isc_result_t status;
u_int32_t id;
int i;
if (trace_playback ()) { if (trace_playback ()) {
int nscount; int nscount;
@ -95,40 +104,107 @@ void trace_mr_statp_setup (res_state statp)
log_error ("trace_mr_statp: no statp packet found."); log_error ("trace_mr_statp: no statp packet found.");
return; return;
} }
nscount = buflen / sizeof (struct sockaddr_in); nscount = buflen / sizeof (struct in_addr);
if (nscount * (sizeof (struct sockaddr_in)) != buflen) { if (nscount * (sizeof (struct in_addr)) != buflen ||
nscount < 1) {
log_error ("trace_mr_statp: bogus length: %d", log_error ("trace_mr_statp: bogus length: %d",
buflen); buflen);
return; return;
} }
if (nscount > MAXNS) if (nscount > MAXNS)
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); dfree (buf, MDL);
buf = (char *)0; buf = (char *)0;
} }
if (trace_record ()) { if (trace_record ()) {
trace_write_packet (trace_mr_statp, trace_iov_t *iov;
statp -> nscount * sizeof (struct sockaddr_in), iov = dmalloc ((statp -> nscount *
(char *)statp -> nsaddr_list, MDL); 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) ssize_t trace_mr_send (int fd, void *msg, size_t len, int flags)
{ {
if (trace_record ()) ssize_t rv;
trace_write_packet (trace_mr_output, len, msg, MDL); #if defined (TRACING)
return send (fd, msg, len, flags);
}
ssize_t trace_mr_read_playback (void *buf, size_t nbytes)
{
isc_result_t status; isc_result_t status;
unsigned buflen = 0; unsigned buflen = 0;
char *inbuf = (char *)0; char *inbuf = (char *)0;
u_int32_t result; u_int32_t result;
ssize_t rv; 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;
}
#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, left;
char *inbuf = (char *)0;
char *bufp;
u_int32_t result;
status = trace_get_packet (&trace_mr_input, &buflen, &inbuf); status = trace_get_packet (&trace_mr_input, &buflen, &inbuf);
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
@ -139,56 +215,105 @@ ssize_t trace_mr_read_playback (void *buf, size_t nbytes)
if (buflen < sizeof result) { if (buflen < sizeof result) {
log_error ("trace_mr_recvfrom: data too short."); log_error ("trace_mr_recvfrom: data too short.");
errno = ECONNREFUSED; errno = ECONNREFUSED;
dfree (buf, MDL); dfree (inbuf, MDL);
return -1; return -1;
} }
memcpy (&result, inbuf, sizeof result); bufp = inbuf;
left = buflen;
memcpy (&result, bufp, sizeof result);
result = ntohl (result); result = ntohl (result);
bufp += sizeof result;
left -= sizeof result;
if (result == 0) { if (result == 0) {
rv = buflen - sizeof result; if (left < ((sizeof from -> sin_port) +
if (rv > nbytes) { 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", log_error ("trace_mr_recvfrom: too much%s",
" data."); " data.");
errno = ECONNREFUSED; errno = ECONNREFUSED;
dfree (buf, MDL); dfree (inbuf, MDL);
return -1; return -1;
} }
memcpy (buf, inbuf, (unsigned)rv); memcpy (buf, bufp, left);
return rv; dfree (inbuf, MDL);
return left;
} }
errno = ECONNREFUSED; errno = ECONNREFUSED;
return -1; 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; u_int32_t result;
int iolen = 0;
static char zero [4] = { 0, 0, 0, 0 };
result = htonl (rv); if (rv < 0)
iov [0].buf = (char *)&result; result = htonl (errno); /* XXX */
iov [0].len = sizeof result; else
result = 0;
iov [iolen].buf = (char *)&result;
iov [iolen++].len = sizeof result;
if (rv > 0) { if (rv > 0) {
iov [1].buf = buf; if (from) {
iov [1].len = rv; 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;
} }
trace_write_packet_iov (trace_mr_input,
rv > 0 ? 2 : 1, iov, MDL); iov [iolen].buf = buf;
iov [iolen++].len = rv;
}
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, ssize_t trace_mr_recvfrom (int s, void *buf, size_t len, int flags,
struct sockaddr *from, SOCKLEN_T *fromlen) struct sockaddr *from, SOCKLEN_T *fromlen)
{ {
ssize_t rv; ssize_t rv;
if (trace_playback ()) { #if defined (TRACING)
trace_mr_read_playback (buf, len); if (trace_playback ())
} else { rv = trace_mr_read_playback ((struct sockaddr_in *)from,
buf, len);
else
#endif
rv = recvfrom (s, buf, len, flags, from, fromlen); rv = recvfrom (s, buf, len, flags, from, fromlen);
#if defined (TRACING)
if (trace_record ()) { if (trace_record ()) {
trace_mr_read_record (buf, rv); trace_mr_read_record ((struct sockaddr_in *)from, buf, rv);
}
} }
#endif
return rv; return rv;
} }
@ -196,68 +321,132 @@ ssize_t trace_mr_read (int d, void *buf, size_t nbytes)
{ {
ssize_t rv; ssize_t rv;
if (trace_playback ()) { #if defined (TRACING)
trace_mr_read_playback (buf, nbytes); if (trace_playback ())
} else { rv = trace_mr_read_playback ((struct sockaddr_in *)0,
buf, nbytes);
else
#endif
rv = read (d, buf, nbytes); rv = read (d, buf, nbytes);
#if defined (TRACING)
if (trace_record ()) { if (trace_record ()) {
trace_mr_read_record (buf, rv); trace_mr_read_record ((struct sockaddr_in *)0, buf, rv);
}
} }
#endif
return rv; return rv;
} }
int trace_mr_connect (int s, const struct sockaddr *name, SOCKLEN_T namelen) int trace_mr_connect (int s, const struct sockaddr *name, SOCKLEN_T namelen)
{ {
#if defined (TRACING)
if (!trace_playback ()) if (!trace_playback ())
#endif
return connect (s, name, namelen); return connect (s, name, namelen);
return 1000; #if defined (TRACING)
return 0;
#endif
} }
int trace_mr_socket (int domain, int type, int protocol) int trace_mr_socket (int domain, int type, int protocol)
{ {
#if defined (TRACING)
if (!trace_playback ()) if (!trace_playback ())
#endif
return socket (domain, type, protocol); 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) int trace_mr_bind (int s, const struct sockaddr *name, SOCKLEN_T namelen)
{ {
#if defined (TRACING)
if (!trace_playback ()) if (!trace_playback ())
#endif
return bind (s, name, namelen); return bind (s, name, namelen);
#if defined (TRACING)
return 0; return 0;
#endif
} }
int trace_mr_close (int s) int trace_mr_close (int s)
{ {
#if defined (TRACING)
if (!trace_playback ()) if (!trace_playback ())
#endif
return close (s); return close (s);
#if defined (TRACING)
return 0; return 0;
#endif
} }
time_t trace_mr_time (time_t *tp) time_t trace_mr_time (time_t *tp)
{ {
#if defined (TRACING)
if (trace_playback ()) { if (trace_playback ()) {
if (tp) if (tp)
*tp = cur_time; *tp = cur_time;
return cur_time; return cur_time;
} }
#endif
return time (tp); return time (tp);
} }
int trace_mr_select (int s, fd_set *r, fd_set *w, fd_set *x, struct timeval *t) 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 ()) { if (trace_playback ()) {
time_t nct = trace_snoop_time (); time_t nct = trace_snoop_time (&ttp);
time_t secr = t -> tv_sec; time_t secr = t -> tv_sec;
t -> tv_sec = nct - cur_time; t -> tv_sec = nct - cur_time;
if (t -> tv_sec > secr) if (t -> tv_sec > secr)
return 0; return 0;
if (ttp == trace_mr_input)
return 1; return 1;
return 0;
} }
#endif
return select (s, r, w, x, t); 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, static void trace_mr_output_input (trace_type_t *ttype,
unsigned length, char *buf) 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 #endif