summaryrefslogtreecommitdiffstats
path: root/usr.sbin/xntpd/patches/patch.10
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/xntpd/patches/patch.10')
-rw-r--r--usr.sbin/xntpd/patches/patch.101925
1 files changed, 1925 insertions, 0 deletions
diff --git a/usr.sbin/xntpd/patches/patch.10 b/usr.sbin/xntpd/patches/patch.10
new file mode 100644
index 0000000..1771b5f
--- /dev/null
+++ b/usr.sbin/xntpd/patches/patch.10
@@ -0,0 +1,1925 @@
+diff -c COPYRIGHT:1.1.1.16 COPYRIGHT:1.21
+*** COPYRIGHT:1.1.1.16 Wed Feb 2 18:09:17 1994
+--- COPYRIGHT Wed Feb 2 18:09:18 1994
+***************
+*** 1,6 ****
+ /******************************************************************************
+ * *
+! * Copyright (c) David L. Mills 1992, 1993, 1994 *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, provided *
+--- 1,6 ----
+ /******************************************************************************
+ * *
+! * Copyright (c) David L. Mills 1992, 1993, 1994 *
+ * *
+ * Permission to use, copy, modify, and distribute this software and its *
+ * documentation for any purpose and without fee is hereby granted, provided *
+***************
+*** 55,58 ****
+ * Torsten Duwe <duwe@immd4.informatik.uni-erlangen.de> (Linux Port)
+ * Paul A Vixie <vixie@vix.com> (TrueTime GPS driver)
+ * Jim Jagielski <jim@jagubox.gsfc.nasa.gov> (A/UX port)
+! */
+--- 55,58 ----
+ * Torsten Duwe <duwe@immd4.informatik.uni-erlangen.de> (Linux Port)
+ * Paul A Vixie <vixie@vix.com> (TrueTime GPS driver)
+ * Jim Jagielski <jim@jagubox.gsfc.nasa.gov> (A/UX port)
+! */
+diff -c doc/xntpd.8:1.1.1.12 doc/xntpd.8:3.24
+*** doc/xntpd.8:1.1.1.12 Wed Feb 2 18:10:44 1994
+--- doc/xntpd.8 Wed Feb 2 18:10:45 1994
+***************
+*** 446,451 ****
+--- 446,467 ----
+ .Ip notrust 10
+ Treat these hosts normally in other respects, but never use them as
+ synchronization sources.
++ .Ip limited 10
++ These hosts are subject to limitation of number of clients from the
++ same net. Net in this context refers to the IP notion of net (class A,
++ class B, class C, etc.). Only the first \*(L"client_limit\*(R" hosts
++ that have shown up at the server and that have been active during the
++ last \*(L"client_limit_period\*(R" seconds are accepted. Requests from
++ other clients from the same net are rejected. Only time request
++ packets are taken into account. \*(L"Private\*(R", \*(L"control\*(R",
++ and \*(L"broadcast\*(R" packets are not subject to client limitation
++ and therefore are not contributing to client count. History of clients
++ is kept using the monitoring capability of
++ .IR xntpd .
++ Thus, monitoring is active as long as there is a restriction entry
++ with the \*(L"limited\*(R" flag. The default value for
++ \*(L"client_limit\*(R" is 3. The default value for
++ \*(L"client_limit_period\*(R" is 3600 seconds.
+ .Ip ntpport 10
+ This is actually a match algorithm modifier, rather than a restriction
+ flag. Its presence causes the restriction entry to be matched only if
+***************
+*** 469,474 ****
+--- 485,505 ----
+ considered an alternative to the standard NTP authentication facility. Source
+ address based restrictions are easily circumvented by a determined cracker.
+ .PP
++ .B clientlimit
++ .I limit
++ .PP
++ Sets \*(L"client_limit\*(R" to \*(L"limit\*(R", allows configuration
++ of client limitation policy. This variable defines the number of
++ clients from the same network that are allowed to use the server.
++ .PP
++ .B clientperiod
++ .I period
++ .PP
++ Sets \*(L"client_limit_period\*(R", allows configuration of client
++ limitation policy. This variable specifies the number
++ of seconds after which a client is considered inactive and thus no
++ longer is counted for client limit restriction.
++ .PP
+ .B trap
+ .I host_address
+ [
+diff -c doc/xntpdc.8:1.1.1.2 doc/xntpdc.8:3.4
+*** doc/xntpdc.8:1.1.1.2 Wed Feb 2 18:10:46 1994
+--- doc/xntpdc.8 Wed Feb 2 18:10:47 1994
+***************
+*** 539,544 ****
+--- 539,555 ----
+ Ignore all NTP mode 7 packets which attempt to modify the state of the
+ server (i.e. run time reconfiguration). Queries which return information
+ are permitted.
++ .Ip notrap 10
++ Decline to provide mode 6 control message trap service to matching
++ hosts. The trap service is a subsystem of the mode 6 control message
++ protocol which is intended for use by remote event logging programs.
++ .Ip lowpriotrap 10
++ Declare traps set by matching hosts to be low priority. The number
++ of traps a server can maintain is limited (the current limit is 3).
++ Traps are usually assigned on a first come, first served basis, with
++ later trap requestors being denied service. This flag modifies the
++ assignment algorithm by allowing low priority traps to be overridden
++ by later requests for normal priority traps.
+ .Ip noserve 10
+ Ignore NTP packets whose mode is other than 7. In effect, time service is
+ denied, though queries may still be permitted.
+***************
+*** 549,554 ****
+--- 560,582 ----
+ .Ip notrust 10
+ Treat these hosts normally in other respects, but never use them as
+ synchronization sources.
++ .Ip limited 10
++ These hosts are subject to limitation of number of clients from the
++ same net. Net in this context refers to the IP notion of net (class A,
++ class B, class C, etc.). Only the first \*(L"client_limit\*(R" hosts
++ that have shown up at the server and that have been active during the
++ last \*(L"client_limit_period\*(R" seconds are accepted. Requests from
++ other clients from the same net are rejected. Only time request
++ packets are taken into account. \*(L"Private\*(R", \*(L"control\*(R",
++ and \*(L"broadcast\*(R" packets are not subject to client limitation
++ and therefore are not contributing to client count. History of clients
++ is kept using the monitoring capability of
++ .IR xntpd.
++ Thus, monitoring is active as long as there is a restriction entry
++ with the \*(L"limited\*(R" flag. The default value for
++ \*(L"client_limit\*(R" is 3. The default value for
++ \*(L"client_limit_period\*(R" is 3600 seconds. Currently both
++ variables are not runtime configurable.
+ .Ip ntpport 10
+ This is actually a match algorithm modifier, rather than a restriction
+ flag. Its presence causes the restriction entry to be matched only if
+diff -c hints/linux:1.1.1.1 hints/linux:1.2
+*** hints/linux:1.1.1.1 Wed Feb 2 18:10:58 1994
+--- hints/linux Wed Feb 2 18:10:59 1994
+***************
+*** 1,29 ****
+
+! Requirements: kernel 0.99.14 or newer, libc 4.5 or newer
+ ------------
+
+! With this configuration, xntp should build an run right out of the
+! box (see generic hints for how-to), with one big limitation: tickadj doesn't
+! work yet. This is especially painful since PCs are usually equipped with
+! untuned, badly-drifting quartzes, values up to 200 ppm being no exception.
+! Because the loop filter algorithms are limited to compensating no more than
+! 100 ppm, currently only one workaround is possible:
+! Compile your own kernel and adjust linux/include/linux/timex.h,
+! line 67 (in pl14):
+!
+! #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+!
+! Since this is surely not true for your hardware, adjust the hundreds
+! to match your quartz. Adding 100 compensates for a drift of -83.8 ppm
+! (1/CLOCK_TICK_RATE). The number gets rounded to the nearest 100 so don't
+! bother to tune any finer.
+!
+! Fixing tickadj is already in my work queue, so the previous comment should be
+! obsolete RSN. If you really need to run xntp on any earlier versions of the
+! kernel or libc, or have any other question not covered in the READMEs / hint
+! files (sorry, necessary comment in the Linux community ;-) feel free to ask
+! me (duwe@informatik.uni-erlangen.de)
+!
+! xntp3.3b of 1993/12/06 : remember to change #define ntp_adjtime adjtimex to
+! __adjtimex in the Linux section (line 316). This is hopefully done if you
+! (don't :-) see this paragraph in the xntp3.x distribution.
+--- 1,9 ----
+
+! Requirements: kernel 0.99.14y or newer, libc 4.5.8 or newer
+ ------------
+
+! With this configuration, xntp should build an run right out of the box
+! (see generic hints for how-to). If you really need to run xntp on any earlier
+! versions of the kernel or libc, or have any other question not covered in the
+! READMEs / hint files (sorry, necessary comment in the Linux community ;-) feel
+! free to ask me (duwe@informatik.uni-erlangen.de)
+diff -c include/ntp.h:1.1.1.17 include/ntp.h:3.23
+*** include/ntp.h:1.1.1.17 Wed Feb 2 18:11:18 1994
+--- include/ntp.h Wed Feb 2 18:11:18 1994
+***************
+*** 612,617 ****
+--- 612,620 ----
+ struct mon_data *hash_prev; /* previous structure in hash list */
+ struct mon_data *mru_next; /* next structure in MRU list */
+ struct mon_data *mru_prev; /* previous structure in MRU list */
++ struct mon_data *fifo_next; /* next structure in FIFO list */
++ struct mon_data *fifo_prev; /* previous structure in FIFO list */
++ U_LONG lastdrop; /* last time dropped due to RES_LIMIT*/
+ U_LONG lasttime; /* last time data updated */
+ U_LONG firsttime; /* time structure initialized */
+ U_LONG count; /* count we have seen */
+***************
+*** 621,627 ****
+ u_char version; /* version of incoming packet */
+ };
+
+!
+ /*
+ * Structure used for restrictlist entries
+ */
+--- 624,635 ----
+ u_char version; /* version of incoming packet */
+ };
+
+! /*
+! * Values used with mon_enabled to indicate reason for enabling monitoring
+! */
+! #define MON_OFF 0x00 /* no monitoring */
+! #define MON_ON 0x01 /* monitoring explicitly enabled */
+! #define MON_RES 0x02 /* implicit monitoring for RES_LIMITED */
+ /*
+ * Structure used for restrictlist entries
+ */
+***************
+*** 645,654 ****
+ #define RES_NOPEER 0x20 /* don't allocate memory resources */
+ #define RES_NOTRAP 0x40 /* don't allow him to set traps */
+ #define RES_LPTRAP 0x80 /* traps set by him are low priority */
+
+ #define RES_ALLFLAGS \
+ (RES_IGNORE|RES_DONTSERVE|RES_DONTTRUST|RES_NOQUERY\
+! |RES_NOMODIFY|RES_NOPEER|RES_NOTRAP|RES_LPTRAP)
+
+ /*
+ * Match flags
+--- 653,663 ----
+ #define RES_NOPEER 0x20 /* don't allocate memory resources */
+ #define RES_NOTRAP 0x40 /* don't allow him to set traps */
+ #define RES_LPTRAP 0x80 /* traps set by him are low priority */
++ #define RES_LIMITED 0x100 /* limit per net number of clients */
+
+ #define RES_ALLFLAGS \
+ (RES_IGNORE|RES_DONTSERVE|RES_DONTTRUST|RES_NOQUERY\
+! |RES_NOMODIFY|RES_NOPEER|RES_NOTRAP|RES_LPTRAP|RES_LIMITED)
+
+ /*
+ * Match flags
+diff -c include/ntp_request.h:1.1.1.7 include/ntp_request.h:3.7
+*** include/ntp_request.h:1.1.1.7 Wed Feb 2 18:11:27 1994
+--- include/ntp_request.h Wed Feb 2 18:11:28 1994
+***************
+*** 429,438 ****
+--- 429,456 ----
+ U_LONG processed; /* packets processed */
+ U_LONG badauth; /* packets dropped because of authorization */
+ U_LONG wanderhold;
++ U_LONG limitrejected; /* rejected because of client limitation */
+ };
+
+
+ /*
++ * System stats - old version
++ */
++ struct old_info_sys_stats {
++ U_LONG timeup; /* time we have been up and running */
++ U_LONG timereset; /* time since these were last cleared */
++ U_LONG badstratum; /* packets claiming an invalid stratum */
++ U_LONG oldversionpkt; /* old version packets received */
++ U_LONG newversionpkt; /* new version packets received */
++ U_LONG unknownversion; /* don't know version packets */
++ U_LONG badlength; /* packets with bad length */
++ U_LONG processed; /* packets processed */
++ U_LONG badauth; /* packets dropped because of authorization */
++ U_LONG wanderhold;
++ };
++
++
++ /*
+ * Peer memory statistics. Collected in the peer module.
+ */
+ struct info_mem_stats {
+***************
+*** 546,551 ****
+--- 564,570 ----
+ struct info_monitor {
+ U_LONG lasttime; /* last packet from this host */
+ U_LONG firsttime; /* first time we received a packet */
++ U_LONG lastdrop; /* last time we rejected a packet due to client limitation policy */
+ U_LONG count; /* count of packets received */
+ U_LONG addr; /* host address */
+ u_short port; /* port number of last reception */
+***************
+*** 553,558 ****
+--- 572,589 ----
+ u_char version; /* version number of last packet */
+ };
+
++ /*
++ * Structure used for returning monitor data (old format
++ */
++ struct old_info_monitor {
++ U_LONG lasttime; /* last packet from this host */
++ U_LONG firsttime; /* first time we received a packet */
++ U_LONG count; /* count of packets received */
++ U_LONG addr; /* host address */
++ u_short port; /* port number of last reception */
++ u_char mode; /* mode of last packet */
++ u_char version; /* version number of last packet */
++ };
+
+ /*
+ * Structure used for passing indication of flags to clear
+diff -c include/ntp_stdlib.h:1.1.1.7 include/ntp_stdlib.h:1.2
+*** include/ntp_stdlib.h:1.1.1.7 Wed Feb 2 18:11:31 1994
+--- include/ntp_stdlib.h Wed Feb 2 18:11:31 1994
+***************
+*** 79,84 ****
+--- 79,85 ----
+ extern char * mfptoa P((U_LONG, U_LONG, int));
+ extern char * mfptoms P((U_LONG, U_LONG, int));
+ extern char * modetoa P((int));
++ extern U_LONG netof P((U_LONG));
+ extern char * numtoa P((U_LONG));
+ extern char * numtohost P((U_LONG));
+ extern int octtoint P((const char *, U_LONG *));
+diff -c include/ntpd.h:1.1.1.7 include/ntpd.h:1.6
+*** include/ntpd.h:1.1.1.7 Wed Feb 2 18:11:38 1994
+--- include/ntpd.h Wed Feb 2 18:11:38 1994
+***************
+*** 93,100 ****
+
+ /* ntp_monitor.c */
+ extern void init_mon P((void));
+! extern void mon_start P((void));
+! extern void mon_stop P((void));
+ extern void monitor P((struct recvbuf *));
+
+ /* ntp_peer.c */
+--- 93,100 ----
+
+ /* ntp_monitor.c */
+ extern void init_mon P((void));
+! extern void mon_start P((int));
+! extern void mon_stop P((int));
+ extern void monitor P((struct recvbuf *));
+
+ /* ntp_peer.c */
+diff -c lib/Makefile.tmpl:1.1.1.14 lib/Makefile.tmpl:3.25
+*** lib/Makefile.tmpl:1.1.1.14 Wed Feb 2 18:12:06 1994
+--- lib/Makefile.tmpl Wed Feb 2 18:12:07 1994
+***************
+*** 31,37 ****
+ uglydate.c uinttoa.c utvtoa.c machines.c clocktypes.c \
+ md5.c a_md5encrypt.c a_md5decrypt.c \
+ a_md512crypt.c decodenetnum.c systime.c msyslog.c syssignal.c \
+! findconfig.c
+
+ OBJS= atoint.o atolfp.o atouint.o auth12crypt.o authdecrypt.o authdes.o \
+ authencrypt.o authkeys.o authparity.o authreadkeys.o authusekey.o \
+--- 31,37 ----
+ uglydate.c uinttoa.c utvtoa.c machines.c clocktypes.c \
+ md5.c a_md5encrypt.c a_md5decrypt.c \
+ a_md512crypt.c decodenetnum.c systime.c msyslog.c syssignal.c \
+! findconfig.c netof.c
+
+ OBJS= atoint.o atolfp.o atouint.o auth12crypt.o authdecrypt.o authdes.o \
+ authencrypt.o authkeys.o authparity.o authreadkeys.o authusekey.o \
+***************
+*** 44,50 ****
+ uglydate.o uinttoa.o utvtoa.o machines.o clocktypes.o \
+ md5.o a_md5encrypt.o a_md5decrypt.o \
+ a_md512crypt.o decodenetnum.o systime.o msyslog.o syssignal.o \
+! findconfig.o
+
+ $(LIBNAME).a: $(OBJS)
+ ar rv $@ $?
+--- 44,50 ----
+ uglydate.o uinttoa.o utvtoa.o machines.o clocktypes.o \
+ md5.o a_md5encrypt.o a_md5decrypt.o \
+ a_md512crypt.o decodenetnum.o systime.o msyslog.o syssignal.o \
+! findconfig.o netof.o
+
+ $(LIBNAME).a: $(OBJS)
+ ar rv $@ $?
+diff -c /dev/null lib/netof.c:3.1
+*** /dev/null Wed Feb 2 18:13:07 1994
+--- lib/netof.c Wed Feb 2 18:13:07 1994
+***************
+*** 0 ****
+--- 1,25 ----
++ /*
++ * netof - return the net address part of an ip address
++ * (zero out host part)
++ */
++ #include <stdio.h>
++
++ #include "ntp_fp.h"
++ #include "ntp_stdlib.h"
++
++ U_LONG
++ netof(num)
++ U_LONG num;
++ {
++ register U_LONG netnum;
++
++ netnum = num;
++
++ if(IN_CLASSC(netnum))
++ netnum &= IN_CLASSC_NET;
++ else if (IN_CLASSB(netnum))
++ netnum &= IN_CLASSB_NET;
++ else /* treat als other like class A */
++ netnum &= IN_CLASSA_NET;
++ return netnum;
++ }
+diff -c /dev/null parse/README.new_clocks:3.2
+*** /dev/null Wed Feb 2 18:14:30 1994
+--- parse/README.new_clocks Wed Feb 2 18:14:30 1994
+***************
+*** 0 ****
+--- 1,203 ----
++ Here is an attempt to scetch out what you need to do in order to
++ add another clock to the parse driver:
++
++ Prerequsites:
++ - Does the system you want the clock connect to have
++ termio.h or termios.h ? (You need that for the parse driver)
++
++ What to do:
++
++ Make a conversion module (parse/clk_*.c)
++
++ - What ist the time code format ?
++ - find year, month, day, hour, minute, second, status (synchronised or
++ not), possibly time zone information (you need to give the offset to UTC)
++ You will have to convert the data from a string into a struct clocktime:
++ struct clocktime /* clock time broken up from time code */
++ {
++ LONG day;
++ LONG month;
++ LONG year;
++ LONG hour;
++ LONG minute;
++ LONG second;
++ LONG usecond;
++ LONG utcoffset; /* in seconds */
++ LONG flags; /* current clock status */
++ };
++
++ Conversion is usually simple and straight forward. For the flags following
++ values can be OR'ed together:
++
++ PARSEB_ANNOUNCE switch time zone warning (informational only)
++ PARSEB_POWERUP no synchronisation - clock confused (must set then)
++ PARSEB_NOSYNC timecode currently not confirmed (must set then)
++ usually on reception error when the is still a
++ chance the the generated time is still ok.
++
++ PARSEB_DST DST in effect (informational only)
++ PARSEB_UTC timecode contains UTC time (informational only)
++ PARSEB_LEAP LEAP warning (prior to leap happening - must set when imminent)
++ PARSEB_ALTERNATE backup transmitter (informational only)
++ PARSEB_POSITION geographic position available (informational only)
++ PARSEB_LEAPSECOND actual leap second (this time code is the leap
++ second - informational only)
++
++ These are feature flags denoting items that are supported by the clock:
++ PARSEB_S_LEAP supports LEAP - might set PARSEB_LEAP
++ PARSEB_S_ANTENNA supports ANTENNA - might set PARSEB_ALTERNATE
++ PARSEB_S_PPS supports PPS time stamping
++ PARSEB_S_POSITION supports position information (GPS)
++
++ Conversion is done in the cvt_* routine in parse/clk_*.c files. look in
++ them for examples. The basic structure is:
++
++ struct clockformat <yourclock>_format = {
++ lots of field for you to fill out (see below)
++ };
++
++ static cvt_<yourclock>()
++ ...
++ {
++ if (<I do not recognize my time code>) {
++ return CVT_NONE;
++ } else {
++ if (<conversion into clockformat is ok>) {
++ <set all necessary flags>;
++ return CVT_OK;
++ } else {
++ return CVT_FAIL|CVT_BADFMT;
++ }
++ }
++
++ The struct clockformat is the interface to the rest of the parse
++ driver - it holds all information necessary for finding the
++ clock message and doing the appropriate time stamping.
++
++ struct clockformat
++ {
++ unsigned LONG (*convert)();
++ /* conversion routine - your routine - cvt_<yourclock> */
++ void (*syncevt)();
++ /* routine for handling RS232 sync events (time stamps) - usually sync_simple */
++ unsigned LONG (*syncpps)();
++ /* PPS input routine - usually pps_simple */
++ unsigned LONG (*synth)();
++ /* time code synthesizer - usually not used - (LONG (*)())0 */
++ void *data;
++ /* local parameters - any parameters/data/configuration info your conversion
++ routine might need */
++ char *name;
++ /* clock format name - Name of the time code */
++ unsigned short length;
++ /* maximum length of data packet for your clock format */
++ unsigned LONG flags;
++ /* information for the parser what to look for */
++ struct timeval timeout;
++ /* buffer restart after timeout (us) - some clocks preceede new data by
++ a longer period of silence - unsually not used */
++ unsigned char startsym;
++ /* start symbol - character at the beginning of the clock data */
++ unsigned char endsym;
++ /* end symbol - character at the end of the clock data */
++ unsigned char syncsym;
++ /* sync symbol - character that is "on time" - where the time stamp should be taken */
++ };
++
++ The flags:
++ F_START use startsym to find the beginning of the clock data
++ F_END use endsym to find the end of the clock data
++ SYNC_TIMEOUT packet restart after timeout in timeout field
++ SYNC_START packet start is sync event (time stamp at paket start)
++ SYNC_END packet end is sync event (time stamp at paket end)
++ SYNC_CHAR special character (syncsym) is sync event
++ SYNC_ONE PPS synchronize on 'ONE' transition
++ SYNC_ZERO PPS synchronize on 'ZERO' transition
++ SYNC_SYNTHESIZE generate intermediate time stamps (very special case!)
++ CVT_FIXEDONLY convert only in fixed configuration - (data format not
++ suitable for auto-configuration)
++
++
++ The above should have given you some hints on how to build a clk_*.c
++ file with the time code conversion. See the examples and pick a clock
++ closest to yours and tweak the code to match your clock.
++
++ In order to make your clk_*.c file usable a referenc to the clockformat
++ structure must be put into parse_conf.c.
++
++
++
++ TTY setup and initialisation/configuration will be done in
++ xntpd/refclock_parse.c
++
++ - Find out the exact tty settings for your clock (baud rate, parity,
++ stop bits, character size, ...) and note them in terms of
++ termio*.h c_cflag macros.
++
++ - in xntpd/refclock_parse.c fill out a new the struct clockinfo element
++ (allocates a new "IP" address - see comments)
++ (see all the other clocks for example)
++ struct clockinfo
++ {
++ U_LONG cl_flags; /* operation flags (io modes) */
++ PARSE_F_NOPOLLONLY always do async io - read whenever input comes
++ PARSE_F_POLLONLY never do async io - only read when expecting data
++ PARSE_F_PPSPPS use loopfilter PPS code (CIOGETEV)
++ PARSE_F_PPSONSECOND PPS pulses are on second
++ usually flags stay 0 as they are used only for special setups
++
++ void (*cl_poll)(); /* active poll routine */
++ The routine to call when the clock needs data sent to it in order to
++ get a time code from the clock (e.g. Trimble clock)
++ int (*cl_init)(); /* active poll init routine */
++ The routine to call for very special initializations.
++ void (*cl_end)(); /* active poll end routine */
++ The routine to call to undo any special initialisation (free memory/timers)
++ void *cl_data; /* local data area for "poll" mechanism */
++ local data for polling routines
++ u_fp cl_rootdelay; /* rootdelay */
++ NTP rottdelay estimate (usually 0)
++ U_LONG cl_basedelay; /* current offset - unsigned l_fp fractional par
++ time (fraction) by which the RS232 time code is delayed from the actual time.
++ t */
++ U_LONG cl_ppsdelay; /* current PPS offset - unsigned l_fp fractional
++ time (fraction) by which the PPS time stamp is delayed (usually 0)
++ part */
++ char *cl_id; /* ID code (usually "DCF") */
++ Refclock id - (max 4 chars)
++ char *cl_description; /* device name */
++ Name of this device.
++ char *cl_format; /* fixed format */
++ If the data format cann not ne detected automatically this is the name
++ as in clk_*.c clockformat.
++ u_char cl_type; /* clock type (ntp control) */
++ Type if clock as in clock status word (ntp control messages) - usually 0
++ U_LONG cl_maxunsync; /* time to trust oscillator after loosing synch
++ */
++ seconds a clock can be trusted after loosing synchronisation.
++
++ U_LONG cl_cflag; /* terminal io flags */
++ U_LONG cl_iflag; /* terminal io flags */
++ U_LONG cl_oflag; /* terminal io flags */
++ U_LONG cl_lflag; /* terminal io flags */
++ termio*.h tty modes.
++ } clockinfo[] = {
++ ...,<other clocks>,...
++ { < your parameters> },
++ };
++
++
++ Well, this is very sketchy, i know. But I hope it helps a little bit.
++ The best way is to look which clock comes closet to your and tweak that
++ code.
++ Two sorts of clocks are used with parse. Clocks that automatically sent
++ thier time code (once a second) do not nee entries in the poll routines because
++ they sent the data all the time. The second sort are the clocks that need a
++ command sent to then in order to reply with a time code (like the Trimble
++ clock).
++
++ For questions: kardel@informatik.uni-erlangen.de. Please include
++ an exact description on how your clock works. (initialisation,
++ TTY modes, strings to be sent to it, responses received from the clock).
++
++ Frank Kardel
+diff -c /dev/null parse/README.parse_clocks:3.1
+*** /dev/null Wed Feb 2 18:14:33 1994
+--- parse/README.parse_clocks Wed Feb 2 18:14:33 1994
+***************
+*** 0 ****
+--- 1,263 ----
++ The parse driver currently supports several clock with different
++ query mechanisms. In order for you to find a sample that might be
++ similar to a clock you might want to integrate into parse i'll sum
++ up the major features of the clocks (this information is distributed
++ in the parse/clk_*.c and xntpd/refclock_parse.c files).
++
++ ---
++ Meinberg: 127.127.8. 0- 3 (PZF535TCXO)
++ 127.127.8. 4- 7 (PZF535OCXO)
++ 127.127.8. 8-11 (DCFUA31)
++ 127.127.8.28-31 (GPS166)
++ Meinberg: start=<STX>, end=<ETX>, sync on start
++ pattern="\2D: . . ;T: ;U: . . ; \3"
++ pattern="\2 . . ; ; : : ; \3"
++ pattern="\2 . . ; ; : : ; : ; ; . . "
++
++ Meinberg is a german manufacturer of time code receivers. Those clocks
++ have a pretty common output format in the stock version. In order to
++ support NTP Meinberg was so kind to produce some special versions of
++ the firmware for the use with NTP. So, if you are going to use a
++ Meinberg clock please ask whether there is a special Uni Erlangen
++ version.
++
++ General characteristics:
++ Meinberg clocks primarily output pulse per second and a describing
++ ASCII string. This string can be produced in two modes. either upon
++ the reception of a question mark or every second. NTP uses the latter
++ mechanism. The DCF77 variants have a pretty good relationship between
++ RS232 time code and the PPS signal while the GPS receiver has no fixed
++ timeing between the datagram and the pulse (you need to use PPS with
++ GPS!) on DCF77 you might get away without the PPS signal.
++
++ The preferred tty setting for Meinberg is:
++ CFLAG (B9600|CS7|PARENB|CREAD|HUPCL)
++ IFLAG (IGNBRK|IGNPAR|ISTRIP)
++ OFLAG 0
++ LFLAG 0
++
++ The clock is run at datagram once per second.
++ Stock dataformat is:
++
++ <STX>D:<dd>.<mm>.<yy>;T:<w>;U:<hh>:<mm>:<ss>;<S><F><D><A><ETX>
++ pos: 0 00 00 0 00 0 11 111 1 111 12 2 22 2 22 2 2 2 3 3 3
++ 1 23 45 6 78 9 01 234 5 678 90 1 23 4 56 7 8 9 0 1 2
++
++ <STX> = '\002' ASCII start of text
++ <ETX> = '\003' ASCII end of text
++ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
++ <w> = day of week (sunday= 0)
++ <hh>,<mm>,<ss> = hour, minute, second
++ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
++ '#' if not PZF sychronisation available else ' ' for PZF 535
++ <F> = '*' if time comes from internal quartz else ' '
++ <D> = 'S' if daylight saving time is active else ' '
++ <A> = '!' during the hour preceeding an daylight saving time
++ start/end change
++
++ For the university of Erlangen a special format was implemented to support
++ LEAP announcement and anouncement of alternate antenna.
++
++ Version for UNI-ERLANGEN Software is: PZFUERL V4.6 (Meinberg)
++
++ The use of this software release (or higher) is *ABSOLUTELY*
++ recommended (ask for PZFUERL version as some minor HW fixes have
++ been introduced) due to the LEAP second support and UTC indication.
++ The standard timecode does not indicate when the timecode is in
++ UTC (by front panel configuration) thus we have no chance to find
++ the correct utc offset. For the standard format do not ever use
++ UTC display as this is not detectable in the time code !!!
++
++ <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <U><S><F><D><A><L><R><ETX>
++ pos: 0 00 0 00 0 00 11 1 11 11 1 11 2 22 22 2 2 2 2 2 3 3 3
++ 1 23 4 56 7 89 01 2 34 56 7 89 0 12 34 5 6 7 8 9 0 1 2
++ <STX> = '\002' ASCII start of text
++ <ETX> = '\003' ASCII end of text
++ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
++ <w> = day of week (sunday= 0)
++ <hh>,<mm>,<ss> = hour, minute, second
++ <U> = 'U' UTC time display
++ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
++ '#' if not PZF sychronisation available else ' ' for PZF 535
++ <F> = '*' if time comes from internal quartz else ' '
++ <D> = 'S' if daylight saving time is active else ' '
++ <A> = '!' during the hour preceeding an daylight saving time
++ start/end change
++ <L> = 'A' LEAP second announcement
++ <R> = 'R' alternate antenna
++
++ Meinberg GPS166 receiver
++
++ You must get the Uni-Erlangen firmware for the GPS receiver support
++ to work to full satisfaction !
++
++ <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <+/-><00:00>; <U><S><F><D><A><L><R><L>; <position...><ETX>
++ *
++ 000000000111111111122222222223333333333444444444455555555556666666
++ 123456789012345678901234567890123456789012345678901234567890123456
++ \x0209.07.93; 5; 08:48:26; +00:00; ; 49.5736N 11.0280E 373m\x03
++ *
++
++ <STX> = '\002' ASCII start of text
++ <ETX> = '\003' ASCII end of text
++ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
++ <w> = day of week (sunday= 0)
++ <hh>,<mm>,<ss> = hour, minute, second
++ <+/->,<00:00> = offset to UTC
++ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
++ '#' if not PZF sychronisation available else ' ' for PZF 535
++ <U> = 'U' UTC time display
++ <F> = '*' if time comes from internal quartz else ' '
++ <D> = 'S' if daylight saving time is active else ' '
++ <A> = '!' during the hour preceeding an daylight saving time
++ start/end change
++ <L> = 'A' LEAP second announcement
++ <R> = 'R' alternate antenna (reminiscent of PZF535) usually ' '
++ <L> = 'L' on 23:59:60
++
++
++ For the Meinberg parse look into clock_meinberg.c
++
++ ---
++ RAWDCF: 127.127.8.20-23 (Conrad receiver module - delay 210ms)
++ 127.127.8.24-27 (FAU receiver - delay 258ms)
++ RAWDCF: end=TIMEOUT>1.5s, sync each char (any char),generate psuedo time
++ codes, fixed format
++
++ direct DCF77 code input
++ In Europe it is relatively easy/cheap the receive the german time code
++ transmitter DCF77. The simplest version to process its signal is to
++ feed the 100/200ms pulse of the demodulated AM signal via a level
++ converter to an RS232 port at 50Baud. parse/clk_rawdcf.c holds all
++ necessary decoding logic for the time code which is transmitted each
++ minute for one minute. A bit of the time code is sent once a second.
++
++ The preferred tty setting is:
++ CFLAG (B50|CS8|CREAD|CLOCAL)
++ IFLAG 0
++ OFLAG 0
++ LFLAG 0
++
++ DCF77 raw time code
++
++ From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
++ und Berlin, Maerz 1989
++
++ Timecode transmission:
++ AM:
++ time marks are send every second except for the second before the
++ next minute mark
++ time marks consist of a reduction of transmitter power to 25%
++ of the nominal level
++ the falling edge is the time indication (on time)
++ time marks of a 100ms duration constitute a logical 0
++ time marks of a 200ms duration constitute a logical 1
++ FM:
++ see the spec. (basically a (non-)inverted psuedo random phase shift)
++
++ Encoding:
++ Second Contents
++ 0 - 10 AM: free, FM: 0
++ 11 - 14 free
++ 15 R - alternate antenna
++ 16 A1 - expect zone change (1 hour before)
++ 17 - 18 Z1,Z2 - time zone
++ 0 0 illegal
++ 0 1 MEZ (MET)
++ 1 0 MESZ (MED, MET DST)
++ 1 1 illegal
++ 19 A2 - expect leap insertion/deletion (1 hour before)
++ 20 S - start of time code (1)
++ 21 - 24 M1 - BCD (lsb first) Minutes
++ 25 - 27 M10 - BCD (lsb first) 10 Minutes
++ 28 P1 - Minute Parity (even)
++ 29 - 32 H1 - BCD (lsb first) Hours
++ 33 - 34 H10 - BCD (lsb first) 10 Hours
++ 35 P2 - Hour Parity (even)
++ 36 - 39 D1 - BCD (lsb first) Days
++ 40 - 41 D10 - BCD (lsb first) 10 Days
++ 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
++ 45 - 49 MO - BCD (lsb first) Month
++ 50 MO0 - 10 Months
++ 51 - 53 Y1 - BCD (lsb first) Years
++ 54 - 57 Y10 - BCD (lsb first) 10 Years
++ 58 P3 - Date Parity (even)
++ 59 - usually missing (minute indication), except for leap insertion
++
++ ---
++ Schmid clock: 127.127.8.16-19
++ Schmid clock: needs poll, binary input, end='\xFC', sync start
++
++ The Schmid clock is a DCF77 receiver that sends a binary
++ time code at the reception of a flag byte. The contents
++ if the flag byte determined the time code format. The
++ binary time code is delimited by the byte 0xFC.
++
++ TTY setup is:
++ CFLAG (B1200|CS8|CREAD|CLOCAL)
++ IFLAG 0
++ OFLAG 0
++ LFLAG 0
++
++ The command to Schmid's DCF77 clock is a single byte; each bit
++ allows the user to select some part of the time string, as follows (the
++ output for the lsb is sent first).
++
++ Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths
++ Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy
++ Bit 2: week day, 1 byte (unused here)
++ Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here)
++ Bit 4: clock status, 1 byte, 0=time invalid,
++ 1=time from crystal backup,
++ 3=time from DCF77
++ Bit 5: transmitter status, 1 byte,
++ bit 0: backup antenna
++ bit 1: time zone change within 1h
++ bit 3,2: TZ 01=MEST, 10=MET
++ bit 4: leap second will be
++ added within one hour
++ bits 5-7: Zero
++ Bit 6: time in backup mode, units of 5 minutes (unused here)
++
++
++ ---
++ Trimble SV6: 127.127.8.32-35
++ Trimble SV6: needs poll, ascii timecode, start='>', end='<',
++ query='>QTM<', eol='<'
++
++ Trimble SV6 is a GPS receiver with PPS output. It needs to be polled.
++ It also need a special tty mode setup (EOL='<').
++
++ TTY setup is:
++ CFLAG (B4800|CS8|CREAD)
++ IFLAG (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON)
++ OFLAG (OPOST|ONLCR)
++ LFLAG (ICANON|ECHOK)
++
++ Special flags are:
++ PARSE_F_PPSPPS - use CIOGETEV for PPS time stamping
++ PARSE_F_PPSONSECOND - the time code is not related to
++ the PPS pulse (so use the time code
++ only for the second epoch)
++
++ Timecode
++ 0000000000111111111122222222223333333 / char
++ 0123456789012345678901234567890123456 \ posn
++ >RTMhhmmssdddDDMMYYYYoodnnvrrrrr;*xx< Actual
++ ----33445566600112222BB7__-_____--99- Parse
++ >RTM 1 ;* <", Check
++
++ ---
++ ELV DCF7000: 127.127.8.12-15
++ ELV DCF7000: end='\r', pattern=" - - - - - - - \r"
++
++ The ELV DCF7000 is a cheap DCF77 receiver sending each second
++ a time code (though not very precise!) delimited by '`r'
++
++ Timecode
++ YY-MM-DD-HH-MM-SS-FF\r
++
++ FF&0x1 - DST
++ FF&0x2 - DST switch warning
++ FF&0x4 - unsynchronised
++
+diff -c parse/parsesolaris.c:1.1.1.5 parse/parsesolaris.c:3.11
+*** parse/parsesolaris.c:1.1.1.5 Wed Feb 2 18:14:49 1994
+--- parse/parsesolaris.c Wed Feb 2 18:14:49 1994
+***************
+*** 65,71 ****
+ {
+ "parse", /* module name */
+ &parseinfo, /* module information */
+! 0, /* not clean yet */
+ /* lock ptr */
+ };
+
+--- 65,71 ----
+ {
+ "parse", /* module name */
+ &parseinfo, /* module information */
+! D_NEW, /* not clean yet */
+ /* lock ptr */
+ };
+
+diff -c scripts/support/bin/monl:1.1.1.1 scripts/support/bin/monl:1.2
+*** scripts/support/bin/monl:1.1.1.1 Wed Feb 2 18:16:01 1994
+--- scripts/support/bin/monl Wed Feb 2 18:16:01 1994
+***************
+*** 143,149 ****
+ {
+ chop;
+ split;
+! ($host, $count, $mode, $version, $lasttime, $firsttime) = (@_[$[, $[+2 .. $[+6]);
+
+ $Seen{$host, $mode} = 1;
+
+--- 143,150 ----
+ {
+ chop;
+ split;
+! ($host, $count, $mode, $version, $lasttime, $firsttime) =
+! (@_[$[, $[+2 .. $[+4, $#_-1,$#_]);
+
+ $Seen{$host, $mode} = 1;
+
+diff -c util/tickadj.c:1.1.1.16 util/tickadj.c:3.17
+*** util/tickadj.c:1.1.1.16 Wed Feb 2 18:16:23 1994
+--- util/tickadj.c Wed Feb 2 18:16:23 1994
+***************
+*** 1,4 ****
+! /* tickadj.c,v 3.1 1993/07/06 01:11:05 jbj Exp
+ * tickadj - read, and possibly modify, the kernel `tick' and
+ * `tickadj' variables, as well as `dosynctodr'. Note that
+ * this operates on the running kernel only. I'd like to be
+--- 1,4 ----
+! /*
+ * tickadj - read, and possibly modify, the kernel `tick' and
+ * `tickadj' variables, as well as `dosynctodr'. Note that
+ * this operates on the running kernel only. I'd like to be
+***************
+*** 6,11 ****
+--- 6,46 ----
+ * mastered this yet.
+ */
+ #include <stdio.h>
++
++ #ifdef SYS_LINUX
++ #include <sys/timex.h>
++
++ struct timex txc;
++
++ int
++ main(int argc, char ** argv)
++ {
++ if (argc > 2)
++ {
++ fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
++ exit(-1);
++ }
++ else if (argc == 2)
++ {
++ if ( (txc.tick = atoi(argv[1])) < 1 )
++ {
++ fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
++ exit(-1);
++ }
++ txc.mode = ADJ_TICK;
++ }
++ else
++ txc.mode = 0;
++
++ if (__adjtimex(&txc) < 0)
++ perror("adjtimex");
++ else
++ printf("tick = %d\n", txc.tick);
++
++ return(0);
++ }
++ #else /* not Linux... kmem tweaking: */
++
+ #include <sys/types.h>
+ #include <sys/file.h>
+ #include <sys/stat.h>
+***************
+*** 513,515 ****
+--- 548,551 ----
+ exit(1);
+ }
+ }
++ #endif /* not Linux */
+diff -c xntpd/ntp_config.c:1.1.1.19 xntpd/ntp_config.c:3.24
+*** xntpd/ntp_config.c:1.1.1.19 Wed Feb 2 18:16:36 1994
+--- xntpd/ntp_config.c Wed Feb 2 18:16:37 1994
+***************
+*** 58,63 ****
+--- 58,64 ----
+ * statsdir /var/NTP/
+ * filegen peerstats [ file peerstats ] [ type day ] [ link ]
+ * resolver /path/progname
++ * netlimit integer
+ *
+ * And then some. See the manual page.
+ */
+***************
+*** 94,99 ****
+--- 95,102 ----
+ #define CONFIG_PIDFILE 25
+ #define CONFIG_LOGFILE 26
+ #define CONFIG_SETVAR 27
++ #define CONFIG_CLIENTLIMIT 28
++ #define CONFIG_CLIENTPERIOD 29
+
+ #define CONF_MOD_VERSION 1
+ #define CONF_MOD_KEY 2
+***************
+*** 114,119 ****
+--- 117,123 ----
+ #define CONF_RES_NOTRAP 8
+ #define CONF_RES_LPTRAP 9
+ #define CONF_RES_NTPPORT 10
++ #define CONF_RES_LIMITED 11
+
+ #define CONF_TRAP_PORT 1
+ #define CONF_TRAP_INTERFACE 2
+***************
+*** 179,184 ****
+--- 183,190 ----
+ { "pidfile", CONFIG_PIDFILE },
+ { "logfile", CONFIG_LOGFILE },
+ { "setvar", CONFIG_SETVAR },
++ { "clientlimit", CONFIG_CLIENTLIMIT },
++ { "clientperiod", CONFIG_CLIENTPERIOD },
+ { "", CONFIG_UNKNOWN }
+ };
+
+***************
+*** 217,222 ****
+--- 223,229 ----
+ { "notrap", CONF_RES_NOTRAP },
+ { "lowpriotrap", CONF_RES_LPTRAP },
+ { "ntpport", CONF_RES_NTPPORT },
++ { "limited", CONF_RES_LIMITED },
+ { "", CONFIG_UNKNOWN }
+ };
+
+***************
+*** 817,825 ****
+ errflg = 0;
+ if (ntokens >= 2) {
+ if (STREQ(tokens[1], "yes"))
+! mon_start();
+ else if (STREQ(tokens[1], "no"))
+! mon_stop();
+ else
+ errflg++;
+ } else {
+--- 824,832 ----
+ errflg = 0;
+ if (ntokens >= 2) {
+ if (STREQ(tokens[1], "yes"))
+! mon_start(MON_ON);
+ else if (STREQ(tokens[1], "no"))
+! mon_stop(MON_ON);
+ else
+ errflg++;
+ } else {
+***************
+*** 965,970 ****
+--- 972,981 ----
+ peerkey |= RESM_NTPONLY;
+ break;
+
++ case CONF_RES_LIMITED:
++ peerversion |= RES_LIMITED;
++ break;
++
+ case CONFIG_UNKNOWN:
+ errflg++;
+ break;
+***************
+*** 1413,1418 ****
+--- 1424,1483 ----
+ set_sys_var(tokens[1], strlen(tokens[1])+1, RW |
+ ((((ntokens > 2) && !strcmp(tokens[2], "default"))) ? DEF : 0));
+ }
++ break;
++
++ case CONFIG_CLIENTLIMIT:
++ if (ntokens < 2)
++ {
++ syslog(LOG_ERR,
++ "no value for clientlimit command - line ignored");
++ }
++ else
++ {
++ U_LONG i;
++ if (!atouint(tokens[1], &i) || !i)
++ {
++ syslog(LOG_ERR,
++ "illegal value for clientlimit command - line ignored");
++ }
++ else
++ {
++ extern U_LONG client_limit;
++ char bp[80];
++
++ sprintf(bp, "client_limit=%d", i);
++ set_sys_var(bp, strlen(bp)+1, RO);
++
++ client_limit = i;
++ }
++ }
++ break;
++
++ case CONFIG_CLIENTPERIOD:
++ if (ntokens < 2)
++ {
++ syslog(LOG_ERR,
++ "no value for clientperiod command - line ignored");
++ }
++ else
++ {
++ U_LONG i;
++ if (!atouint(tokens[1], &i) || i < 64)
++ {
++ syslog(LOG_ERR,
++ "illegal value for clientperiod command - line ignored");
++ }
++ else
++ {
++ extern U_LONG client_limit_period;
++ char bp[80];
++
++ sprintf(bp, "client_limit_period=%d", i);
++ set_sys_var(bp, strlen(bp)+1, RO);
++
++ client_limit_period = i;
++ }
++ }
+ break;
+ }
+ }
+diff -c xntpd/ntp_monitor.c:1.1.1.10 xntpd/ntp_monitor.c:3.9
+*** xntpd/ntp_monitor.c:1.1.1.10 Wed Feb 2 18:16:48 1994
+--- xntpd/ntp_monitor.c Wed Feb 2 18:16:48 1994
+***************
+*** 58,64 ****
+ static struct mon_data *mon_hash; /* Pointer to array of hash buckets */
+ static int *mon_hash_count; /* Point to hash count stats keeper */
+ struct mon_data mon_mru_list;
+!
+ /*
+ * List of free structures structures, and counters of free and total
+ * structures. The free structures are linked with the hash_next field.
+--- 58,64 ----
+ static struct mon_data *mon_hash; /* Pointer to array of hash buckets */
+ static int *mon_hash_count; /* Point to hash count stats keeper */
+ struct mon_data mon_mru_list;
+! struct mon_data mon_fifo_list;
+ /*
+ * List of free structures structures, and counters of free and total
+ * structures. The free structures are linked with the hash_next field.
+***************
+*** 93,99 ****
+ * Don't do much of anything here. We don't allocate memory
+ * until someone explicitly starts us.
+ */
+! mon_enabled = 0;
+ mon_have_memory = 0;
+
+ mon_free_mem = 0;
+--- 93,99 ----
+ * Don't do much of anything here. We don't allocate memory
+ * until someone explicitly starts us.
+ */
+! mon_enabled = MON_OFF;
+ mon_have_memory = 0;
+
+ mon_free_mem = 0;
+***************
+*** 103,108 ****
+--- 103,109 ----
+ mon_hash = 0;
+ mon_hash_count = 0;
+ memset((char *)&mon_mru_list, 0, sizeof mon_mru_list);
++ memset((char *)&mon_fifo_list, 0, sizeof mon_fifo_list);
+ }
+
+
+***************
+*** 110,122 ****
+ * mon_start - start up the monitoring software
+ */
+ void
+! mon_start()
+ {
+ register struct mon_data *md;
+ register int i;
+
+! if (mon_enabled)
+ return;
+
+ if (!mon_have_memory) {
+ mon_hash = (struct mon_data *)
+--- 111,128 ----
+ * mon_start - start up the monitoring software
+ */
+ void
+! mon_start(mode)
+! int mode;
+ {
+ register struct mon_data *md;
+ register int i;
+
+! if (mon_enabled != MON_OFF) {
+! mon_enabled |= mode;
+ return;
++ }
++ if (mode == MON_OFF)
++ return; /* Ooops.. */
+
+ if (!mon_have_memory) {
+ mon_hash = (struct mon_data *)
+***************
+*** 142,148 ****
+ mon_mru_list.mru_next = &mon_mru_list;
+ mon_mru_list.mru_prev = &mon_mru_list;
+
+! mon_enabled = 1;
+ }
+
+
+--- 148,157 ----
+ mon_mru_list.mru_next = &mon_mru_list;
+ mon_mru_list.mru_prev = &mon_mru_list;
+
+! mon_fifo_list.fifo_next = &mon_fifo_list;
+! mon_fifo_list.fifo_prev = &mon_fifo_list;
+!
+! mon_enabled = mode;
+ }
+
+
+***************
+*** 150,161 ****
+ * mon_stop - stop the monitoring software
+ */
+ void
+! mon_stop()
+ {
+ register struct mon_data *md;
+ register int i;
+
+! if (!mon_enabled)
+ return;
+
+ /*
+--- 159,177 ----
+ * mon_stop - stop the monitoring software
+ */
+ void
+! mon_stop(mode)
+! int mode;
+ {
+ register struct mon_data *md;
+ register int i;
+
+! if (mon_enabled == MON_OFF)
+! return;
+! if ((mon_enabled & mode) == 0 || mode == MON_OFF)
+! return;
+!
+! mon_enabled &= ~mode;
+! if (mon_enabled != MON_OFF)
+ return;
+
+ /*
+***************
+*** 176,182 ****
+ mon_mru_list.mru_next = &mon_mru_list;
+ mon_mru_list.mru_prev = &mon_mru_list;
+
+! mon_enabled = 0;
+ }
+
+
+--- 192,199 ----
+ mon_mru_list.mru_next = &mon_mru_list;
+ mon_mru_list.mru_prev = &mon_mru_list;
+
+! mon_fifo_list.fifo_next = &mon_fifo_list;
+! mon_fifo_list.fifo_prev = &mon_fifo_list;
+ }
+
+
+***************
+*** 194,200 ****
+ register int mode;
+ register struct mon_data *mdhash;
+
+! if (!mon_enabled)
+ return;
+
+ pkt = &rbufp->recv_pkt;
+--- 211,217 ----
+ register int mode;
+ register struct mon_data *mdhash;
+
+! if (mon_enabled == MON_OFF)
+ return;
+
+ pkt = &rbufp->recv_pkt;
+***************
+*** 220,225 ****
+--- 237,243 ----
+ md->mru_prev = &mon_mru_list;
+ mon_mru_list.mru_next->mru_prev = md;
+ mon_mru_list.mru_next = md;
++
+ return;
+ }
+ md = md->hash_next;
+***************
+*** 240,245 ****
+--- 258,269 ----
+ md->hash_next->hash_prev = md->hash_prev;
+ md->hash_prev->hash_next = md->hash_next;
+ *(mon_hash_count + MON_HASH(md->rmtadr)) -= 1;
++ /*
++ * Get it from FIFO list
++ */
++ md->fifo_prev->fifo_next = md->fifo_next;
++ md->fifo_next->fifo_prev = md->fifo_prev;
++
+ } else {
+ if (mon_free_mem == 0)
+ mon_getmoremem();
+***************
+*** 252,257 ****
+--- 276,282 ----
+ * Got one, initialize it
+ */
+ md->lasttime = md->firsttime = current_time;
++ md->lastdrop = 0;
+ md->count = 1;
+ md->rmtadr = netnum;
+ md->rmtport = NSRCPORT(&rbufp->recv_srcadr);
+***************
+*** 260,266 ****
+
+ /*
+ * Shuffle him into the hash table, inserting him at the
+! * end. Also put him on top of the MRU list.
+ */
+ mdhash = mon_hash + MON_HASH(netnum);
+ md->hash_next = mdhash;
+--- 285,292 ----
+
+ /*
+ * Shuffle him into the hash table, inserting him at the
+! * end. Also put him on top of the MRU list
+! * and at bottom of FIFO list
+ */
+ mdhash = mon_hash + MON_HASH(netnum);
+ md->hash_next = mdhash;
+***************
+*** 273,278 ****
+--- 299,309 ----
+ md->mru_prev = &mon_mru_list;
+ mon_mru_list.mru_next->mru_prev = md;
+ mon_mru_list.mru_next = md;
++
++ md->fifo_prev = mon_fifo_list.fifo_prev;
++ md->fifo_next = &mon_fifo_list;
++ mon_fifo_list.fifo_prev->fifo_next = md;
++ mon_fifo_list.fifo_prev = md;
+ }
+
+
+diff -c xntpd/ntp_proto.c:1.1.1.19 xntpd/ntp_proto.c:3.21
+*** xntpd/ntp_proto.c:1.1.1.19 Wed Feb 2 18:16:51 1994
+--- xntpd/ntp_proto.c Wed Feb 2 18:16:52 1994
+***************
+*** 49,54 ****
+--- 49,55 ----
+ U_LONG sys_processed; /* packets processed */
+ U_LONG sys_badauth; /* packets dropped because of authorization */
+ U_LONG sys_wanderhold; /* sys_peer held to prevent wandering */
++ U_LONG sys_limitrejected; /* pkts rejected due toclient count per net */
+
+ /*
+ * Imported from ntp_timer.c
+***************
+*** 373,378 ****
+--- 374,394 ----
+ return;
+
+ /*
++ * See if we only accept limited number of clients
++ * from the net this guy is from.
++ * Note: the flag is determined dynamically within restrictions()
++ */
++ if (restrict & RES_LIMITED) {
++ extern U_LONG client_limit;
++
++ sys_limitrejected++;
++ syslog(LOG_NOTICE,
++ "rejected mode %d request from %s - per net client limit (%d) exceeded",
++ PKT_MODE(pkt->li_vn_mode),
++ ntoa(&rbufp->recv_srcadr), client_limit);
++ return;
++ }
++ /*
+ * Dump anything with a putrid stratum. These will most likely
+ * come from someone trying to poll us with ntpdc.
+ */
+***************
+*** 2165,2168 ****
+--- 2181,2185 ----
+ sys_badauth = 0;
+ sys_wanderhold = 0;
+ sys_stattime = current_time;
++ sys_limitrejected = 0;
+ }
+diff -c xntpd/ntp_request.c:1.1.1.14 xntpd/ntp_request.c:3.15
+*** xntpd/ntp_request.c:1.1.1.14 Wed Feb 2 18:16:55 1994
+--- xntpd/ntp_request.c Wed Feb 2 18:16:55 1994
+***************
+*** 916,921 ****
+--- 916,922 ----
+ extern U_LONG sys_processed;
+ extern U_LONG sys_badauth;
+ extern U_LONG sys_wanderhold;
++ extern U_LONG sys_limitrejected;
+
+ ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_sys_stats));
+***************
+*** 930,936 ****
+ ss->processed = htonl(sys_processed);
+ ss->badauth = htonl(sys_badauth);
+ ss->wanderhold = htonl(sys_wanderhold);
+!
+ (void) more_pkt();
+ flush_pkt();
+ }
+--- 931,937 ----
+ ss->processed = htonl(sys_processed);
+ ss->badauth = htonl(sys_badauth);
+ ss->wanderhold = htonl(sys_wanderhold);
+! ss->limitrejected = htonl(sys_limitrejected);
+ (void) more_pkt();
+ flush_pkt();
+ }
+***************
+*** 1311,1317 ****
+ struct interface *inter;
+ struct req_pkt *inpkt;
+ {
+! mon_start();
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+ }
+
+--- 1312,1318 ----
+ struct interface *inter;
+ struct req_pkt *inpkt;
+ {
+! mon_start(MON_ON);
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+ }
+
+***************
+*** 1325,1331 ****
+ struct interface *inter;
+ struct req_pkt *inpkt;
+ {
+! mon_stop();
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+ }
+
+--- 1326,1332 ----
+ struct interface *inter;
+ struct req_pkt *inpkt;
+ {
+! mon_stop(MON_ON);
+ req_ack(srcadr, inter, inpkt, INFO_OKAY);
+ }
+
+***************
+*** 1497,1502 ****
+--- 1498,1507 ----
+ md = md->mru_next) {
+ im->lasttime = htonl(current_time - md->lasttime);
+ im->firsttime = htonl(current_time - md->firsttime);
++ if (md->lastdrop)
++ im->lastdrop = htonl(current_time - md->lastdrop);
++ else
++ im->lastdrop = 0;
+ im->count = htonl(md->count);
+ im->addr = md->rmtadr;
+ im->port = md->rmtport;
+diff -c xntpd/ntp_restrict.c:1.1.1.10 xntpd/ntp_restrict.c:3.10
+*** xntpd/ntp_restrict.c:1.1.1.10 Wed Feb 2 18:16:57 1994
+--- xntpd/ntp_restrict.c Wed Feb 2 18:16:57 1994
+***************
+*** 1,4 ****
+! /* ntp_restrict.c,v 3.1 1993/07/06 01:11:28 jbj Exp
+ * ntp_restrict.c - find out what restrictions this host is running under
+ */
+ #include <stdio.h>
+--- 1,4 ----
+! /*
+ * ntp_restrict.c - find out what restrictions this host is running under
+ */
+ #include <stdio.h>
+***************
+*** 60,65 ****
+--- 60,80 ----
+ U_LONG res_timereset;
+
+ /*
++ * Parameters of the RES_LIMITED restriction option.
++ * client_limit is the number of hosts allowed per source net
++ * client_limit_period is the number of seconds after which an entry
++ * is no longer considered for client limit determination
++ */
++ U_LONG client_limit;
++ U_LONG client_limit_period;
++ /*
++ * count number of restriction entries referring to RES_LIMITED
++ * controls activation/deactivation of monitoring
++ * (with respect ro RES_LIMITED control)
++ */
++ U_LONG res_limited_refcnt;
++
++ /*
+ * Our initial allocation of list entries.
+ */
+ static struct restrictlist resinit[INITRESLIST];
+***************
+*** 70,81 ****
+--- 85,102 ----
+ extern U_LONG current_time;
+
+ /*
++ * debug flag
++ */
++ extern int debug;
++
++ /*
+ * init_restrict - initialize the restriction data structures
+ */
+ void
+ init_restrict()
+ {
+ register int i;
++ char bp[80];
+
+ /*
+ * Zero the list and put all but one on the free list
+***************
+*** 108,113 ****
+--- 129,146 ----
+ res_found = 0;
+ res_not_found = 0;
+ res_timereset = 0;
++
++ /*
++ * set default values for RES_LIMIT functionality
++ */
++ client_limit = 3;
++ client_limit_period = 3600;
++ res_limited_refcnt = 0;
++
++ sprintf(bp, "client_limit=%d", client_limit);
++ set_sys_var(bp, strlen(bp)+1, RO);
++ sprintf(bp, "client_limit_period=%d", client_limit_period);
++ set_sys_var(bp, strlen(bp)+1, RO);
+ }
+
+
+***************
+*** 150,155 ****
+--- 183,302 ----
+ else
+ res_found++;
+
++ /*
++ * The following implements limiting the number of clients
++ * accepted from a given network. The notion of "same network"
++ * is determined by the mask and addr fields of the restrict
++ * list entry. The monitor mechanism has to be enabled for
++ * collecting info on current clients.
++ *
++ * The policy is as follows:
++ * - take the list of clients recorded
++ * from the given "network" seen within the last
++ * client_limit_period seconds
++ * - if there are at most client_limit entries:
++ * --> access allowed
++ * - otherwise sort by time first seen
++ * - current client among the first client_limit seen
++ * hosts?
++ * if yes: access allowed
++ * else: eccess denied
++ */
++ if (match->flags & RES_LIMITED) {
++ int lcnt;
++ struct mon_data *md, *this_client;
++ extern int mon_enabled;
++ extern struct mon_data mon_fifo_list, mon_mru_list;
++
++ #ifdef DEBUG
++ if (debug > 2)
++ printf("limited clients check: %d clients, period %d seconds, net is 0x%X\n",
++ client_limit, client_limit_period,
++ netof(hostaddr));
++ #endif /*DEBUG*/
++ if (mon_enabled == MON_OFF) {
++ #ifdef DEBUG
++ if (debug > 4)
++ printf("no limit - monitoring is off\n");
++ #endif
++ return (int)(match->flags & ~RES_LIMITED);
++ }
++
++ /*
++ * How nice, MRU list provides our current client as the
++ * first entry in the list.
++ * Monitoring was verified to be active above, thus we
++ * know an entry for our client must exist, or some
++ * brain dead set the memory limit for mon entries to ZERO!!!
++ */
++ this_client = mon_mru_list.mru_next;
++
++ for (md = mon_fifo_list.fifo_next,lcnt = 0;
++ md != &mon_fifo_list;
++ md = md->fifo_next) {
++ if ((current_time - md->lasttime)
++ > client_limit_period) {
++ #ifdef DEBUG
++ if (debug > 5)
++ printf("checking: %s: ignore: too old: %d\n",
++ numtoa(md->rmtadr),
++ current_time - md->lasttime);
++ #endif
++ continue;
++ }
++ if (md->mode == MODE_BROADCAST ||
++ md->mode == MODE_CONTROL ||
++ md->mode == MODE_PRIVATE) {
++ #ifdef DEBUG
++ if (debug > 5)
++ printf("checking: %s: ignore mode %d\n",
++ numtoa(md->rmtadr),
++ md->mode);
++ #endif
++ continue;
++ }
++ if (netof(md->rmtadr) !=
++ netof(hostaddr)) {
++ #ifdef DEBUG
++ if (debug > 5)
++ printf("checking: %s: different net 0x%X\n",
++ numtoa(md->rmtadr),
++ netof(md->rmtadr));
++ #endif
++ continue;
++ }
++ lcnt++;
++ if (lcnt > client_limit ||
++ md->rmtadr == hostaddr) {
++ #ifdef DEBUG
++ if (debug > 5)
++ printf("considering %s: found host\n",
++ numtoa(md->rmtadr));
++ #endif
++ break;
++ }
++ #ifdef DEBUG
++ else {
++ if (debug > 5)
++ printf("considering %s: same net\n",
++ numtoa(md->rmtadr));
++ }
++ #endif
++
++ }
++ #ifdef DEBUG
++ if (debug > 4)
++ printf("this one is rank %d in list, limit is %d: %s\n",
++ lcnt, client_limit,
++ (lcnt <= client_limit) ? "ALLOW" : "REJECT");
++ #endif
++ if (lcnt <= client_limit) {
++ this_client->lastdrop = 0;
++ return (int)(match->flags & ~RES_LIMITED);
++ } else {
++ this_client->lastdrop = current_time;
++ }
++ }
+ return (int)match->flags;
+ }
+
+***************
+*** 257,262 ****
+--- 404,413 ----
+ rlprev->next = rl;
+ restrictcount++;
+ }
++ if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
++ res_limited_refcnt++;
++ mon_start(MON_RES); /* ensure data gets collected */
++ }
+ rl->flags |= (u_short)flags;
+ break;
+
+***************
+*** 265,272 ****
+ * Remove some bits from the flags. If we didn't
+ * find this one, just return.
+ */
+! if (rl != 0)
+ rl->flags &= (u_short)~flags;
+ break;
+
+ case RESTRICT_REMOVE:
+--- 416,429 ----
+ * Remove some bits from the flags. If we didn't
+ * find this one, just return.
+ */
+! if (rl != 0) {
+! if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
+! res_limited_refcnt--;
+! if (res_limited_refcnt == 0)
+! mon_stop(MON_RES);
+! }
+ rl->flags &= (u_short)~flags;
++ }
+ break;
+
+ case RESTRICT_REMOVE:
+***************
+*** 280,285 ****
+--- 437,447 ----
+ && !(rl->mflags & RESM_INTERFACE)) {
+ rlprev->next = rl->next;
+ restrictcount--;
++ if (rl->flags & RES_LIMITED) {
++ res_limited_refcnt--;
++ if (res_limited_refcnt == 0)
++ mon_stop(MON_RES);
++ }
+ memset((char *)rl, 0, sizeof(struct restrictlist));
+
+ rl->next = resfree;
+diff -c xntpd/ntp_unixclock.c:1.1.1.27 xntpd/ntp_unixclock.c:3.29
+*** xntpd/ntp_unixclock.c:1.1.1.27 Wed Feb 2 18:17:00 1994
+--- xntpd/ntp_unixclock.c Wed Feb 2 18:17:01 1994
+***************
+*** 556,568 ****
+ #endif /* SOLARIS */
+
+ #ifdef SYS_LINUX
+! /* XXX should look this up somewhere ! */
+ static void
+ clock_parms(tickadj, tick)
+ U_LONG *tickadj;
+ U_LONG *tick;
+ {
+! *tickadj = (U_LONG)1;
+! *tick = (U_LONG)10000;
+ }
+ #endif /* SYS_LINUX */
+--- 556,573 ----
+ #endif /* SOLARIS */
+
+ #ifdef SYS_LINUX
+! #include <sys/timex.h>
+ static void
+ clock_parms(tickadj, tick)
+ U_LONG *tickadj;
+ U_LONG *tick;
+ {
+! struct timex txc;
+!
+! txc.mode = 0;
+! __adjtimex(&txc);
+!
+! *tickadj = (U_LONG)1; /* our adjtime is accurate */
+! *tick = (U_LONG)txc.tick;
+ }
+ #endif /* SYS_LINUX */
+diff -c xntpdc/ntpdc_ops.c:1.1.1.12 xntpdc/ntpdc_ops.c:3.16
+*** xntpdc/ntpdc_ops.c:1.1.1.12 Wed Feb 2 18:17:35 1994
+--- xntpdc/ntpdc_ops.c Wed Feb 2 18:17:36 1994
+***************
+*** 846,853 ****
+ if (!check1item(items, fp))
+ return;
+
+! if (!checkitemsize(itemsize, sizeof(struct info_sys_stats)))
+ return;
+
+ (void) fprintf(fp, "system uptime: %d\n",
+ ntohl(ss->timeup));
+--- 846,857 ----
+ if (!check1item(items, fp))
+ return;
+
+! if (itemsize != sizeof(struct info_sys_stats) &&
+! itemsize != sizeof(struct old_info_sys_stats)) {
+! /* issue warning according to new structure size */
+! checkitemsize(itemsize, sizeof(struct info_sys_stats));
+ return;
++ }
+
+ (void) fprintf(fp, "system uptime: %d\n",
+ ntohl(ss->timeup));
+***************
+*** 869,874 ****
+--- 873,883 ----
+ ntohl(ss->badauth));
+ (void) fprintf(fp, "wander hold downs: %d\n",
+ ntohl(ss->wanderhold));
++ if (itemsize != sizeof(struct info_sys_stats))
++ return;
++
++ (void) fprintf(fp, "limitation rejects: %d\n",
++ ntohl(ss->limitrejected));
+ }
+
+
+***************
+*** 1243,1248 ****
+--- 1252,1258 ----
+ { "nopeer", RES_NOPEER },
+ { "notrap", RES_NOTRAP },
+ { "lptrap", RES_LPTRAP },
++ { "limited", RES_LIMITED },
+ { "", 0 }
+ };
+
+***************
+*** 1463,1468 ****
+--- 1473,1479 ----
+ FILE *fp;
+ {
+ struct info_monitor *ml;
++ struct old_info_monitor *oml;
+ int items;
+ int itemsize;
+ int res;
+***************
+*** 1476,1498 ****
+ if (!checkitems(items, fp))
+ return;
+
+! if (!checkitemsize(itemsize, sizeof(struct info_monitor)))
+! return;
+
+! (void) fprintf(fp,
+! " address port count mode version lasttime firsttime\n");
+! (void) fprintf(fp,
+! "=====================================================================\n");
+! while (items > 0) {
+! (void) fprintf(fp, "%-20.20s %5d %9d %4d %3d %9u %9u\n",
+! nntohost(ml->addr),
+! ntohs(ml->port),
+! ntohl(ml->count),
+! ml->mode, ml->version,
+! ntohl(ml->lasttime),
+! ntohl(ml->firsttime));
+! ml++;
+! items--;
+ }
+ }
+
+--- 1487,1535 ----
+ if (!checkitems(items, fp))
+ return;
+
+! if (itemsize == sizeof(struct info_monitor)) {
+
+! (void) fprintf(fp,
+! " address port count mode version lastdrop lasttime firsttime\n");
+! (void) fprintf(fp,
+! "===============================================================================\n");
+! while (items > 0) {
+! (void) fprintf(fp, "%-20.20s %5d %9d %4d %3d %9u %9u %9u\n",
+! nntohost(ml->addr),
+! ntohs(ml->port),
+! ntohl(ml->count),
+! ml->mode,
+! ml->version,
+! ntohl(ml->lastdrop),
+! ntohl(ml->lasttime),
+! ntohl(ml->firsttime));
+! ml++;
+! items--;
+! }
+! } else {
+! if (itemsize != sizeof(struct old_info_monitor)) {
+! /* issue warning according to new info_monitor size */
+! checkitemsize(itemsize, sizeof(struct info_monitor));
+! return;
+! }
+!
+! oml = (struct old_info_monitor *)ml;
+! (void) fprintf(fp,
+! " address port count mode version lasttime firsttime\n");
+! (void) fprintf(fp,
+! "======================================================================\n");
+! while (items > 0) {
+! (void) fprintf(fp, "%-20.20s %5d %9d %4d %3d %9u %9u\n",
+! nntohost(oml->addr),
+! ntohs(oml->port),
+! ntohl(oml->count),
+! oml->mode,
+! oml->version,
+! ntohl(oml->lasttime),
+! ntohl(oml->firsttime));
+! oml++;
+! items--;
+! }
+ }
+ }
+
OpenPOWER on IntegriCloud