diff options
author | hrs <hrs@FreeBSD.org> | 2013-08-05 20:13:02 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2013-08-05 20:13:02 +0000 |
commit | 13c1bcf2c1d5fbdca99cdddec726f822b68dddbc (patch) | |
tree | c3af796aa3d9d6e1a9fa48bdec823e34beac7892 /usr.sbin/ndp | |
parent | 103825c951713677489b0556d7cd86852ec2969c (diff) | |
download | FreeBSD-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.c | 76 |
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 |