From: Dave Hart Date: Sun, 7 Mar 2010 17:36:49 +0000 (+0000) Subject: ntp_util.c: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=392e5e1fc60592feea96ca5446d7bb43c46d7808;p=thirdparty%2Fntp.git ntp_util.c: whitespace only ntpq-subs.c: split mrulist() into mrulist() and collect_mru_list(). adjust row limit based on success/failure of individual queries for collect_mru_list(). revert to one MRU entry per IP address regardless of port. ntp_monitor.c: correct MRU list preemption logic. revert to one MRU entry per IP address regardless of port. ntp_control.h, ntp_control.c: add "kod_sent" non-default system variable for sys_kodsent. config.h: #undef STRINGIZE after use to avoid accidentally using on Windows without noticing it's specific to Windows port. ntpq.c, ntpq.h: move definitions to ntpq.h needed by mrulist code in ntpq-subs.h. bk: 4b93e431N5hrcLho1Yq8lWTzexOhcg --- diff --git a/include/ntp_control.h b/include/ntp_control.h index be8e88e14a..86ca63ae90 100644 --- a/include/ntp_control.h +++ b/include/ntp_control.h @@ -178,18 +178,20 @@ struct ntp_control { #define CS_MRU_MAXDEPTH 29 #define CS_MRU_MEM 30 #define CS_MRU_MAXMEM 31 +#define CS_KOD_SENT 32 +#define CS_MAX_NOSSL CS_KOD_SENT #ifdef OPENSSL -#define CS_FLAGS 32 -#define CS_HOST 33 -#define CS_PUBLIC 34 -#define CS_CERTIF 35 -#define CS_SIGNATURE 36 -#define CS_REVTIME 37 -#define CS_GROUP 38 -#define CS_DIGEST 39 +#define CS_FLAGS (1 + CS_MAX_NOSSL) +#define CS_HOST (2 + CS_MAX_NOSSL) +#define CS_PUBLIC (3 + CS_MAX_NOSSL) +#define CS_CERTIF (4 + CS_MAX_NOSSL) +#define CS_SIGNATURE (5 + CS_MAX_NOSSL) +#define CS_REVTIME (6 + CS_MAX_NOSSL) +#define CS_GROUP (7 + CS_MAX_NOSSL) +#define CS_DIGEST (8 + CS_MAX_NOSSL) #define CS_MAXCODE CS_DIGEST #else -#define CS_MAXCODE CS_MRU_MAXMEM +#define CS_MAXCODE CS_MAX_NOSSL #endif /* OPENSSL */ /* diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 6e9fe055fd..e0df701520 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -136,17 +136,18 @@ static struct ctl_var sys_var[] = { { CS_MRU_MAXDEPTH, RO, "mru_maxdepth" },/* 29 */ { CS_MRU_MEM, RO, "mru_mem" }, /* 30 */ { CS_MRU_MAXMEM, RO, "mru_maxmem" }, /* 31 */ + { CS_KOD_SENT, RO, "kod_sent" }, /* 32 */ #ifdef OPENSSL - { CS_FLAGS, RO, "flags" }, /* 32 */ - { CS_HOST, RO, "host" }, /* 33 */ - { CS_PUBLIC, RO, "update" }, /* 34 */ - { CS_CERTIF, RO, "cert" }, /* 35 */ - { CS_SIGNATURE, RO, "signature" }, /* 36 */ - { CS_REVTIME, RO, "until" }, /* 37 */ - { CS_GROUP, RO, "group" }, /* 38 */ - { CS_DIGEST, RO, "digest" }, /* 39 */ + { CS_FLAGS, RO, "flags" }, /* 33 */ + { CS_HOST, RO, "host" }, /* 34 */ + { CS_PUBLIC, RO, "update" }, /* 35 */ + { CS_CERTIF, RO, "cert" }, /* 36 */ + { CS_SIGNATURE, RO, "signature" }, /* 37 */ + { CS_REVTIME, RO, "until" }, /* 38 */ + { CS_GROUP, RO, "group" }, /* 39 */ + { CS_DIGEST, RO, "digest" }, /* 40 */ #endif /* OPENSSL */ - { 0, EOV, "" } /* 32/40 */ + { 0, EOV, "" } /* 33/41 */ }; static struct ctl_var *ext_sys_var = (struct ctl_var *)0; @@ -1606,6 +1607,11 @@ ctl_putsys( ctl_putuint(sys_var[varid].text, u); break; + case CS_KOD_SENT: + ctl_putint(sys_var[varid].text, sys_kodsent); + break; + + #ifdef OPENSSL case CS_FLAGS: if (crypto_flags) @@ -2645,7 +2651,14 @@ static void configure( * newer neighbor, fetch the supplied entry, and * in that case the #.last timestamp can be zero. * This enables fetching a single entry by IP - address. + * address. + * mincount= (decimal) return entries with count >= mincount. + * resall= 0x-prefixed hex restrict bits which must all be + * lit for an MRU entry to be included. + * Has precedence over any resany=. + * resany= 0x-prefixed hex restrict bits, at least one of + * which must be list for an MRU entry to be + * included. * 0.last= 0x-prefixed hex l_fp timestamp of newest entry * which client previously received. * 0.addr= text of newest entry's IP address and port, @@ -2701,6 +2714,10 @@ static void read_mru_list( ) { const char limit_text[] = "limit"; + const char mincount_text[] = "mincount"; + const char resall_text[] = "resall"; + const char resany_text[] = "resany"; + const char resaxx_fmt[] = "0x%hx"; const char addr_fmt[] = "addr.%d"; const char last_fmt[] = "last.%d"; const char first_fmt[] = "first.%d"; @@ -2709,6 +2726,9 @@ static void read_mru_list( const char rs_fmt[] = "rs.%d"; const char l_fp_hexfmt[] = "0x%08x.%08x"; u_int limit; + u_short resall; + u_short resany; + int mincount; u_int count; u_int ui; u_int uf; @@ -2724,6 +2744,7 @@ static void read_mru_list( int priors; u_short hash; mon_entry * mon; + mon_entry * prior_mon; l_fp now; /* @@ -2731,6 +2752,9 @@ static void read_mru_list( */ in_parms = NULL; set_var(&in_parms, limit_text, sizeof(limit_text), 0); + set_var(&in_parms, mincount_text, sizeof(mincount_text), 0); + set_var(&in_parms, resall_text, sizeof(resall_text), 0); + set_var(&in_parms, resany_text, sizeof(resany_text), 0); for (i = 0; i < COUNTOF(last); i++) { snprintf(buf, sizeof(buf), last_fmt, i); set_var(&in_parms, buf, strlen(buf) + 1, 0); @@ -2740,6 +2764,9 @@ static void read_mru_list( /* decode input parms */ limit = 0; + mincount = 0; + resall = 0; + resany = 0; priors = 0; memset(last, 0, sizeof(last)); memset(addr, 0, sizeof(addr)); @@ -2748,8 +2775,15 @@ static void read_mru_list( !(EOV & v->flags)) { if (!strcmp(limit_text, v->text)) { - if (1 != sscanf(val, "%u", &limit)) - limit = 0; + sscanf(val, "%u", &limit); + } else if (!strcmp(mincount_text, v->text)) { + if (1 != sscanf(val, "%d", &mincount) || + mincount < 0) + mincount = 0; + } else if (!strcmp(resall_text, v->text)) { + sscanf(val, resaxx_fmt, &resall); + } else if (!strcmp(resany_text, v->text)) { + sscanf(val, resaxx_fmt, &resany); } else if (1 == sscanf(v->text, last_fmt, &i) && i < COUNTOF(last)) { if (2 == sscanf(val, l_fp_hexfmt, &ui, &uf)) { @@ -2809,10 +2843,18 @@ static void read_mru_list( mon = PREV_DLIST(mon_mru_list, mon, mru); } else /* start with the oldest */ mon = TAIL_DLIST(mon_mru_list, mru); - + + prior_mon = NULL; for (count = 0; count < limit && mon != NULL; - count++, mon = PREV_DLIST(mon_mru_list, mon, mru)) { + mon = PREV_DLIST(mon_mru_list, mon, mru)) { + + if (mon->count < mincount) + continue; + if (resall && (resall != (resall & mon->flags))) + continue; + if (resany && !(resany & mon->flags)) + continue; snprintf(tag, sizeof(tag), addr_fmt, count); pch = sptoa(&mon->rmtadr); @@ -2836,20 +2878,23 @@ static void read_mru_list( snprintf(tag, sizeof(tag), rs_fmt, count); ctl_puthex(tag, mon->flags); + + count++; + prior_mon = mon; } /* * If this batch completes the MRU list (has the most recent), * say so explicitly. */ if (NULL == mon) { - mon = HEAD_DLIST(mon_mru_list, mru); - if (mon != NULL) { - get_systime(&now); - snprintf(buf, sizeof(buf), l_fp_hexfmt, - now.l_ui, now.l_uf); - ctl_putunqstr("now", buf, strlen(buf)); + get_systime(&now); + snprintf(buf, sizeof(buf), l_fp_hexfmt, + now.l_ui, now.l_uf); + ctl_putunqstr("now", buf, strlen(buf)); + if (prior_mon != NULL) { snprintf(buf, sizeof(buf), l_fp_hexfmt, - mon->last.l_ui, mon->last.l_uf); + prior_mon->last.l_ui, + prior_mon->last.l_uf); ctl_putunqstr("last.newest", buf, strlen(buf)); } } diff --git a/ntpd/ntp_monitor.c b/ntpd/ntp_monitor.c index 0a554d54f0..1adc4d483e 100644 --- a/ntpd/ntp_monitor.c +++ b/ntpd/ntp_monitor.c @@ -332,8 +332,13 @@ ntp_monitor( version = PKT_VERSION(pkt->li_vn_mode); mon = mon_hash[hash]; + /* + * We keep track of all traffic for a given IP in one entry, + * otherwise cron'ed ntpdate or similar evades RES_LIMITED. + */ + for (; mon != NULL; mon = mon->hash_next) - if (ADDR_PORT_EQ(&mon->rmtadr, &rbufp->recv_srcadr)) + if (SOCK_EQ(&mon->rmtadr, &rbufp->recv_srcadr)) break; if (mon != NULL) { @@ -341,6 +346,7 @@ ntp_monitor( L_SUB(&interval_fp, &mon->last); interval = interval_fp.l_i; mon->last = rbufp->recv_time; + NSRCPORT(&mon->rmtadr) = NSRCPORT(&rbufp->recv_srcadr); mon->count++; restrict_mask = flags; mon->vn_mode = VN_MODE(version, mode); @@ -423,8 +429,9 @@ ntp_monitor( * ntp.conf controls. Similarly for "mru initalloc" and "mru * initmem", and for "mru incalloc" and "mru incmem". */ - if (NULL == mon_free && mru_alloc < mru_mindepth) { - mon_getmoremem(); + if (mru_entries < mru_mindepth) { + if (NULL == mon_free) + mon_getmoremem(); UNLINK_HEAD_SLIST(mon, mon_free, hash_next); } else { oldest = TAIL_DLIST(mon_mru_list, mru); diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index e9faf213c8..505d4168ce 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -766,7 +766,7 @@ record_sys_stats(void) day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (sysstats.fp != NULL) { - fprintf(sysstats.fp, + fprintf(sysstats.fp, "%lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", day, ulfptoa(&now, 3), current_time - sys_stattime, sys_received, sys_processed, sys_newversion, diff --git a/ntpq/ntpq-subs.c b/ntpq/ntpq-subs.c index 8bb9ebde83..e895fe5bc2 100644 --- a/ntpq/ntpq-subs.c +++ b/ntpq/ntpq-subs.c @@ -69,7 +69,6 @@ static void saveconfig (struct parse *, FILE *); static void config_from_file(struct parse *, FILE *); static void mrulist (struct parse *, FILE *); - /* * Commands we understand. Ntpdc imports this. */ @@ -164,9 +163,9 @@ struct xcmd opcmds[] = { { "config-from-file", config_from_file, { NTP_STR, NO, NO, NO }, { "", "", "", "" }, "configure ntpd using the configuration filename" }, - { "mrulist", mrulist, { OPT|NTP_STR, NO, NO, NO }, - { "", "", "", "" }, - "display the list of most recently seen source addresses" }, + { "mrulist", mrulist, { OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR }, + { "tag=value", "", "", "" }, + "display the list of most recently seen source addresses, tags mincount=... resall=0x... resany=0x..." }, { 0, 0, { NO, NO, NO, NO }, { "-4|-6", "", "", "" }, "" } }; @@ -235,7 +234,12 @@ struct mru_tag { }; static mru mru_list; /* listhead */ static mru **hash_table; -static mru * add_mru (mru *); + +/* + * other static function prototypes + */ +static mru * add_mru(mru *); +static int collect_mru_list(const char *, l_fp *); /* @@ -2070,8 +2074,9 @@ config_from_file ( /* - * add_mru add and entry to mru list, hash table, and allocate + * add_mru Add and entry to mru list, hash table, and allocate * and return a replacement. + * This is a helper for collect_mru_list(). */ static mru * add_mru( @@ -2083,6 +2088,14 @@ add_mru( mru *unlinked; int first_ts_matches; + if (debug) + fprintf(stderr, + "add_mru %08x.%08x c %d m %d v %d rest %x first %08x.%08x %s\n", + add->last.l_ui, add->last.l_uf, add->count, + (int)add->mode, (int)add->ver, (u_int)add->rs, + add->first.l_ui, add->first.l_uf, + sptoa(&add->addr)); + hash = NTP_HASH_ADDR(&add->addr); /* see if we have it among previously received entries */ for (mon = hash_table[hash]; mon != NULL; mon = mon->hlink) @@ -2090,7 +2103,15 @@ add_mru( break; if (mon != NULL) { first_ts_matches = L_ISEQU(&add->first, &mon->first); - NTP_INSIST(first_ts_matches); + if (!first_ts_matches) { + fprintf(stderr, + "add_mru duplicate %s first ts mismatch %08x.%08x expected %08x.%08x\n", + sptoa(&add->addr), add->last.l_ui, + add->last.l_uf, mon->last.l_ui, + mon->last.l_uf); + exit(1); + + } UNLINK_DLIST(mon, mlink); UNLINK_SLIST(unlinked, hash_table[hash], mon, hlink, mru); NTP_INSIST(unlinked == mon); @@ -2103,13 +2124,6 @@ add_mru( } LINK_DLIST(mru_list, add, mlink); LINK_SLIST(hash_table[hash], add, hlink); - if (debug) - fprintf(stderr, - "add_mru %08x.%08x c %d m %d v %d rest %x first %08x.%08x %s\n", - add->last.l_ui, add->last.l_uf, add->count, - (int)add->mode, (int)add->ver, (u_int)add->rs, - add->first.l_ui, add->first.l_uf, - sptoa(&add->addr)); if (NULL == mon) mon = emalloc(sizeof(*mon)); memset(mon, 0, sizeof(*mon)); @@ -2117,13 +2131,7 @@ add_mru( } -static void -mrulist( - struct parse *pcmd, - FILE *fp - ) -{ - u_char got; /* MRU_GOT_* bits */ +/* MGOT macro is specific to collect_mru_list() */ #define MGOT(bit) \ do { \ got |= (bit); \ @@ -2133,6 +2141,16 @@ mrulist( ci++; \ } \ } while (0) + + +static int +collect_mru_list( + const char *parms, + l_fp * pnow + ) +{ + int c_mru_l_rc; /* this function's return code */ + u_char got; /* MRU_GOT_* bits */ const char ts_fmt[] = "0x%08x.%08x"; size_t cb; mru *mon; @@ -2155,41 +2173,35 @@ mrulist( int ci; /* client (our) index for validation */ int ri; /* request index (.# suffix) */ int mv; - l_fp now; l_fp newest; l_fp last_older; - l_fp interval; sockaddr_u addr_older; - double favgint; - double flstint; - int avgint; - int lstint; int have_now; int have_addr_older; int have_last_older; u_short hash; mru *unlinked; + c_mru_l_rc = FALSE; list_complete = FALSE; - INIT_DLIST(mru_list, mlink); - cb = NTP_HASH_SIZE * sizeof(*hash_table); - hash_table = emalloc(cb); - memset(hash_table, 0, cb); + have_now = FALSE; + got = 0; + ri = 0; cb = sizeof(*mon); mon = emalloc(cb); memset(mon, 0, cb); - memset(&now, 0, sizeof(now)); + memset(pnow, 0, sizeof(*pnow)); memset(&last_older, 0, sizeof(last_older)); - have_now = FALSE; - got = 0; - ri = 0; limit = 2; - snprintf(req_buf, sizeof(req_buf), "limit=%d", limit); + snprintf(req_buf, sizeof(req_buf), "limit=%d%s", limit, parms); while (TRUE) { if (debug) fprintf(stderr, "READ_MRU: %s\n", req_buf); + // if (debug) !!!!! + fprintf(stderr, "attempting next %d\n", limit); + qres = doqueryex(CTL_OP_READ_MRU, 0, 0, strlen(req_buf), req_buf, &rstatus, &rsize, &rdata, TRUE); @@ -2214,10 +2226,25 @@ mrulist( NTP_INSIST(unlinked == recent); free(recent); } + } else if (ERR_INCOMPLETE == qres) { + /* + * Reduce the number of rows to minimize effect + * of single lost packets. + */ + limit = max(2, limit * 2 / 3); } else if (qres) { show_error_msg(qres, 0); - return; + goto cleanup_return; } + /* + * This is a cheap cop-out implementation of rawmode + * output for mrulist. A better approach would be to + * dump similar output after the list is collected by + * ntpq with a continuous sequence of indexes. This + * cheap approach has indexes resetting to zero for + * each query/response, and duplicates are not + * coalesced. + */ if (!qres && rawmode) printvars(rsize, rdata, rstatus, TYPE_SYS, 1, stdout); ci = 0; @@ -2325,16 +2352,17 @@ mrulist( if (1 != sscanf(tag, "first.%d", &si) || si != ci || 2 != sscanf(val, ts_fmt, - &mon->first.l_ui, - &mon->first.l_uf)) + &mon->first.l_ui, + &mon->first.l_uf)) goto nomatch; MGOT(MRU_GOT_FIRST); break; case 'n': if (strcmp(tag, "now") || - 2 != sscanf(val, ts_fmt, &now.l_ui, - &now.l_uf)) + 2 != sscanf(val, ts_fmt, + &pnow->l_ui, + &pnow->l_uf)) goto nomatch; have_now = TRUE; break; @@ -2372,7 +2400,8 @@ mrulist( /* ignore unknown tags */ } } - + if (have_now) + list_complete = TRUE; if (list_complete) { NTP_INSIST(0 == ri || have_addr_older); break; @@ -2382,6 +2411,14 @@ mrulist( * up with other duties. */ sleep(1); + /* + * If there were no errors, increase the number of rows + * to a maximum of 3 * MAXFRAGS (the most packets ntpq + * can handle in one response), on the assumption that + * no less than 3 rows fit in each packet. + */ + if (!qres) + limit = min(3 * MAXFRAGS, limit * 2); /* * prepare next query with as many address and last-seen * timestamps as will fit in a single packet. @@ -2389,7 +2426,7 @@ mrulist( req = req_buf; req_end = req_buf + sizeof(req_buf); #define REQ_ROOM (req_end - req) - snprintf(req, REQ_ROOM, "limit=%d", limit); + snprintf(req, REQ_ROOM, "limit=%d%s", limit, parms); req += strlen(req); for (ri = 0, recent = HEAD_DLIST(mru_list, mlink); @@ -2410,11 +2447,85 @@ mrulist( NTP_INSIST(ri > 0 || NULL == recent); } + c_mru_l_rc = TRUE; + +cleanup_return: + if (mon != NULL) + free(mon); + + return c_mru_l_rc; +} + + +/* + * mrulist - ntpq's mrulist command to fetch an arbitrarily large Most + * Recently Used (seen) remote address list from ntpd. + * + * Similar to ntpdc's monlist command, but not limited to a single + * request/response, and thereby not limited to a few hundred remote + * addresses. + * + * See ntpd/ntp_control.c read_mru_list() for comments on the way + * CTL_OP_READ_MRU is designed to be used. + */ +static void +mrulist( + struct parse *pcmd, + FILE *fp + ) +{ + const char mincount_eq[] = "mincount="; + const char resall_eq[] = "resall="; + const char resany_eq[] = "resany="; + char parms_buf[128]; + char *parms; + char *arg; + size_t cb; + mru *recent; + l_fp now; + l_fp interval; + double favgint; + double flstint; + int avgint; + int lstint; + int i; + + parms_buf[0] = '\0'; + parms = parms_buf; + for (i = 0; i < pcmd->nargs; i++) { + arg = pcmd->argval[i].string; + if (arg != NULL) { + cb = strlen(arg) + 1; + if ((!strncmp(resall_eq, arg, sizeof(resall_eq) + - 1) || !strncmp(resany_eq, arg, + sizeof(resany_eq) - 1) || !strncmp( + mincount_eq, arg, sizeof(mincount_eq) - 1)) + && parms + cb + 2 <= parms_buf + + sizeof(parms_buf)) { + memcpy(parms, ", ", 2); + parms += 2; + memcpy(parms, arg, cb); + parms += cb - 1; + } else + fprintf(stderr, + "ignoring unrecognized mrulist parameter: %s\n", + arg); + } + } + parms = parms_buf; + + INIT_DLIST(mru_list, mlink); + cb = NTP_HASH_SIZE * sizeof(*hash_table); + hash_table = emalloc(cb); + memset(hash_table, 0, cb); + + if (!collect_mru_list(parms, &now)) + return; + /* display the results */ if (rawmode) goto cleanup_return; - printf( "lstint avgint rstr m v count rport remote address\n" "==============================================================================\n"); /* '-' x 78 */ @@ -2435,8 +2546,6 @@ mrulist( ITER_DLIST_END() cleanup_return: - if (mon != NULL) - free(mon); ITER_DLIST_BEGIN(mru_list, recent, mlink, mru) free(recent); ITER_DLIST_END() diff --git a/ntpq/ntpq.c b/ntpq/ntpq.c index 9eddcde8c0..d2f35c93c4 100644 --- a/ntpq/ntpq.c +++ b/ntpq/ntpq.c @@ -419,7 +419,6 @@ u_short sequence; * Holds data returned from queries. Declare buffer long to be sure of * alignment. */ -#define MAXFRAGS 64 /* maximum number of fragments */ #define DATASIZE (MAXFRAGS*480) /* maximum amount of data */ long pktdata[DATASIZE/sizeof(long)]; @@ -443,14 +442,6 @@ int numhosts = 0; const char *chosts[MAXHOSTS]; #define ADDHOST(cp) if (numhosts < MAXHOSTS) chosts[numhosts++] = (cp) -/* - * Error codes for internal use - */ -#define ERR_UNSPEC 256 -#define ERR_INCOMPLETE 257 -#define ERR_TIMEOUT 258 -#define ERR_TOOMUCH 259 - /* * Macro definitions we use */ @@ -1202,6 +1193,10 @@ getresponse( } if (n == numfrags) { *rsize = offsets[numfrags-1] + counts[numfrags-1]; + if (debug) + fprintf(stderr, + "%d packets reassembled into response\n", + numfrags); return 0; } } diff --git a/ntpq/ntpq.h b/ntpq/ntpq.h index 4c5e69b5cf..e26baba119 100644 --- a/ntpq/ntpq.h +++ b/ntpq/ntpq.h @@ -18,8 +18,18 @@ #define MAXARGS 4 /* - * Flags for forming descriptors. + * Limit on packets in a single response */ +#define MAXFRAGS 64 + +/* + * Error codes for internal use + */ +#define ERR_UNSPEC 256 +#define ERR_INCOMPLETE 257 +#define ERR_TIMEOUT 258 +#define ERR_TOOMUCH 259 + /* * Flags for forming descriptors. */ diff --git a/ports/winnt/include/config.h b/ports/winnt/include/config.h index d49c2f080a..b8ecf1c2b8 100644 --- a/ports/winnt/include/config.h +++ b/ports/winnt/include/config.h @@ -457,6 +457,8 @@ typedef unsigned long uintptr_t; #endif /* !defined(STR_PROCESSOR) */ +#undef STRINGIZE + #define SIOCGIFFLAGS SIO_GET_INTERFACE_LIST /* used in ntp_io.c */ /* * Below this line are includes which must happen after the bulk of