Skip to content
Commits on Source (4)
......@@ -52,8 +52,6 @@ below:
|*ntp_config.c* | This file contains the major chunk of the configuration code. It contains all the functions that are called for building the AST as well as the functions that are needed for traversing the AST.
| *ntp_config.h* | This file is the header file for *ntp_config.c*. It mainly contains the structure definitions needed to build the AST.
| *ntp_scanner.c* | This file contains the code for a simple lexical analyzer. This file is directly included into the *ntp_config.c* file since this code is only used by the configuration code. The most important function in this file is +yylex+, which is called by the generated parser to get the next token on the input line.
| *ntp_data_structures.c* | This file contains a generic implementation of a priority queue and a simple queue. This code can be used to create a queue for any structure.
| *ntp_data_structures.h* | This header file contains the structure declarations and function prototypes needed to use the data structures defined in *ntp_data_structures.c* This file forms the public interface of the data structures.
| *ntp_config.tab.c* | This file is generated by Bison from the *ntp_config.y* file. This file is also included directly into the configuration code.
|==============================================================================
......@@ -102,53 +100,14 @@ lexeme; +yylex+ then checks whether this lexeme is an integer, a
double, an IP address or a reserved word. If yes, the corresponding
token is returned. If not, a token for a string is returned as the
default token.
+
+struct state *create_keyword_scanner(struct key_tok *keyword_list)+::
This function takes a list of (_keyword, token_) pairs and converts
them into a tree that can recognize the keywords (reserved words).
Every time the scanner reads a lexeme, it compares it against the list
of reserved words. If it finds a match, it returns the corresponding
token for that keyword.
*ntp_data_structures.c*::
This file contains an implementation of a generic priority queue and
FIFO queue. By generic, we mean that these queues can hold element of
any type (integers, user-defined structs, etc.), provided that these
elements are allocated on the heap using the function +void+
*+get_node(size_t size)+. Note that the prototype for this function is
exactly the same as that of +malloc+ and that it can be used in the
exact same way. Behind the scenes, +get_node+ calls +malloc+ to
allocate _size_ plus some extra memory needed for bookkeeping. The
allocated memory can be freed using the function
+void free_node (void *my_node)+. In addition to these two functions,
the public interface of this file contains the following functions:
+queue *create_priority_queue(int (*get_order)(void *, void*))+::
This function creates a priority queue in which the order of the
elements is determined by the +get_order+ function that is passed
as input to the priority queue. The +get_order+ function should
return positive if the priority of the first element is less than the
priority of the second element.
+queue *create_queue(void)+::
This function creates a FIFO queue. It basically calls the
+create_priority_queue+ function with the +get_fifo_order+ function
as its argument.
+void destroy_queue(queue *my_queue)+::
This function deletes _my_queue_ and frees up all the memory
allocated to it an its elements.
+int empty(queue *my_queue)+::
This function checks to see if _my_queue_ is empty. Returns +true+
if _my_queue_ does not have any elements, else it returns +false+.
+queue *enqueue(queue *my_queue, void *my_node)+::
This function adds an element, _my_node_, to a queue, _my_queue_.
_my_node_ must be allocated on the heap using the +get_node+
function instead of +malloc+.
+void *dequeue(queue *my_queue)+::
This function returns the element at the front of the queue. This
element will be ithe element with the highest priority.
+int get_no_of_elements(queue *my_queue)+::
This function returns the number of elements in _my_queue_.
+void append_queue(queue *q1, queue *q2)+::
This function adds all the elements of +q2+ to +q1+. The queue +q2+ is
destroyed in the process.
*ntp_config.y*::
This file is structured as a standard Bison file and consists of three
main parts, separated by +%%+:
......
docs/pic/description.jpg

33.4 KiB | W: | H:

docs/pic/description.jpg

26.6 KiB | W: | H:

docs/pic/description.jpg
docs/pic/description.jpg
docs/pic/description.jpg
docs/pic/description.jpg
  • 2-up
  • Swipe
  • Onion skin
......@@ -449,7 +449,7 @@ ntp_monitor(
mon_getmoremem();
UNLINK_HEAD_SLIST(mon, mon_free, hash_next);
/* Preempt from the MRU list if old enough. */
} else if (intercept_ntp_random(__func__) / (2. * FRAC) >
} else if (ntp_random() / (2.0 * FRAC) >
(double)oldest_age / mon_age) {
return ~(RES_LIMITED | RES_KOD) & flags;
} else {
......
......@@ -55,16 +55,9 @@ def build(ctx):
libntpd_source = [
"ntp_control.c",
"ntp_filegen.c",
"ntp_intercept.c",
"ntp_leapsec.c",
"ntp_loopfilter.c",
"ntp_monitor.c",
"ntp_peer.c",
"ntp_proto.c",
"ntp_monitor.c", # Needed by the restrict code
"ntp_restrict.c",
"ntp_sandbox.c",
"ntp_signd.c",
"ntp_timer.c",
"ntp_util.c",
]
......@@ -109,7 +102,14 @@ def build(ctx):
ntpd_source = [
"ntp_config.c",
"ntp_io.c",
"ntp_intercept.c",
"ntp_loopfilter.c",
"ntp_peer.c",
"ntp_proto.c",
"ntp_sandbox.c",
"ntp_scanner.c",
"ntp_signd.c",
"ntp_timer.c",
"ntpd.c",
ctx.bldnode.parent.find_node("host/ntpd/ntp_parser.tab.c") if not ctx.env.NTPS_RELEASE else "ntp_parser.tab.c"
]
......
......@@ -56,6 +56,7 @@ static void RunAllTests(void)
RUN_TEST_GROUP(numtohost);
RUN_TEST_GROUP(prettydate);
RUN_TEST_GROUP(recvbuff);
RUN_TEST_GROUP(refidsmear);
RUN_TEST_GROUP(sfptostr);
RUN_TEST_GROUP(socktoa);
RUN_TEST_GROUP(ssl_init);
......@@ -71,6 +72,7 @@ static void RunAllTests(void)
#ifdef TEST_NTPD
RUN_TEST_GROUP(leapsec);
RUN_TEST_GROUP(hackrestrict);
#endif
}
......
......@@ -26,32 +26,10 @@ TEST_TEAR_DOWN(lfpfunc) {}
TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf"); \
}
typedef struct {
uint32_t h, l;
} lfp_hl;
int l_fp_scmp(const l_fp first, const l_fp second);
int l_fp_ucmp(const l_fp first, l_fp second);
l_fp l_fp_init(int32_t i, uint32_t f);
l_fp l_fp_add(const l_fp first, const l_fp second);
l_fp l_fp_subtract(const l_fp first, const l_fp second);
l_fp l_fp_negate(const l_fp first);
l_fp l_fp_abs(const l_fp first);
int l_fp_signum(const l_fp first);
double l_fp_convert_to_double(const l_fp first);
l_fp l_fp_init_from_double( double rhs);
void l_fp_swap(l_fp * first, l_fp *second);
bool l_isgt(const l_fp first, const l_fp second);
bool l_isgtu(const l_fp first, const l_fp second);
bool l_ishis(const l_fp first, const l_fp second);
bool l_isgeq(const l_fp first, const l_fp second);
bool l_isequ(const l_fp first, const l_fp second);
double eps(double d);
static int cmp_work(uint32_t a[3], uint32_t b[3]);
//----------------------------------------------------------------------
// reference comparision
// This is implementad as a full signed MP-subtract in 3 limbs, where
......@@ -59,8 +37,20 @@ static int cmp_work(uint32_t a[3], uint32_t b[3]);
// executed.
//----------------------------------------------------------------------
int
l_fp_scmp(const l_fp first, const l_fp second)
// maybe rename it to lf_cmp_work
static int cmp_work(uint32_t a[3], uint32_t b[3])
{
uint32_t cy, idx, tmp;
for (cy = idx = 0; idx < 3; ++idx) {
tmp = a[idx]; cy = (a[idx] -= cy ) > tmp;
tmp = a[idx]; cy |= (a[idx] -= b[idx]) > tmp;
}
if (a[2])
return -1;
return a[0] || a[1];
}
static int l_fp_scmp(const l_fp first, const l_fp second)
{
uint32_t a[3], b[3];
......@@ -76,8 +66,7 @@ l_fp_scmp(const l_fp first, const l_fp second)
return cmp_work(a,b);
}
int
l_fp_ucmp(const l_fp first, l_fp second)
static int l_fp_ucmp(const l_fp first, l_fp second)
{
uint32_t a[3], b[3];
const l_fp op1 = first;
......@@ -89,28 +78,12 @@ l_fp_ucmp(const l_fp first, l_fp second)
return cmp_work(a,b);
}
// maybe rename it to lf_cmp_work
int
cmp_work(uint32_t a[3], uint32_t b[3])
{
uint32_t cy, idx, tmp;
for (cy = idx = 0; idx < 3; ++idx) {
tmp = a[idx]; cy = (a[idx] -= cy ) > tmp;
tmp = a[idx]; cy |= (a[idx] -= b[idx]) > tmp;
}
if (a[2])
return -1;
return a[0] || a[1];
}
//----------------------------------------------------------------------
// imlementation of the LFP stuff
// This should be easy enough...
//----------------------------------------------------------------------
l_fp
l_fp_init(int32_t i, uint32_t f)
static l_fp l_fp_init(int32_t i, uint32_t f)
{
l_fp temp;
temp.l_i = i;
......@@ -119,8 +92,7 @@ l_fp_init(int32_t i, uint32_t f)
return temp;
}
l_fp
l_fp_add(const l_fp first, const l_fp second)
static l_fp l_fp_add(const l_fp first, const l_fp second)
{
l_fp temp = first;
L_ADD(&temp, &second);
......@@ -128,8 +100,7 @@ l_fp_add(const l_fp first, const l_fp second)
return temp;
}
l_fp
l_fp_subtract(const l_fp first, const l_fp second)
static l_fp l_fp_subtract(const l_fp first, const l_fp second)
{
l_fp temp = first;
L_SUB(&temp, &second);
......@@ -137,8 +108,7 @@ l_fp_subtract(const l_fp first, const l_fp second)
return temp;
}
l_fp
l_fp_negate(const l_fp first)
static l_fp l_fp_negate(const l_fp first)
{
l_fp temp = first;
L_NEG(&temp);
......@@ -146,8 +116,7 @@ l_fp_negate(const l_fp first)
return temp;
}
l_fp
l_fp_abs(const l_fp first)
static l_fp l_fp_abs(const l_fp first)
{
l_fp temp = first;
if (L_ISNEG(&temp))
......@@ -155,32 +124,28 @@ l_fp_abs(const l_fp first)
return temp;
}
int
l_fp_signum(const l_fp first)
static int l_fp_signum(const l_fp first)
{
if (first.l_ui & 0x80000000u)
return -1;
return (first.l_ui || first.l_uf);
}
double
l_fp_convert_to_double(const l_fp first)
static double l_fp_convert_to_double(const l_fp first)
{
double res;
LFPTOD(&first, res);
return res;
}
l_fp
l_fp_init_from_double( double rhs)
static l_fp l_fp_init_from_double( double rhs)
{
l_fp temp;
DTOLFP(rhs, &temp);
return temp;
}
void
l_fp_swap(l_fp * first, l_fp *second)
static void l_fp_swap(l_fp * first, l_fp *second)
{
l_fp temp = *second;
......@@ -197,38 +162,28 @@ l_fp_swap(l_fp * first, l_fp *second)
//----------------------------------------------------------------------
bool
l_isgt (const l_fp first, const l_fp second)
static bool l_isgt (const l_fp first, const l_fp second)
{
return L_ISGT(&first, &second);
}
bool
l_isgtu(const l_fp first, const l_fp second)
static bool l_isgtu(const l_fp first, const l_fp second)
{
return L_ISGTU(&first, &second);
}
bool
l_ishis(const l_fp first, const l_fp second)
static bool l_ishis(const l_fp first, const l_fp second)
{
return L_ISHIS(&first, &second);
}
bool
l_isgeq(const l_fp first, const l_fp second)
static bool l_isgeq(const l_fp first, const l_fp second)
{
return L_ISGEQ(&first, &second);
}
bool
l_isequ(const l_fp first, const l_fp second)
static bool l_isequ(const l_fp first, const l_fp second)
{
return L_ISEQU(&first, &second);
}
......
#include "config.h"
#include <ntp.h>
#include <ntp_fp.h>
#include <refidsmear.h>
#include "unity.h"
#include "unity_fixture.h"
#include <stdio.h>
TEST_GROUP(refidsmear);
TEST_SETUP(refidsmear) {init_lib();}
TEST_TEAR_DOWN(refidsmear) {}
/*
* we want to test a refid format of:
* 254.x.y.x
*
* where x.y.z are 24 bits containing 2 (signed) integer bits
* and 22 fractional bits.
*
* we want functions to convert to/from this format, with unit tests.
*
* Interesting test cases include:
* 254.0.0.0
* 254.0.0.1
* 254.127.255.255
* 254.128.0.0
* 254.255.255.255
*/
static void
rtol(uint32_t r, char *es)
{
l_fp l;
char *as;
char msg[100];
TEST_ASSERT_NOT_NULL(es);
snprintf(msg, 100, "rtol was called with r=%#.8x, es=%s", r, es);
l = convertRefIDToLFP(htonl(r));
as = lfptoa(&l, 8);
//printf("refid %#x, smear %s\n", r, as);
TEST_ASSERT_NOT_NULL_MESSAGE(as, msg);
TEST_ASSERT_EQUAL_STRING_MESSAGE(es, as, msg);
return;
}
static void
rtoltor(uint32_t er, char *es)
{
l_fp l;
char *as;
uint32_t ar;
char msg[100];
TEST_ASSERT_NOT_NULL(es);
snprintf(msg, 100, "rtoltor was called with er=%#.8x, es=%s", er, es);
l = convertRefIDToLFP(htonl(er));
as = lfptoa(&l, 8);
ar = convertLFPToRefID(l);
//printf("smear %s, refid %#.8x\n", lfptoa(&l, 8), ntohl(ar));
TEST_ASSERT_NOT_NULL_MESSAGE(as, msg);
TEST_ASSERT_EQUAL_STRING_MESSAGE(es, as, msg);
TEST_ASSERT_EQUAL_UINT_MESSAGE(er, ntohl(ar), msg);
return;
}
TEST(refidsmear, Main)
{
rtol(0xfe800000, "-2.00000000");
rtol(0xfe800001, "-1.99999976");
rtol(0xfe8ffffe, "-1.75000048");
rtol(0xfe8fffff, "-1.75000024");
rtol(0xfef00000, "-0.25000000");
rtol(0xfef00001, "-0.24999976");
rtol(0xfefffffe, "-0.00000048");
rtol(0xfeffffff, "-0.00000024");
rtol(0xfe000000, "0.00000000");
rtol(0xfe000001, "0.00000024");
rtol(0xfe6ffffe, "1.74999952");
rtol(0xfe6fffff, "1.74999976");
rtol(0xfe700000, "1.75000000");
rtol(0xfe700001, "1.75000024");
rtol(0xfe7ffffe, "1.99999952");
rtol(0xfe7fffff, "1.99999976");
rtoltor(0xfe800000, "-2.00000000");
rtoltor(0xfe800001, "-1.99999976");
rtoltor(0xfe8ffffe, "-1.75000048");
rtoltor(0xfe8fffff, "-1.75000024");
rtoltor(0xfef00000, "-0.25000000");
rtoltor(0xfef00001, "-0.24999976");
rtoltor(0xfefffffe, "-0.00000048");
rtoltor(0xfeffffff, "-0.00000024");
rtoltor(0xfe000000, "0.00000000");
rtoltor(0xfe000001, "0.00000024");
rtoltor(0xfe6ffffe, "1.74999952");
rtoltor(0xfe6fffff, "1.74999976");
rtoltor(0xfe700000, "1.75000000");
rtoltor(0xfe700001, "1.75000024");
rtoltor(0xfe7ffffe, "1.99999952");
rtoltor(0xfe7fffff, "1.99999976");
return;
}
TEST_GROUP_RUNNER(refidsmear) {
RUN_TEST_CASE(refidsmear, Main);
}
#include "config.h"
#include "ntpd.h"
#include "ntp_lists.h"
#include "unity.h"
#include "unity_fixture.h"
/* Helper functions */
static sockaddr_u
create_sockaddr_u(unsigned short sin_port, char* ip_addr)
{
sockaddr_u sockaddr;
sockaddr.sa4.sin_family = AF_INET;
sockaddr.sa4.sin_port = htons(sin_port);
memset(sockaddr.sa4.sin_zero, 0, 8);
sockaddr.sa4.sin_addr.s_addr = inet_addr(ip_addr);
return sockaddr;
}
TEST_GROUP(hackrestrict);
TEST_SETUP(hackrestrict) {
init_restrict();
}
u_long current_time; /* not used - restruct code needs it */
TEST_TEAR_DOWN(hackrestrict) {
restrict_u *empty_restrict = malloc(sizeof(restrict_u));
memset(empty_restrict, 0, sizeof(restrict_u));
restrict_u *current;
do {
UNLINK_HEAD_SLIST(current, restrictlist4, link);
if (current != NULL)
{
*current = *empty_restrict;
}
} while (current != NULL);
do {
UNLINK_HEAD_SLIST(current, restrictlist6, link);
if (current != NULL)
{
*current = *empty_restrict;
}
} while (current != NULL);
free(empty_restrict);
}
/* Tests */
TEST(hackrestrict, RestrictionsAreEmptyAfterInit) {
restrict_u *rl4 = malloc(sizeof(restrict_u));
restrict_u *rl6 = malloc(sizeof(restrict_u));
memset(rl4, 0, sizeof(restrict_u));
memset(rl6, 0, sizeof(restrict_u));
TEST_ASSERT_EQUAL(rl4->count, restrictlist4->count);
TEST_ASSERT_EQUAL(rl4->flags, restrictlist4->flags);
TEST_ASSERT_EQUAL(rl4->mflags, restrictlist4->mflags);
TEST_ASSERT_EQUAL(rl4->expire, restrictlist4->expire);
TEST_ASSERT_EQUAL(rl4->u.v4.addr, restrictlist4->u.v4.addr);
TEST_ASSERT_EQUAL(rl4->u.v4.mask, restrictlist4->u.v4.mask);
TEST_ASSERT_EQUAL(rl6->count, restrictlist6->count);
TEST_ASSERT_EQUAL(rl6->flags, restrictlist6->flags);
TEST_ASSERT_EQUAL(rl6->mflags, restrictlist6->mflags);
TEST_ASSERT_EQUAL(rl6->expire, restrictlist6->expire);
free(rl4);
free(rl6);
}
TEST(hackrestrict, ReturnsCorrectDefaultRestrictions) {
sockaddr_u sockaddr = create_sockaddr_u(54321, "63.161.169.137");
u_short retval = restrictions(&sockaddr);
TEST_ASSERT_EQUAL(0, retval);
}
TEST(hackrestrict, HackingDefaultRestriction) {
/*
* We change the flag of the default restriction,
* and check if restriction() returns that flag
*/
const u_short flags = 42;
sockaddr_u resaddr = create_sockaddr_u(54321, "0.0.0.0");
sockaddr_u resmask = create_sockaddr_u(54321, "0.0.0.0");
hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, flags, 0);
sockaddr_u sockaddr = create_sockaddr_u(54321, "111.123.251.124");
TEST_ASSERT_EQUAL(flags, restrictions(&sockaddr));
}
TEST(hackrestrict, CantRemoveDefaultEntry) {
sockaddr_u resaddr = create_sockaddr_u(54321, "0.0.0.0");
sockaddr_u resmask = create_sockaddr_u(54321, "0.0.0.0");
hack_restrict(RESTRICT_REMOVE, &resaddr, &resmask, 0, 0, 0);
TEST_ASSERT_EQUAL(0, restrictions(&resaddr));
}
TEST(hackrestrict, AddingNewRestriction) {
sockaddr_u resaddr = create_sockaddr_u(54321, "11.22.33.44");
sockaddr_u resmask = create_sockaddr_u(54321, "128.0.0.0");
const u_short flags = 42;
hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, flags, 0);
TEST_ASSERT_EQUAL(flags, restrictions(&resaddr));
}
TEST(hackrestrict, TheMostFittingRestrictionIsMatched) {
sockaddr_u resaddr_target = create_sockaddr_u(54321, "11.22.33.44");
sockaddr_u resaddr_not_matching = create_sockaddr_u(54321, "11.99.33.44");
sockaddr_u resmask_not_matching = create_sockaddr_u(54321, "255.255.0.0");
sockaddr_u resaddr_best_match = create_sockaddr_u(54321, "11.22.30.20");
sockaddr_u resmask_best_match = create_sockaddr_u(54321, "255.255.0.0");
/* it also matches, but we prefer the one above, as it's more specific */
sockaddr_u resaddr_second_match = create_sockaddr_u(54321, "11.99.33.44");
sockaddr_u resmask_second_match = create_sockaddr_u(54321, "255.0.0.0");
hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, 0, 11, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, 0, 22, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_second_match, &resmask_second_match, 0, 128, 0);
TEST_ASSERT_EQUAL(22, restrictions(&resaddr_target));
}
TEST(hackrestrict, DeletedRestrictionIsNotMatched) {
sockaddr_u resaddr_target = create_sockaddr_u(54321, "11.22.33.44");
sockaddr_u resaddr_not_matching = create_sockaddr_u(54321, "11.99.33.44");
sockaddr_u resmask_not_matching = create_sockaddr_u(54321, "255.255.0.0");
sockaddr_u resaddr_best_match = create_sockaddr_u(54321, "11.22.30.20");
sockaddr_u resmask_best_match = create_sockaddr_u(54321, "255.255.0.0");
sockaddr_u resaddr_second_match = create_sockaddr_u(54321, "11.99.33.44");
sockaddr_u resmask_second_match = create_sockaddr_u(54321, "255.0.0.0");
hack_restrict(RESTRICT_FLAGS, &resaddr_not_matching, &resmask_not_matching, 0, 11, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_best_match, &resmask_best_match, 0, 22, 0);
hack_restrict(RESTRICT_FLAGS, &resaddr_second_match, &resmask_second_match, 0, 128, 0);
/* deleting the best match*/
hack_restrict(RESTRICT_REMOVE, &resaddr_best_match, &resmask_best_match, 0, 22, 0);
TEST_ASSERT_EQUAL(128, restrictions(&resaddr_target));
}
TEST(hackrestrict, RestrictUnflagWorks) {
sockaddr_u resaddr = create_sockaddr_u(54321, "11.22.30.20");
sockaddr_u resmask = create_sockaddr_u(54321, "255.255.0.0");
hack_restrict(RESTRICT_FLAGS, &resaddr, &resmask, 0, 11, 0);
hack_restrict(RESTRICT_UNFLAG, &resaddr, &resmask, 0, 10, 0);
TEST_ASSERT_EQUAL(1, restrictions(&resaddr));
}
TEST_GROUP_RUNNER(hackrestrict) {
RUN_TEST_CASE(hackrestrict, RestrictionsAreEmptyAfterInit);
RUN_TEST_CASE(hackrestrict, ReturnsCorrectDefaultRestrictions);
RUN_TEST_CASE(hackrestrict, HackingDefaultRestriction);
RUN_TEST_CASE(hackrestrict, CantRemoveDefaultEntry);
RUN_TEST_CASE(hackrestrict, AddingNewRestriction);
RUN_TEST_CASE(hackrestrict, TheMostFittingRestrictionIsMatched);
RUN_TEST_CASE(hackrestrict, DeletedRestrictionIsNotMatched);
RUN_TEST_CASE(hackrestrict, RestrictUnflagWorks);
}
......@@ -70,6 +70,7 @@ def build(ctx):
"libntp/numtohost.c",
"libntp/prettydate.c",
"libntp/recvbuff.c",
"libntp/refidsmear.c",
"libntp/sfptostr.c",
"libntp/socktoa.c",
"libntp/ssl_init.c",
......@@ -98,7 +99,8 @@ def build(ctx):
)
ntpd_source = [
"ntpd/leapsec.c"
"ntpd/leapsec.c",
"ntpd/restrict.c",
] + common_source
ctx.ntp_test(
......