diff options
Diffstat (limited to 'usr.sbin/xntpd/patches/patch.10')
-rw-r--r-- | usr.sbin/xntpd/patches/patch.10 | 1925 |
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--; +! } + } + } + |