]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Add support for logging random ID and fix various bugs in minires tracing.
authorTed Lemon <source@isc.org>
Thu, 22 Feb 2001 07:28:58 +0000 (07:28 +0000)
committerTed Lemon <source@isc.org>
Thu, 22 Feb 2001 07:28:58 +0000 (07:28 +0000)
omapip/mrtrace.c

index ce19d3bcce25e54b60c1f7dbc95282909c6d8b87..0fb67a692c995abc3830b6eb1c0b240dbc045f4e 100644 (file)
 #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