summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ndp
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2013-08-05 20:13:02 +0000
committerhrs <hrs@FreeBSD.org>2013-08-05 20:13:02 +0000
commit13c1bcf2c1d5fbdca99cdddec726f822b68dddbc (patch)
treec3af796aa3d9d6e1a9fa48bdec823e34beac7892 /usr.sbin/ndp
parent103825c951713677489b0556d7cd86852ec2969c (diff)
downloadFreeBSD-src-13c1bcf2c1d5fbdca99cdddec726f822b68dddbc.zip
FreeBSD-src-13c1bcf2c1d5fbdca99cdddec726f822b68dddbc.tar.gz
- Use time_uptime instead of time_second in data structures for
PF_INET6 in kernel. This fixes various malfunction when the wall time clock is changed. Bump __FreeBSD_version to 1000041. - Use clock_gettime(CLOCK_MONOTONIC_FAST) in userland utilities. MFC after: 1 month
Diffstat (limited to 'usr.sbin/ndp')
-rw-r--r--usr.sbin/ndp/ndp.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index 0449c12..ae1fbca 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -79,7 +79,6 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
-#include <sys/time.h>
#include <sys/queue.h>
#include <net/if.h>
@@ -105,6 +104,7 @@
#include <paths.h>
#include <err.h>
#include <stdlib.h>
+#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include "gmt2local.h"
@@ -125,6 +125,7 @@ static int tflag;
static int32_t thiszone; /* time difference with gmt */
static int s = -1;
static int repeat = 0;
+static struct timespec ts, ts0;
char ntop_buf[INET6_ADDRSTRLEN]; /* inet_ntop() */
char host_buf[NI_MAXHOST]; /* getnameinfo() */
@@ -153,7 +154,7 @@ static void getdefif(void);
static void setdefif(char *);
#endif
static char *sec2str(time_t);
-static void ts_print(const struct timeval *);
+static void ts_print(const struct timespec *);
#ifdef ICMPV6CTL_ND6_DRLIST
static char *rtpref_str[] = {
@@ -164,6 +165,16 @@ static char *rtpref_str[] = {
};
#endif
+#define TS_SUB(tsp, usp, vsp) \
+ do { \
+ (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
+ (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
+ if ((vsp)->tv_nsec < 0) { \
+ (vsp)->tv_sec--; \
+ (vsp)->tv_nsec += 1000000000L; \
+ } \
+ } while (0)
+
int mode = 0;
char *arg = NULL;
@@ -172,10 +183,14 @@ main(argc, argv)
int argc;
char **argv;
{
+ struct timespec now;
int ch;
pid = getpid();
thiszone = gmt2local(0);
+ clock_gettime(CLOCK_REALTIME_FAST, &now);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
+ TS_SUB(&now, &ts, &ts0);
while ((ch = getopt(argc, argv, "acd:f:Ii:nprstA:HPR")) != -1)
switch (ch) {
case 'a':
@@ -367,7 +382,8 @@ getsocket()
struct sockaddr_in6 so_mask = {sizeof(so_mask), AF_INET6 };
struct sockaddr_in6 blank_sin = {sizeof(blank_sin), AF_INET6 }, sin_m;
struct sockaddr_dl blank_sdl = {sizeof(blank_sdl), AF_LINK }, sdl_m;
-int expire_time, flags, found_entry;
+static time_t expire_time;
+static int flags, found_entry;
struct {
struct rt_msghdr m_rtm;
char m_space[512];
@@ -412,10 +428,10 @@ set(argc, argv)
flags = expire_time = 0;
while (argc-- > 0) {
if (strncmp(argv[0], "temp", 4) == 0) {
- struct timeval time;
+ struct timespec now;
- gettimeofday(&time, 0);
- expire_time = time.tv_sec + 20 * 60;
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
+ expire_time = now.tv_sec + 20 * 60;
} else if (strncmp(argv[0], "proxy", 5) == 0)
flags |= RTF_ANNOUNCE;
argv++;
@@ -566,7 +582,7 @@ dump(addr, cflag)
struct sockaddr_dl *sdl;
extern int h_errno;
struct in6_nbrinfo *nbi;
- struct timeval time;
+ struct timespec now;
int addrwidth;
int llwidth;
int ifwidth;
@@ -653,9 +669,9 @@ again:;
#endif
continue;
}
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
if (tflag)
- ts_print(&time);
+ ts_print(&now);
addrwidth = strlen(host_buf);
if (addrwidth < W_ADDR)
@@ -676,9 +692,9 @@ again:;
/* Print neighbor discovery specific informations */
nbi = getnbrinfo(&sin->sin6_addr, sdl->sdl_index, 1);
if (nbi) {
- if (nbi->expire > time.tv_sec) {
+ if (nbi->expire > now.tv_sec) {
printf(" %-9.9s",
- sec2str(nbi->expire - time.tv_sec));
+ sec2str(nbi->expire - now.tv_sec));
} else if (nbi->expire == 0)
printf(" %-9.9s", "permanent");
else
@@ -1075,7 +1091,7 @@ rtrlist()
char *buf;
struct in6_defrouter *p, *ep;
size_t l;
- struct timeval time;
+ struct timespec now;
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0) {
err(1, "sysctl(ICMPV6CTL_ND6_DRLIST)");
@@ -1110,18 +1126,18 @@ rtrlist()
rtpref = ((p->flags & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff;
printf(", pref=%s", rtpref_str[rtpref]);
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
if (p->expire == 0)
printf(", expire=Never\n");
else
printf(", expire=%s\n",
- sec2str(p->expire - time.tv_sec));
+ sec2str(p->expire - now.tv_sec));
}
free(buf);
#else
struct in6_drlist dr;
int s, i;
- struct timeval time;
+ struct timespec now;
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
err(1, "socket");
@@ -1150,12 +1166,12 @@ rtrlist()
printf(", flags=%s%s",
DR.flags & ND_RA_FLAG_MANAGED ? "M" : "",
DR.flags & ND_RA_FLAG_OTHER ? "O" : "");
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
if (DR.expire == 0)
printf(", expire=Never\n");
else
printf(", expire=%s\n",
- sec2str(DR.expire - time.tv_sec));
+ sec2str(DR.expire - now.tv_sec));
}
#undef DR
close(s);
@@ -1171,7 +1187,7 @@ plist()
struct in6_prefix *p, *ep, *n;
struct sockaddr_in6 *advrtr;
size_t l;
- struct timeval time;
+ struct timespec now;
const int niflags = NI_NUMERICHOST;
int ninflags = nflag ? NI_NUMERICHOST : 0;
char namebuf[NI_MAXHOST];
@@ -1202,7 +1218,7 @@ plist()
printf("%s/%d if=%s\n", namebuf, p->prefixlen,
if_indextoname(p->if_index, ifix_buf));
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
/*
* meaning of fields, especially flags, is very different
* by origin. notify the difference to the users.
@@ -1228,9 +1244,9 @@ plist()
printf(", pltime=%lu", (unsigned long)p->pltime);
if (p->expire == 0)
printf(", expire=Never");
- else if (p->expire >= time.tv_sec)
+ else if (p->expire >= now.tv_sec)
printf(", expire=%s",
- sec2str(p->expire - time.tv_sec));
+ sec2str(p->expire - now.tv_sec));
else
printf(", expired");
printf(", ref=%d", p->refcnt);
@@ -1278,9 +1294,9 @@ plist()
#else
struct in6_prlist pr;
int s, i;
- struct timeval time;
+ struct timespec now;
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
err(1, "socket");
@@ -1316,7 +1332,7 @@ plist()
printf("%s/%d if=%s\n", namebuf, PR.prefixlen,
if_indextoname(PR.if_index, ifix_buf));
- gettimeofday(&time, 0);
+ clock_gettime(CLOCK_MONOTONIC_FAST, &now);
/*
* meaning of fields, especially flags, is very different
* by origin. notify the difference to the users.
@@ -1352,9 +1368,9 @@ plist()
printf(", pltime=%lu", PR.pltime);
if (PR.expire == 0)
printf(", expire=Never");
- else if (PR.expire >= time.tv_sec)
+ else if (PR.expire >= now.tv_sec)
printf(", expire=%s",
- sec2str(PR.expire - time.tv_sec));
+ sec2str(PR.expire - now.tv_sec));
else
printf(", expired");
#ifdef NDPRF_ONLINK
@@ -1577,15 +1593,15 @@ sec2str(total)
* from tcpdump/util.c
*/
static void
-ts_print(tvp)
- const struct timeval *tvp;
+ts_print(tsp)
+ const struct timespec *tsp;
{
int s;
/* Default */
- s = (tvp->tv_sec + thiszone) % 86400;
+ s = (tsp->tv_sec + thiszone + ts0.tv_sec) % 86400;
(void)printf("%02d:%02d:%02d.%06u ",
- s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
+ s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tsp->tv_nsec / 1000);
}
#undef NEXTADDR
OpenPOWER on IntegriCloud