[Git][NTPsec/ntpsec][master] Checkpoint: replay mode before trying to implement full packet parsing.
Eric S. Raymond
gitlab at mg.gitlab.com
Tue Dec 15 23:50:21 UTC 2015
Eric S. Raymond pushed to branch master at NTPsec / ntpsec
Commits:
f0a57d5e by Eric S. Raymond at 2015-12-15T18:49:19Z
Checkpoint: replay mode before trying to implement full packet parsing.
- - - - -
3 changed files:
- ntpd/ntp_intercept.c
- ntpd/ntp_intercept.h
- ntpd/ntpd.c
Changes:
=====================================
ntpd/ntp_intercept.c
=====================================
--- a/ntpd/ntp_intercept.c
+++ b/ntpd/ntp_intercept.c
@@ -18,21 +18,19 @@ following kinds:
6. Calls to the host's random-number generator.
-7. Alarm events.
+7. Calls to adjtime/ntp_adjtime/adjtime to adjust the system clock.
-8. Calls to adjtime/ntp_adjtime/adjtime to adjust the system clock.
+8 Calls to ntp_set_tod to set the system clock.
-9 Calls to ntp_set_tod to set the system clock.
+9. Read of the system leapsecond file.
-10. Read of the system leapsecond file.
+10. Packets incoming from NTP peers and others.
-11. Packets incoming from NTP peers and others.
+11. Packets outgoing to NTP peers and others.
-12. Packets outgoing to NTP peers and others.
+12. Read of authkey file
-13. Read of authkey file
-
-14. Termination.
+13. Termination.
We must support two modes of operation. In "capture" mode, ntpd
operates normally, logging all events. In "replay" mode, ntpd accepts
@@ -331,16 +329,6 @@ long intercept_ntp_random(const char *legend)
return roll;
}
-void intercept_timer(void)
-{
- timer();
- if (mode == capture)
- printf("timer\n");
- else if (mode == replay)
- /* probably is not necessary to record this... */
- get_operation("timer");
-}
-
bool intercept_drift_read(const char *drift_file, double *drift)
{
if (mode == replay) {
@@ -625,7 +613,7 @@ intercept_leapsec_load_file(
}
static void packet_dump(char *buf, size_t buflen,
- sockaddr_u *dest, struct pkt *pkt, int len)
+ sockaddr_u *dest, struct pkt *pkt, size_t len)
{
size_t i;
/*
@@ -650,6 +638,23 @@ static void packet_dump(char *buf, size_t buflen,
}
}
+static void recvbuf_dump(char *buf, size_t buflen, struct recvbuf *rbufp)
+{
+ char pkt_dump[BUFSIZ];
+
+ packet_dump(pkt_dump, sizeof(pkt_dump),
+ &rbufp->recv_srcadr, &rbufp->recv_pkt, rbufp->recv_length);
+ /*
+ * Order is: cast flags, receipt time, source address, packet,
+ * MAC. Cast flags are only kept because they change the ntpq
+ * display, they have no implications for the protocol machine.
+ * We don't dump srcadr because only the parse clock uses that.
+ */
+ snprintf(buf, buflen,
+ "receive %0x %s %s\n",
+ rbufp->cast_flags, lfpdump(&rbufp->recv_time), pkt_dump);
+}
+
void intercept_sendpkt(const char *legend,
sockaddr_u *dest, struct interface *ep, int ttl,
struct pkt *pkt, int len)
@@ -677,31 +682,62 @@ void intercept_sendpkt(const char *legend,
void intercept_receive(struct recvbuf *rbufp)
{
- char pkt_dump[BUFSIZ], newpacket[BUFSIZ];
+ /* never called in replay mode */
+ if (mode == capture) {
+ char pkt_dump[BUFSIZ];
- packet_dump(pkt_dump, sizeof(pkt_dump),
- &rbufp->recv_srcadr,
- &rbufp->recv_pkt, rbufp->recv_length);
- /*
- * Order is: cast flags, receipt time, source address, packet,
- * MAC. Cast flags are only kept because they change the ntpq
- * display, they have no implications for the protocol machine.
- * We don't dump srcadr because only the parse clock uses that.
- */
- snprintf(newpacket, sizeof(newpacket),
- "receive %0x %s %s\n",
- rbufp->cast_flags, lfpdump(&rbufp->recv_time), pkt_dump);
+ recvbuf_dump(pkt_dump, sizeof(pkt_dump), rbufp);
+ fputs(pkt_dump, stdout);
+ }
- if (mode == replay) {
- if (strcmp(linebuf, newpacket) != 0) {
- fprintf(stderr, "ntpd: line %d, receive mismatch saw %s\n",
- lineno, newpacket);
+ receive(rbufp);
+}
+
+void intercept_replay(void)
+{
+ printf("# entering replay loop at line %d\n", lineno);
+ for (;;) {
+ get_operation(NULL);
+ if (strncmp(linebuf, "finish", 6) == 0)
+ break;
+ else if (strncmp(linebuf, "receive ", 8) == 0)
+ {
+ struct recvbuf rbuf;
+ char recvbuf[BUFSIZ], srcbuf[BUFSIZ], pktbuf[BUFSIZ], macbuf[BUFSIZ];
+
+ if (sscanf(linebuf, "receive %x %s %s %s %s",
+ &rbuf.cast_flags, recvbuf, srcbuf, pktbuf, macbuf) != 5)
+ {
+ fprintf(stderr, "ntpd: bad receive format at line %d\n", lineno);
+ exit(1);
+ }
+
+ atolfp(recvbuf, &rbuf.recv_time);
+ /* FIXME: parse source address */
+ /* FIXME: parse packet and MAC */
+
+ /*
+ * If the packet doesn't dump identically to how it came in,
+ * something is wrong with our packet parsing.
+ */
+ recvbuf_dump(recvbuf, sizeof(recvbuf), &rbuf);
+ if (strcmp(linebuf, recvbuf) != 0)
+ {
+ fprintf(stderr, "ntpd: round-trip failure at line %d\n", lineno);
+ fprintf(stderr, "old = %s\n", linebuf);
+ fprintf(stderr, "new = %s\n", recvbuf);
+ exit(1);
+ }
+
+ /* executing the receive call may pop other things off the queue */
+ receive(&rbuf);
+ }
+ else
+ {
+ fprintf(stderr, "ntpd: unexpected operation at line %d\n", lineno);
exit(1);
}
- } else if (mode == capture)
- fputs(newpacket, stdout);
-
- receive(rbufp);
+ }
}
void
=====================================
ntpd/ntp_intercept.h
=====================================
--- a/ntpd/ntp_intercept.h
+++ b/ntpd/ntp_intercept.h
@@ -20,7 +20,6 @@ void intercept_argparse(int *, char ***);
void intercept_getconfig(const char *);
void intercept_get_systime(const char *, l_fp *);
long intercept_ntp_random(const char *);
-void intercept_timer(void);
void intercept_sendpkt(const char *,
sockaddr_u *, struct interface *, int, struct pkt *, int);
void intercept_receive(struct recvbuf *);
@@ -34,6 +33,7 @@ int intercept_set_tod(struct timespec *tvs);
extern bool intercept_leapsec_load_file(const char * fname, struct stat * sb,
bool force, bool logall);
void intercept_getauthkeys(const char *);
+void intercept_replay(void);
void intercept_exit(const int);
/* end */
=====================================
ntpd/ntpd.c
=====================================
--- a/ntpd/ntpd.c
+++ b/ntpd/ntpd.c
@@ -935,7 +935,10 @@ ntpdmain(
msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
}
- mainloop();
+ if (intercept_get_mode() == replay)
+ intercept_replay();
+ else
+ mainloop();
return 1;
}
@@ -980,7 +983,7 @@ static void mainloop(void)
* Out here, signals are unblocked. Call timer routine
* to process expiry.
*/
- intercept_timer();
+ timer();
was_alarmed = false;
BLOCK_IO_AND_ALARM();
}
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/f0a57d5e59c8dda9f3a9ec789bd79ab7fde791cc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20151215/3f718347/attachment.html>
More information about the vc
mailing list