aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-17 19:09:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-17 19:09:05 +0000
commit459be35234cc24b69309eb0ee22600024c73713e (patch)
tree15ac4122d9c42ec75ba68d342827e37fcb1306ed
parente79dd06782175d50f639180cde5b2c56933aa2ee (diff)
downloadbusybox-w32-459be35234cc24b69309eb0ee22600024c73713e.tar.gz
busybox-w32-459be35234cc24b69309eb0ee22600024c73713e.tar.bz2
busybox-w32-459be35234cc24b69309eb0ee22600024c73713e.zip
hwclock: size optimizations
libbb/time.c: new file, introducing monotonic_us() pscan, traceroute, arping: use it instead of gettimeofday ping, zcip: TODO function old new delta monotonic_us - 89 +89 find_pair 164 180 +16 .rodata 129747 129763 +16 refresh 1144 1152 +8 ............ timeout 8 4 -4 static.start 8 4 -4 last 8 4 -4 parse_conf 1303 1284 -19 time_main 1149 1124 -25 gettimeofday_us 39 - -39 arping_main 2042 1969 -73 hwclock_main 594 501 -93 catcher 485 380 -105 traceroute_main 4300 4117 -183 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 8/11 up/down: 157/-562) Total: -405 bytes
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/Config.in10
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/time.c32
-rw-r--r--miscutils/time.c180
-rw-r--r--networking/arping.c125
-rw-r--r--networking/pscan.c28
-rw-r--r--networking/traceroute.c53
-rw-r--r--networking/wget.c2
-rw-r--r--util-linux/hwclock.c60
10 files changed, 230 insertions, 262 deletions
diff --git a/include/libbb.h b/include/libbb.h
index c0c417c95..2a50bce66 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -200,6 +200,7 @@ struct sysinfo {
200}; 200};
201int sysinfo(struct sysinfo* info); 201int sysinfo(struct sysinfo* info);
202 202
203unsigned long long monotonic_us(void);
203 204
204extern void chomp(char *s); 205extern void chomp(char *s);
205extern void trim(char *s); 206extern void trim(char *s);
diff --git a/libbb/Config.in b/libbb/Config.in
index a1ff7c056..0a3769df2 100644
--- a/libbb/Config.in
+++ b/libbb/Config.in
@@ -95,4 +95,14 @@ config FEATURE_EDITING_FANCY_PROMPT
95 Setting this option allows for prompts to use things like \w and 95 Setting this option allows for prompts to use things like \w and
96 \$ and escape codes. 96 \$ and escape codes.
97 97
98config MONOTONIC_SYSCALL
99 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
100 default y
101 help
102 Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring
103 time intervals (time, ping, traceroute etc need this).
104 Probably requires Linux 2.6+. If not selected, gettimeofday
105 will be used instead (which gives wrong results if date/time
106 is reset).
107
98endmenu 108endmenu
diff --git a/libbb/Kbuild b/libbb/Kbuild
index e562f3222..693f6092c 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -78,6 +78,7 @@ lib-y += simplify_path.o
78lib-y += skip_whitespace.o 78lib-y += skip_whitespace.o
79lib-y += speed_table.o 79lib-y += speed_table.o
80lib-y += str_tolower.o 80lib-y += str_tolower.o
81lib-y += time.o
81lib-y += trim.o 82lib-y += trim.o
82lib-y += u_signal_names.o 83lib-y += u_signal_names.o
83lib-y += udp_io.o 84lib-y += udp_io.o
diff --git a/libbb/time.c b/libbb/time.c
new file mode 100644
index 000000000..f2a741521
--- /dev/null
+++ b/libbb/time.c
@@ -0,0 +1,32 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 2007 Denis Vlasenko
6 *
7 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
8 */
9
10#include "libbb.h"
11
12#if ENABLE_MONOTONIC_SYSCALL
13#include <sys/syscall.h>
14
15/* libc has incredibly messy way of doing this,
16 * typically requiring -lrt. We just skip all this mess */
17unsigned long long monotonic_us(void)
18{
19 struct timespec ts;
20 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts))
21 bb_error_msg_and_die("clock_gettime(MONOTONIC) failed");
22 return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000;
23}
24#else
25unsigned long long monotonic_us(void)
26{
27 struct timeval tv;
28 if (gettimeofday(&tv, NULL))
29 bb_error_msg_and_die("gettimeofday failed");
30 return tv.tv_sec * 1000000ULL + tv_usec;
31}
32#endif
diff --git a/miscutils/time.c b/miscutils/time.c
index 705123c9e..578cb35ff 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -11,28 +11,16 @@
11 11
12#include "libbb.h" 12#include "libbb.h"
13 13
14#define TV_MSEC tv_usec / 1000
15
16/* Information on the resources used by a child process. */ 14/* Information on the resources used by a child process. */
17typedef struct { 15typedef struct {
18 int waitstatus; 16 int waitstatus;
19 struct rusage ru; 17 struct rusage ru;
20 struct timeval start, elapsed; /* Wallclock time of process. */ 18 unsigned elapsed_ms; /* Wallclock time of process. */
21} resource_t; 19} resource_t;
22 20
23/* msec = milliseconds = 1/1,000 (1*10e-3) second. 21/* msec = milliseconds = 1/1,000 (1*10e-3) second.
24 usec = microseconds = 1/1,000,000 (1*10e-6) second. */ 22 usec = microseconds = 1/1,000,000 (1*10e-6) second. */
25 23
26#ifndef TICKS_PER_SEC
27#define TICKS_PER_SEC 100
28#endif
29
30/* The number of milliseconds in one `tick' used by the `rusage' structure. */
31#define MSEC_PER_TICK (1000 / TICKS_PER_SEC)
32
33/* Return the number of clock ticks that occur in M milliseconds. */
34#define MSEC_TO_TICKS(m) ((m) / MSEC_PER_TICK)
35
36#define UL unsigned long 24#define UL unsigned long
37 25
38static const char default_format[] = "real\t%E\nuser\t%u\nsys\t%T"; 26static const char default_format[] = "real\t%E\nuser\t%u\nsys\t%T";
@@ -76,7 +64,6 @@ static const char long_format[] =
76static int resuse_end(pid_t pid, resource_t * resp) 64static int resuse_end(pid_t pid, resource_t * resp)
77{ 65{
78 int status; 66 int status;
79
80 pid_t caught; 67 pid_t caught;
81 68
82 /* Ignore signals, but don't ignore the children. When wait3 69 /* Ignore signals, but don't ignore the children. When wait3
@@ -85,18 +72,8 @@ static int resuse_end(pid_t pid, resource_t * resp)
85 if (caught == -1) 72 if (caught == -1)
86 return 0; 73 return 0;
87 } 74 }
88 75 resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms;
89 gettimeofday(&resp->elapsed, (struct timezone *) 0);
90 resp->elapsed.tv_sec -= resp->start.tv_sec;
91 if (resp->elapsed.tv_usec < resp->start.tv_usec) {
92 /* Manually carry a one from the seconds field. */
93 resp->elapsed.tv_usec += 1000000;
94 --resp->elapsed.tv_sec;
95 }
96 resp->elapsed.tv_usec -= resp->start.tv_usec;
97
98 resp->waitstatus = status; 76 resp->waitstatus = status;
99
100 return 1; 77 return 1;
101} 78}
102 79
@@ -181,30 +158,30 @@ static unsigned long ptok(unsigned long pages)
181 COMMAND is the command and args that are being summarized. 158 COMMAND is the command and args that are being summarized.
182 RESP is resource information on the command. */ 159 RESP is resource information on the command. */
183 160
161#ifndef TICKS_PER_SEC
162#define TICKS_PER_SEC 100
163#endif
164
184static void summarize(const char *fmt, char **command, resource_t * resp) 165static void summarize(const char *fmt, char **command, resource_t * resp)
185{ 166{
186 unsigned long r; /* Elapsed real milliseconds. */ 167 unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */
187 unsigned long v; /* Elapsed virtual (CPU) milliseconds. */ 168 unsigned cpu_ticks; /* Same, in "CPU ticks" */
188 169
189 if (WIFSTOPPED(resp->waitstatus)) 170 if (WIFSTOPPED(resp->waitstatus))
190 printf("Command stopped by signal %d\n", 171 printf("Command stopped by signal %u\n",
191 WSTOPSIG(resp->waitstatus)); 172 WSTOPSIG(resp->waitstatus));
192 else if (WIFSIGNALED(resp->waitstatus)) 173 else if (WIFSIGNALED(resp->waitstatus))
193 printf("Command terminated by signal %d\n", 174 printf("Command terminated by signal %u\n",
194 WTERMSIG(resp->waitstatus)); 175 WTERMSIG(resp->waitstatus));
195 else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) 176 else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus))
196 printf("Command exited with non-zero status %d\n", 177 printf("Command exited with non-zero status %u\n",
197 WEXITSTATUS(resp->waitstatus)); 178 WEXITSTATUS(resp->waitstatus));
198 179
199 /* Convert all times to milliseconds. Occasionally, one of these values 180 vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000
200 comes out as zero. Dividing by zero causes problems, so we first 181 + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000;
201 check the time value. If it is zero, then we take `evasive action'
202 instead of calculating a value. */
203 182
204 r = resp->elapsed.tv_sec * 1000 + resp->elapsed.tv_usec / 1000; 183 cpu_ticks = vv_ms * TICKS_PER_SEC / 1000;
205 184 if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */
206 v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC +
207 resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC;
208 185
209 /* putchar() != putc(stdout) in glibc! */ 186 /* putchar() != putc(stdout) in glibc! */
210 187
@@ -245,127 +222,122 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
245 break; 222 break;
246 case 'D': /* Average unshared data size. */ 223 case 'D': /* Average unshared data size. */
247 printf("%lu", 224 printf("%lu",
248 MSEC_TO_TICKS(v) == 0 ? 0 : 225 ptok((UL) resp->ru.ru_idrss) / cpu_ticks +
249 ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + 226 ptok((UL) resp->ru.ru_isrss) / cpu_ticks);
250 ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); 227 break;
251 break; 228 case 'E': { /* Elapsed real (wall clock) time. */
252 case 'E': /* Elapsed real (wall clock) time. */ 229 unsigned seconds = resp->elapsed_ms / 1000;
253 if (resp->elapsed.tv_sec >= 3600) /* One hour -> h:m:s. */ 230 if (seconds >= 3600) /* One hour -> h:m:s. */
254 printf("%ldh %ldm %02lds", 231 printf("%uh %um %02us",
255 resp->elapsed.tv_sec / 3600, 232 seconds / 3600,
256 (resp->elapsed.tv_sec % 3600) / 60, 233 (seconds % 3600) / 60,
257 resp->elapsed.tv_sec % 60); 234 seconds % 60);
258 else 235 else
259 printf("%ldm %ld.%02lds", /* -> m:s. */ 236 printf("%um %u.%02us", /* -> m:s. */
260 resp->elapsed.tv_sec / 60, 237 seconds / 60,
261 resp->elapsed.tv_sec % 60, 238 seconds % 60,
262 resp->elapsed.tv_usec / 10000); 239 (unsigned)(resp->elapsed_ms / 10) % 100);
263 break; 240 break;
241 }
264 case 'F': /* Major page faults. */ 242 case 'F': /* Major page faults. */
265 printf("%ld", resp->ru.ru_majflt); 243 printf("%lu", resp->ru.ru_majflt);
266 break; 244 break;
267 case 'I': /* Inputs. */ 245 case 'I': /* Inputs. */
268 printf("%ld", resp->ru.ru_inblock); 246 printf("%lu", resp->ru.ru_inblock);
269 break; 247 break;
270 case 'K': /* Average mem usage == data+stack+text. */ 248 case 'K': /* Average mem usage == data+stack+text. */
271 printf("%lu", 249 printf("%lu",
272 MSEC_TO_TICKS(v) == 0 ? 0 : 250 ptok((UL) resp->ru.ru_idrss) / cpu_ticks +
273 ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + 251 ptok((UL) resp->ru.ru_isrss) / cpu_ticks +
274 ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v) + 252 ptok((UL) resp->ru.ru_ixrss) / cpu_ticks);
275 ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v));
276 break; 253 break;
277 case 'M': /* Maximum resident set size. */ 254 case 'M': /* Maximum resident set size. */
278 printf("%lu", ptok((UL) resp->ru.ru_maxrss)); 255 printf("%lu", ptok((UL) resp->ru.ru_maxrss));
279 break; 256 break;
280 case 'O': /* Outputs. */ 257 case 'O': /* Outputs. */
281 printf("%ld", resp->ru.ru_oublock); 258 printf("%lu", resp->ru.ru_oublock);
282 break; 259 break;
283 case 'P': /* Percent of CPU this job got. */ 260 case 'P': /* Percent of CPU this job got. */
284 /* % cpu is (total cpu time)/(elapsed time). */ 261 /* % cpu is (total cpu time)/(elapsed time). */
285 if (r > 0) 262 if (resp->elapsed_ms > 0)
286 printf("%lu%%", (v * 100 / r)); 263 printf("%u%%", (unsigned)(vv_ms * 100 / resp->elapsed_ms));
287 else 264 else
288 printf("?%%"); 265 printf("?%%");
289 break; 266 break;
290 case 'R': /* Minor page faults (reclaims). */ 267 case 'R': /* Minor page faults (reclaims). */
291 printf("%ld", resp->ru.ru_minflt); 268 printf("%lu", resp->ru.ru_minflt);
292 break; 269 break;
293 case 'S': /* System time. */ 270 case 'S': /* System time. */
294 printf("%ld.%02ld", 271 printf("%u.%02u",
295 resp->ru.ru_stime.tv_sec, 272 (unsigned)resp->ru.ru_stime.tv_sec,
296 resp->ru.ru_stime.TV_MSEC / 10); 273 (unsigned)(resp->ru.ru_stime.tv_usec / 10000));
297 break; 274 break;
298 case 'T': /* System time. */ 275 case 'T': /* System time. */
299 if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */ 276 if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */
300 printf("%ldh %ldm %02lds", 277 printf("%uh %um %02us",
301 resp->ru.ru_stime.tv_sec / 3600, 278 (unsigned)(resp->ru.ru_stime.tv_sec / 3600),
302 (resp->ru.ru_stime.tv_sec % 3600) / 60, 279 (unsigned)(resp->ru.ru_stime.tv_sec % 3600) / 60,
303 resp->ru.ru_stime.tv_sec % 60); 280 (unsigned)(resp->ru.ru_stime.tv_sec % 60));
304 else 281 else
305 printf("%ldm %ld.%02lds", /* -> m:s. */ 282 printf("%um %u.%02us", /* -> m:s. */
306 resp->ru.ru_stime.tv_sec / 60, 283 (unsigned)(resp->ru.ru_stime.tv_sec / 60),
307 resp->ru.ru_stime.tv_sec % 60, 284 (unsigned)(resp->ru.ru_stime.tv_sec % 60),
308 resp->ru.ru_stime.tv_usec / 10000); 285 (unsigned)(resp->ru.ru_stime.tv_usec / 10000));
309 break; 286 break;
310 case 'U': /* User time. */ 287 case 'U': /* User time. */
311 printf("%ld.%02ld", 288 printf("%u.%02u",
312 resp->ru.ru_utime.tv_sec, 289 (unsigned)resp->ru.ru_utime.tv_sec,
313 resp->ru.ru_utime.TV_MSEC / 10); 290 (unsigned)(resp->ru.ru_utime.tv_usec / 10000));
314 break; 291 break;
315 case 'u': /* User time. */ 292 case 'u': /* User time. */
316 if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */ 293 if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */
317 printf("%ldh %ldm %02lds", 294 printf("%uh %um %02us",
318 resp->ru.ru_utime.tv_sec / 3600, 295 (unsigned)(resp->ru.ru_utime.tv_sec / 3600),
319 (resp->ru.ru_utime.tv_sec % 3600) / 60, 296 (unsigned)(resp->ru.ru_utime.tv_sec % 3600) / 60,
320 resp->ru.ru_utime.tv_sec % 60); 297 (unsigned)(resp->ru.ru_utime.tv_sec % 60));
321 else 298 else
322 printf("%ldm %ld.%02lds", /* -> m:s. */ 299 printf("%um %u.%02us", /* -> m:s. */
323 resp->ru.ru_utime.tv_sec / 60, 300 (unsigned)(resp->ru.ru_utime.tv_sec / 60),
324 resp->ru.ru_utime.tv_sec % 60, 301 (unsigned)(resp->ru.ru_utime.tv_sec % 60),
325 resp->ru.ru_utime.tv_usec / 10000); 302 (unsigned)(resp->ru.ru_utime.tv_usec / 10000));
326 break; 303 break;
327 case 'W': /* Times swapped out. */ 304 case 'W': /* Times swapped out. */
328 printf("%ld", resp->ru.ru_nswap); 305 printf("%lu", resp->ru.ru_nswap);
329 break; 306 break;
330 case 'X': /* Average shared text size. */ 307 case 'X': /* Average shared text size. */
331 printf("%lu", 308 printf("%lu", ptok((UL) resp->ru.ru_ixrss) / cpu_ticks);
332 MSEC_TO_TICKS(v) == 0 ? 0 :
333 ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v));
334 break; 309 break;
335 case 'Z': /* Page size. */ 310 case 'Z': /* Page size. */
336 printf("%d", getpagesize()); 311 printf("%u", getpagesize());
337 break; 312 break;
338 case 'c': /* Involuntary context switches. */ 313 case 'c': /* Involuntary context switches. */
339 printf("%ld", resp->ru.ru_nivcsw); 314 printf("%lu", resp->ru.ru_nivcsw);
340 break; 315 break;
341 case 'e': /* Elapsed real time in seconds. */ 316 case 'e': /* Elapsed real time in seconds. */
342 printf("%ld.%02ld", 317 printf("%u.%02u",
343 resp->elapsed.tv_sec, resp->elapsed.tv_usec / 10000); 318 (unsigned)resp->elapsed_ms / 1000,
319 (unsigned)(resp->elapsed_ms / 10) % 100);
344 break; 320 break;
345 case 'k': /* Signals delivered. */ 321 case 'k': /* Signals delivered. */
346 printf("%ld", resp->ru.ru_nsignals); 322 printf("%lu", resp->ru.ru_nsignals);
347 break; 323 break;
348 case 'p': /* Average stack segment. */ 324 case 'p': /* Average stack segment. */
349 printf("%lu", 325 printf("%lu", ptok((UL) resp->ru.ru_isrss) / cpu_ticks);
350 MSEC_TO_TICKS(v) == 0 ? 0 :
351 ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v));
352 break; 326 break;
353 case 'r': /* Incoming socket messages received. */ 327 case 'r': /* Incoming socket messages received. */
354 printf("%ld", resp->ru.ru_msgrcv); 328 printf("%lu", resp->ru.ru_msgrcv);
355 break; 329 break;
356 case 's': /* Outgoing socket messages sent. */ 330 case 's': /* Outgoing socket messages sent. */
357 printf("%ld", resp->ru.ru_msgsnd); 331 printf("%lu", resp->ru.ru_msgsnd);
358 break; 332 break;
359 case 't': /* Average resident set size. */ 333 case 't': /* Average resident set size. */
360 printf("%lu", 334 printf("%lu", ptok((UL) resp->ru.ru_idrss) / cpu_ticks);
361 MSEC_TO_TICKS(v) == 0 ? 0 :
362 ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v));
363 break; 335 break;
364 case 'w': /* Voluntary context switches. */ 336 case 'w': /* Voluntary context switches. */
365 printf("%ld", resp->ru.ru_nvcsw); 337 printf("%lu", resp->ru.ru_nvcsw);
366 break; 338 break;
367 case 'x': /* Exit status. */ 339 case 'x': /* Exit status. */
368 printf("%d", WEXITSTATUS(resp->waitstatus)); 340 printf("%u", WEXITSTATUS(resp->waitstatus));
369 break; 341 break;
370 } 342 }
371 break; 343 break;
@@ -403,7 +375,7 @@ static void run_command(char *const *cmd, resource_t * resp)
403 pid_t pid; /* Pid of child. */ 375 pid_t pid; /* Pid of child. */
404 __sighandler_t interrupt_signal, quit_signal; 376 __sighandler_t interrupt_signal, quit_signal;
405 377
406 gettimeofday(&resp->start, (struct timezone *) 0); 378 resp->elapsed_ms = monotonic_us() / 1000;
407 pid = vfork(); /* Run CMD as child process. */ 379 pid = vfork(); /* Run CMD as child process. */
408 if (pid < 0) 380 if (pid < 0)
409 bb_error_msg_and_die("cannot fork"); 381 bb_error_msg_and_die("cannot fork");
diff --git a/networking/arping.c b/networking/arping.c
index 1b2604902..a022e70ea 100644
--- a/networking/arping.c
+++ b/networking/arping.c
@@ -8,9 +8,6 @@
8 * Busybox port: Nick Fedchik <nick@fedchik.org.ua> 8 * Busybox port: Nick Fedchik <nick@fedchik.org.ua>
9 */ 9 */
10 10
11//#include <sys/ioctl.h>
12//#include <signal.h>
13
14#include <arpa/inet.h> 11#include <arpa/inet.h>
15#include <net/if.h> 12#include <net/if.h>
16#include <netinet/ether.h> 13#include <netinet/ether.h>
@@ -18,42 +15,42 @@
18 15
19#include "libbb.h" 16#include "libbb.h"
20 17
18/* We don't expect to see 1000+ seconds delay, unsigned is enough */
19#define MONOTONIC_US() ((unsigned)monotonic_us())
20
21static struct in_addr src; 21static struct in_addr src;
22static struct in_addr dst; 22static struct in_addr dst;
23static struct sockaddr_ll me; 23static struct sockaddr_ll me;
24static struct sockaddr_ll he; 24static struct sockaddr_ll he;
25static struct timeval last; 25static unsigned last;
26 26
27enum cfg_e { 27enum {
28 dad = 1, 28 DAD = 1,
29 unsolicited = 2, 29 UNSOLICITED = 2,
30 advert = 4, 30 ADVERT = 4,
31 quiet = 8, 31 QUIET = 8,
32 quit_on_reply = 16, 32 QUIT_ON_REPLY = 16,
33 broadcast_only = 32, 33 BCAST_ONLY = 32,
34 unicasting = 64 34 UNICASTING = 64
35}; 35};
36static int cfg; 36static int cfg;
37 37
38static int s; 38static int s;
39static unsigned count = UINT_MAX; 39static unsigned count = UINT_MAX;
40static unsigned timeout; 40static unsigned timeout_us;
41static int sent; 41static int sent;
42static int brd_sent; 42static int brd_sent;
43static int received; 43static int received;
44static int brd_recv; 44static int brd_recv;
45static int req_recv; 45static int req_recv;
46 46
47#define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \
48 ((tv1).tv_usec-(tv2).tv_usec)/1000 )
49
50static int send_pack(int sock, struct in_addr *src_addr, 47static int send_pack(int sock, struct in_addr *src_addr,
51 struct in_addr *dst_addr, struct sockaddr_ll *ME, 48 struct in_addr *dst_addr, struct sockaddr_ll *ME,
52 struct sockaddr_ll *HE) 49 struct sockaddr_ll *HE)
53{ 50{
54 int err; 51 int err;
55 struct timeval now; 52 unsigned now;
56 RESERVE_CONFIG_UBUFFER(buf, 256); 53 unsigned char buf[256];
57 struct arphdr *ah = (struct arphdr *) buf; 54 struct arphdr *ah = (struct arphdr *) buf;
58 unsigned char *p = (unsigned char *) (ah + 1); 55 unsigned char *p = (unsigned char *) (ah + 1);
59 56
@@ -62,7 +59,7 @@ static int send_pack(int sock, struct in_addr *src_addr,
62 ah->ar_pro = htons(ETH_P_IP); 59 ah->ar_pro = htons(ETH_P_IP);
63 ah->ar_hln = ME->sll_halen; 60 ah->ar_hln = ME->sll_halen;
64 ah->ar_pln = 4; 61 ah->ar_pln = 4;
65 ah->ar_op = cfg & advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); 62 ah->ar_op = cfg & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
66 63
67 memcpy(p, &ME->sll_addr, ah->ar_hln); 64 memcpy(p, &ME->sll_addr, ah->ar_hln);
68 p += ME->sll_halen; 65 p += ME->sll_halen;
@@ -70,7 +67,7 @@ static int send_pack(int sock, struct in_addr *src_addr,
70 memcpy(p, src_addr, 4); 67 memcpy(p, src_addr, 4);
71 p += 4; 68 p += 4;
72 69
73 if (cfg & advert) 70 if (cfg & ADVERT)
74 memcpy(p, &ME->sll_addr, ah->ar_hln); 71 memcpy(p, &ME->sll_addr, ah->ar_hln);
75 else 72 else
76 memcpy(p, &HE->sll_addr, ah->ar_hln); 73 memcpy(p, &HE->sll_addr, ah->ar_hln);
@@ -79,21 +76,21 @@ static int send_pack(int sock, struct in_addr *src_addr,
79 memcpy(p, dst_addr, 4); 76 memcpy(p, dst_addr, 4);
80 p += 4; 77 p += 4;
81 78
82 gettimeofday(&now, NULL); 79 now = MONOTONIC_US();
83 err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE)); 80 err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
84 if (err == p - buf) { 81 if (err == p - buf) {
85 last = now; 82 last = now;
86 sent++; 83 sent++;
87 if (!(cfg & unicasting)) 84 if (!(cfg & UNICASTING))
88 brd_sent++; 85 brd_sent++;
89 } 86 }
90 RELEASE_CONFIG_BUFFER(buf);
91 return err; 87 return err;
92} 88}
93 89
90static void finish(void) ATTRIBUTE_NORETURN;
94static void finish(void) 91static void finish(void)
95{ 92{
96 if (!(cfg & quiet)) { 93 if (!(cfg & QUIET)) {
97 printf("Sent %d probe(s) (%d broadcast(s))\n" 94 printf("Sent %d probe(s) (%d broadcast(s))\n"
98 "Received %d repl%s" 95 "Received %d repl%s"
99 " (%d request(s), %d broadcast(s))\n", 96 " (%d request(s), %d broadcast(s))\n",
@@ -101,30 +98,31 @@ static void finish(void)
101 received, (received == 1) ? "ies" : "y", 98 received, (received == 1) ? "ies" : "y",
102 req_recv, brd_recv); 99 req_recv, brd_recv);
103 } 100 }
104 if (cfg & dad) 101 if (cfg & DAD)
105 exit(!!received); 102 exit(!!received);
106 if (cfg & unsolicited) 103 if (cfg & UNSOLICITED)
107 exit(0); 104 exit(0);
108 exit(!received); 105 exit(!received);
109} 106}
110 107
111static void catcher(void) 108static void catcher(void)
112{ 109{
113 struct timeval tv; 110 static unsigned start;
114 static struct timeval start;
115 111
116 gettimeofday(&tv, NULL); 112 unsigned now;
117 113
118 if (start.tv_sec == 0) 114 now = MONOTONIC_US();
119 start = tv; 115 if (start == 0)
116 start = now;
120 117
121 if (count-- == 0 118 if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000)))
122 || (timeout && MS_TDIFF(tv, start) > timeout * 1000 + 500))
123 finish(); 119 finish();
124 120
125 if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) { 121 count--;
122
123 if (last == 0 || (now - last) > 500000) {
126 send_pack(s, &src, &dst, &me, &he); 124 send_pack(s, &src, &dst, &me, &he);
127 if (count == 0 && (cfg & unsolicited)) 125 if (count == 0 && (cfg & UNSOLICITED))
128 finish(); 126 finish();
129 } 127 }
130 alarm(1); 128 alarm(1);
@@ -162,7 +160,7 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
162 return 0; 160 return 0;
163 memcpy(&src_ip, p + ah->ar_hln, 4); 161 memcpy(&src_ip, p + ah->ar_hln, 4);
164 memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); 162 memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4);
165 if (!(cfg & dad)) { 163 if (!(cfg & DAD)) {
166 if (src_ip.s_addr != dst.s_addr) 164 if (src_ip.s_addr != dst.s_addr)
167 return 0; 165 return 0;
168 if (src.s_addr != dst_ip.s_addr) 166 if (src.s_addr != dst_ip.s_addr)
@@ -190,11 +188,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
190 if (src.s_addr && src.s_addr != dst_ip.s_addr) 188 if (src.s_addr && src.s_addr != dst_ip.s_addr)
191 return 0; 189 return 0;
192 } 190 }
193 if (!(cfg & quiet)) { 191 if (!(cfg & QUIET)) {
194 int s_printed = 0; 192 int s_printed = 0;
195 struct timeval tv;
196
197 gettimeofday(&tv, NULL);
198 193
199 printf("%scast re%s from %s [%s]", 194 printf("%scast re%s from %s [%s]",
200 FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", 195 FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad",
@@ -212,13 +207,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
212 ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); 207 ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4));
213 } 208 }
214 209
215 if (last.tv_sec) { 210 if (last) {
216 long usecs = (tv.tv_sec - last.tv_sec) * 1000000 + 211 printf(" %u.%03ums\n", last / 1000, last % 1000);
217 tv.tv_usec - last.tv_usec;
218 long msecs = (usecs + 500) / 1000;
219
220 usecs -= msecs * 1000 - 500;
221 printf(" %ld.%03ldms\n", msecs, usecs);
222 } else { 212 } else {
223 printf(" UNSOLICITED?\n"); 213 printf(" UNSOLICITED?\n");
224 } 214 }
@@ -229,11 +219,11 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
229 brd_recv++; 219 brd_recv++;
230 if (ah->ar_op == htons(ARPOP_REQUEST)) 220 if (ah->ar_op == htons(ARPOP_REQUEST))
231 req_recv++; 221 req_recv++;
232 if (cfg & quit_on_reply) 222 if (cfg & QUIT_ON_REPLY)
233 finish(); 223 finish();
234 if (!(cfg & broadcast_only)) { 224 if (!(cfg & BCAST_ONLY)) {
235 memcpy(he.sll_addr, p, me.sll_halen); 225 memcpy(he.sll_addr, p, me.sll_halen);
236 cfg |= unicasting; 226 cfg |= UNICASTING;
237 } 227 }
238 return 1; 228 return 1;
239} 229}
@@ -245,6 +235,7 @@ int arping_main(int argc, char **argv)
245 int ifindex; 235 int ifindex;
246 char *source = NULL; 236 char *source = NULL;
247 char *target; 237 char *target;
238 unsigned char *packet;
248 239
249 s = xsocket(PF_PACKET, SOCK_DGRAM, 0); 240 s = xsocket(PF_PACKET, SOCK_DGRAM, 0);
250 241
@@ -258,28 +249,23 @@ int arping_main(int argc, char **argv)
258 /* Dad also sets quit_on_reply. 249 /* Dad also sets quit_on_reply.
259 * Advert also sets unsolicited. 250 * Advert also sets unsolicited.
260 */ 251 */
261 opt_complementary = "Df:AU"; 252 opt_complementary = "=1:Df:AU";
262 opt = getopt32(argc, argv, "DUAqfbc:w:I:s:", 253 opt = getopt32(argc, argv, "DUAqfbc:w:I:s:",
263 &_count, &_timeout, &device, &source); 254 &_count, &_timeout, &device, &source);
264 cfg |= opt & 0x3f; /* set respective flags */ 255 cfg |= opt & 0x3f; /* set respective flags */
265 if (opt & 0x40) /* -c: count */ 256 if (opt & 0x40) /* -c: count */
266 count = xatou(_count); 257 count = xatou(_count);
267 if (opt & 0x80) /* -w: timeout */ 258 if (opt & 0x80) /* -w: timeout */
268 timeout = xatoul_range(_timeout, 0, INT_MAX/2000); 259 timeout_us = xatou_range(_timeout, 0, INT_MAX/2000000) * 1000000;
269 //if (opt & 0x100) /* -i: interface */ 260 //if (opt & 0x100) /* -I: interface */
270 if (strlen(device) > IF_NAMESIZE) { 261 if (strlen(device) >= IF_NAMESIZE) {
271 bb_error_msg_and_die("interface name '%s' is too long", 262 bb_error_msg_and_die("interface name '%s' is too long",
272 device); 263 device);
273 } 264 }
274 //if (opt & 0x200) /* -s: source */ 265 //if (opt & 0x200) /* -s: source */
275 } 266 }
276 argc -= optind;
277 argv += optind;
278
279 if (argc != 1)
280 bb_show_usage();
281 267
282 target = *argv; 268 target = argv[optind];
283 269
284 xfunc_error_retval = 2; 270 xfunc_error_retval = 2;
285 271
@@ -301,7 +287,7 @@ int arping_main(int argc, char **argv)
301 } 287 }
302 if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { 288 if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
303 bb_error_msg("interface %s is not ARPable", device); 289 bb_error_msg("interface %s is not ARPable", device);
304 return (cfg & dad ? 0 : 2); 290 return (cfg & DAD ? 0 : 2);
305 } 291 }
306 } 292 }
307 293
@@ -317,10 +303,10 @@ int arping_main(int argc, char **argv)
317 bb_error_msg_and_die("invalid source address %s", source); 303 bb_error_msg_and_die("invalid source address %s", source);
318 } 304 }
319 305
320 if (!(cfg & dad) && (cfg & unsolicited) && src.s_addr == 0) 306 if (!(cfg & DAD) && (cfg & UNSOLICITED) && src.s_addr == 0)
321 src = dst; 307 src = dst;
322 308
323 if (!(cfg & dad) || src.s_addr) { 309 if (!(cfg & DAD) || src.s_addr) {
324 struct sockaddr_in saddr; 310 struct sockaddr_in saddr;
325 int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); 311 int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0);
326 312
@@ -333,7 +319,7 @@ int arping_main(int argc, char **argv)
333 if (src.s_addr) { 319 if (src.s_addr) {
334 saddr.sin_addr = src; 320 saddr.sin_addr = src;
335 xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); 321 xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
336 } else if (!(cfg & dad)) { 322 } else if (!(cfg & DAD)) {
337 socklen_t alen = sizeof(saddr); 323 socklen_t alen = sizeof(saddr);
338 324
339 saddr.sin_port = htons(1025); 325 saddr.sin_port = htons(1025);
@@ -364,18 +350,18 @@ int arping_main(int argc, char **argv)
364 } 350 }
365 if (me.sll_halen == 0) { 351 if (me.sll_halen == 0) {
366 bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); 352 bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device);
367 return (cfg & dad ? 0 : 2); 353 return (cfg & DAD ? 0 : 2);
368 } 354 }
369 he = me; 355 he = me;
370 memset(he.sll_addr, -1, he.sll_halen); 356 memset(he.sll_addr, -1, he.sll_halen);
371 357
372 if (!(cfg & quiet)) { 358 if (!(cfg & QUIET)) {
373 printf("ARPING to %s from %s via %s\n", 359 printf("ARPING to %s from %s via %s\n",
374 inet_ntoa(dst), inet_ntoa(src), 360 inet_ntoa(dst), inet_ntoa(src),
375 device ? device : "unknown"); 361 device ? device : "unknown");
376 } 362 }
377 363
378 if (!src.s_addr && !(cfg & dad)) { 364 if (!src.s_addr && !(cfg & DAD)) {
379 bb_error_msg_and_die("no src address in the non-DAD mode"); 365 bb_error_msg_and_die("no src address in the non-DAD mode");
380 } 366 }
381 367
@@ -394,9 +380,9 @@ int arping_main(int argc, char **argv)
394 380
395 catcher(); 381 catcher();
396 382
383 packet = xmalloc(4096);
397 while (1) { 384 while (1) {
398 sigset_t sset, osset; 385 sigset_t sset, osset;
399 RESERVE_CONFIG_UBUFFER(packet, 4096);
400 struct sockaddr_ll from; 386 struct sockaddr_ll from;
401 socklen_t alen = sizeof(from); 387 socklen_t alen = sizeof(from);
402 int cc; 388 int cc;
@@ -412,6 +398,5 @@ int arping_main(int argc, char **argv)
412 sigprocmask(SIG_BLOCK, &sset, &osset); 398 sigprocmask(SIG_BLOCK, &sset, &osset);
413 recv_pack(packet, cc, &from); 399 recv_pack(packet, cc, &from);
414 sigprocmask(SIG_SETMASK, &osset, NULL); 400 sigprocmask(SIG_SETMASK, &osset, NULL);
415 RELEASE_CONFIG_BUFFER(packet);
416 } 401 }
417} 402}
diff --git a/networking/pscan.c b/networking/pscan.c
index 10bf3b606..9fa6993e8 100644
--- a/networking/pscan.c
+++ b/networking/pscan.c
@@ -17,19 +17,6 @@
17#define DERR(...) ((void)0) 17#define DERR(...) ((void)0)
18#endif 18#endif
19 19
20/* return time in usec */
21// TODO: move to libbb and use in traceroute, zcip, arping etc
22// (maybe also use absolute monotonic clock - no time warps
23// due to admin resetting date/time?)
24static unsigned gettimeofday_us(void)
25{
26 struct timeval now;
27
28 if (gettimeofday(&now, NULL))
29 return 0;
30 return (now.tv_sec * 1000000 + now.tv_usec);
31}
32
33static const char *port_name(unsigned port) 20static const char *port_name(unsigned port)
34{ 21{
35 struct servent *server; 22 struct servent *server;
@@ -40,6 +27,9 @@ static const char *port_name(unsigned port)
40 return "unknown"; 27 return "unknown";
41} 28}
42 29
30/* We don't expect to see 1000+ seconds delay, unsigned is enough */
31#define MONOTONIC_US() ((unsigned)monotonic_us())
32
43int pscan_main(int argc, char **argv); 33int pscan_main(int argc, char **argv);
44int pscan_main(int argc, char **argv) 34int pscan_main(int argc, char **argv)
45{ 35{
@@ -91,7 +81,7 @@ int pscan_main(int argc, char **argv)
91 /* Nonblocking connect typically "fails" with errno == EINPROGRESS */ 81 /* Nonblocking connect typically "fails" with errno == EINPROGRESS */
92 ndelay_on(s); 82 ndelay_on(s);
93 DMSG("connect to port %u", port); 83 DMSG("connect to port %u", port);
94 start = gettimeofday_us(); 84 start = MONOTONIC_US();
95 if (connect(s, &lsap->sa, lsap->len) == 0) { 85 if (connect(s, &lsap->sa, lsap->len) == 0) {
96 /* Unlikely, for me even localhost fails :) */ 86 /* Unlikely, for me even localhost fails :) */
97 DMSG("connect succeeded"); 87 DMSG("connect succeeded");
@@ -110,15 +100,15 @@ int pscan_main(int argc, char **argv)
110 closed_ports++; 100 closed_ports++;
111 break; 101 break;
112 } 102 }
113 DERR("port %u errno %d @%u", port, errno, gettimeofday_us() - start); 103 DERR("port %u errno %d @%u", port, errno, MONOTONIC_US() - start);
114 if ((gettimeofday_us() - start) > rtt_4) 104 if ((MONOTONIC_US() - start) > rtt_4)
115 break; 105 break;
116 /* Can sleep (much) longer than specified delay. 106 /* Can sleep (much) longer than specified delay.
117 * We check rtt BEFORE we usleep, otherwise 107 * We check rtt BEFORE we usleep, otherwise
118 * on localhost we'll do zero writes done (!) 108 * on localhost we'll do zero writes done (!)
119 * before we exceed (rather small) rtt */ 109 * before we exceed (rather small) rtt */
120 usleep(rtt_4/8); 110 usleep(rtt_4/8);
121 DMSG("write to port %u @%u", port, gettimeofday_us() - start); 111 DMSG("write to port %u @%u", port, MONOTONIC_US() - start);
122 if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */ 112 if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */
123 open: 113 open:
124 open_ports++; 114 open_ports++;
@@ -126,13 +116,13 @@ int pscan_main(int argc, char **argv)
126 break; 116 break;
127 } 117 }
128 } 118 }
129 DMSG("out of loop @%u", gettimeofday_us() - start); 119 DMSG("out of loop @%u", MONOTONIC_US() - start);
130 120
131 /* Estimate new rtt - we don't want to wait entire timeout 121 /* Estimate new rtt - we don't want to wait entire timeout
132 * for each port. *4 allows for rise in net delay. 122 * for each port. *4 allows for rise in net delay.
133 * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2) 123 * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2)
134 * because we don't want to accidentally miss ports. */ 124 * because we don't want to accidentally miss ports. */
135 rtt_4 = (gettimeofday_us() - start) * 4; 125 rtt_4 = (MONOTONIC_US() - start) * 4;
136 if (rtt_4 < min_rtt) 126 if (rtt_4 < min_rtt)
137 rtt_4 = min_rtt; 127 rtt_4 = min_rtt;
138 if (rtt_4 > timeout) 128 if (rtt_4 > timeout)
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 40533a82d..9fc15d390 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -275,7 +275,8 @@ struct hostinfo {
275struct outdata { 275struct outdata {
276 unsigned char seq; /* sequence number of this packet */ 276 unsigned char seq; /* sequence number of this packet */
277 unsigned char ttl; /* ttl packet left with */ 277 unsigned char ttl; /* ttl packet left with */
278 struct timeval tv ATTRIBUTE_PACKED; /* time packet left */ 278// UNUSED. Retaining to have the same packet size.
279 struct timeval tv_UNUSED ATTRIBUTE_PACKED; /* time packet left */
279}; 280};
280 281
281struct IFADDRLIST { 282struct IFADDRLIST {
@@ -533,37 +534,19 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from)
533 534
534*/ 535*/
535 536
536/*
537 * Subtract 2 timeval structs: out = out - in.
538 * Out is assumed to be >= in.
539 */
540static inline void
541tvsub(struct timeval *out, struct timeval *in)
542{
543
544 if ((out->tv_usec -= in->tv_usec) < 0) {
545 --out->tv_sec;
546 out->tv_usec += 1000000;
547 }
548 out->tv_sec -= in->tv_sec;
549}
550
551static int 537static int
552wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp) 538wait_for_reply(int sock, struct sockaddr_in *fromp)
553{ 539{
554 fd_set fds; 540 fd_set fds;
555 struct timeval now, tvwait; 541 struct timeval tvwait;
556 struct timezone tz;
557 int cc = 0; 542 int cc = 0;
558 socklen_t fromlen = sizeof(*fromp); 543 socklen_t fromlen = sizeof(*fromp);
559 544
560 FD_ZERO(&fds); 545 FD_ZERO(&fds);
561 FD_SET(sock, &fds); 546 FD_SET(sock, &fds);
562 547
563 tvwait.tv_sec = tp->tv_sec + waittime; 548 tvwait.tv_sec = waittime;
564 tvwait.tv_usec = tp->tv_usec; 549 tvwait.tv_usec = 0;
565 (void)gettimeofday(&now, &tz);
566 tvsub(&tvwait, &now);
567 550
568 if (select(sock + 1, &fds, NULL, NULL, &tvwait) > 0) 551 if (select(sock + 1, &fds, NULL, NULL, &tvwait) > 0)
569 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0, 552 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
@@ -609,7 +592,7 @@ in_cksum(uint16_t *addr, int len)
609 592
610 593
611static void 594static void
612send_probe(int seq, int ttl, struct timeval *tp) 595send_probe(int seq, int ttl)
613{ 596{
614 int cc; 597 int cc;
615 struct udpiphdr *ui, *oui; 598 struct udpiphdr *ui, *oui;
@@ -633,7 +616,8 @@ send_probe(int seq, int ttl, struct timeval *tp)
633 /* Payload */ 616 /* Payload */
634 outdata->seq = seq; 617 outdata->seq = seq;
635 outdata->ttl = ttl; 618 outdata->ttl = ttl;
636 memcpy(&outdata->tv, tp, sizeof(outdata->tv)); 619// UNUSED: was storing gettimeofday's result there, but never ever checked it
620 /*memcpy(&outdata->tv, tp, sizeof(outdata->tv));*/
637 621
638#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP 622#if ENABLE_FEATURE_TRACEROUTE_USE_ICMP
639 if (useicmp) 623 if (useicmp)
@@ -706,7 +690,6 @@ send_probe(int seq, int ttl, struct timeval *tp)
706 packlen, (struct sockaddr *)&whereto, sizeof(whereto)); 690 packlen, (struct sockaddr *)&whereto, sizeof(whereto));
707 if (cc != packlen) { 691 if (cc != packlen) {
708 bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); 692 bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc);
709// (void)fflush(stdout);
710 } 693 }
711} 694}
712 695
@@ -908,9 +891,9 @@ getaddr(uint32_t *ap, const char *host)
908#endif 891#endif
909 892
910static void 893static void
911print_delta_ms(struct timeval *t1p, struct timeval *t2p) 894print_delta_ms(unsigned t1p, unsigned t2p)
912{ 895{
913 unsigned tt = (t2p->tv_sec - t1p->tv_sec) * 1000000 + (t2p->tv_usec - t1p->tv_usec); 896 unsigned tt = t2p - t1p;
914 printf(" %u.%03u ms", tt/1000, tt%1000); 897 printf(" %u.%03u ms", tt/1000, tt%1000);
915} 898}
916 899
@@ -1230,17 +1213,17 @@ int traceroute_main(int argc, char **argv)
1230 printf("%2d ", ttl); 1213 printf("%2d ", ttl);
1231 for (probe = 0; probe < nprobes; ++probe) { 1214 for (probe = 0; probe < nprobes; ++probe) {
1232 int cc; 1215 int cc;
1233 struct timeval t1, t2; 1216 unsigned t1;
1234 struct timezone tz; 1217 unsigned t2;
1235 struct ip *ip; 1218 struct ip *ip;
1236 1219
1237 if (sentfirst && pausemsecs > 0) 1220 if (sentfirst && pausemsecs > 0)
1238 usleep(pausemsecs * 1000); 1221 usleep(pausemsecs * 1000);
1239 (void)gettimeofday(&t1, &tz); 1222 t1 = monotonic_us();
1240 send_probe(++seq, ttl, &t1); 1223 send_probe(++seq, ttl);
1241 ++sentfirst; 1224 ++sentfirst;
1242 while ((cc = wait_for_reply(s, from, &t1)) != 0) { 1225 while ((cc = wait_for_reply(s, from)) != 0) {
1243 (void)gettimeofday(&t2, &tz); 1226 t2 = monotonic_us();
1244 i = packet_ok(packet, cc, from, seq); 1227 i = packet_ok(packet, cc, from, seq);
1245 /* Skip short packet */ 1228 /* Skip short packet */
1246 if (i == 0) 1229 if (i == 0)
@@ -1251,7 +1234,7 @@ int traceroute_main(int argc, char **argv)
1251 lastaddr = from->sin_addr.s_addr; 1234 lastaddr = from->sin_addr.s_addr;
1252 ++gotlastaddr; 1235 ++gotlastaddr;
1253 } 1236 }
1254 print_delta_ms(&t1, &t2); 1237 print_delta_ms(t1, t2);
1255 ip = (struct ip *)packet; 1238 ip = (struct ip *)packet;
1256 if (op & OPT_TTL_FLAG) 1239 if (op & OPT_TTL_FLAG)
1257 printf(" (%d)", ip->ip_ttl); 1240 printf(" (%d)", ip->ip_ttl);
diff --git a/networking/wget.c b/networking/wget.c
index fe669bbdd..fc7f7c32c 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -705,7 +705,7 @@ progressmeter(int flag)
705 ratio = 100; 705 ratio = 100;
706 if (totalsize != 0 && !chunked) { 706 if (totalsize != 0 && !chunked) {
707 /* long long helps to have working ETA even if !LFS */ 707 /* long long helps to have working ETA even if !LFS */
708 ratio = (int) (100 * (unsigned long long)(transferred+beg_range) / totalsize); 708 ratio = (int) (100ULL * (transferred+beg_range) / totalsize);
709 ratio = MIN(ratio, 100); 709 ratio = MIN(ratio, 100);
710 } 710 }
711 711
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index c4b793ef8..204a103c3 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -7,7 +7,6 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8*/ 8*/
9 9
10//#include <sys/ioctl.h>
11#include <sys/utsname.h> 10#include <sys/utsname.h>
12#include <getopt.h> 11#include <getopt.h>
13#include "libbb.h" 12#include "libbb.h"
@@ -98,49 +97,42 @@ static void write_rtc(time_t t, int utc)
98 close(rtc); 97 close(rtc);
99} 98}
100 99
101static int show_clock(int utc) 100static void show_clock(int utc)
102{ 101{
103 struct tm *ptm; 102 //struct tm *ptm;
104 time_t t; 103 time_t t;
105 RESERVE_CONFIG_BUFFER(buffer, 64); 104 char *cp;
106 105
107 t = read_rtc(utc); 106 t = read_rtc(utc);
108 ptm = localtime(&t); /* Sets 'tzname[]' */ 107 //ptm = localtime(&t); /* Sets 'tzname[]' */
109 108
110 safe_strncpy(buffer, ctime(&t), 64); 109 cp = ctime(&t);
111 if (buffer[0]) 110 if (cp[0])
112 buffer[strlen(buffer) - 1] = 0; 111 cp[strlen(cp) - 1] = '\0';
113 112
114 //printf("%s %.6f seconds %s\n", buffer, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); 113 //printf("%s %.6f seconds %s\n", cp, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0]));
115 printf( "%s %.6f seconds\n", buffer, 0.0); 114 printf("%s 0.000000 seconds\n", cp);
116 RELEASE_CONFIG_BUFFER(buffer);
117
118 return 0;
119} 115}
120 116
121static int to_sys_clock(int utc) 117static void to_sys_clock(int utc)
122{ 118{
123 struct timeval tv = { 0, 0 }; 119 struct timeval tv;
124 const struct timezone tz = { timezone/60 - 60*daylight, 0 }; 120 const struct timezone tz = { timezone/60 - 60*daylight, 0 };
125 121
126 tv.tv_sec = read_rtc(utc); 122 tv.tv_sec = read_rtc(utc);
127 123 tv.tv_usec = 0;
128 if (settimeofday(&tv, &tz)) 124 if (settimeofday(&tv, &tz))
129 bb_perror_msg_and_die("settimeofday() failed"); 125 bb_perror_msg_and_die("settimeofday() failed");
130
131 return 0;
132} 126}
133 127
134static int from_sys_clock(int utc) 128static void from_sys_clock(int utc)
135{ 129{
136 struct timeval tv = { 0, 0 }; 130 struct timeval tv;
137 struct timezone tz = { 0, 0 };
138
139 if (gettimeofday(&tv, &tz))
140 bb_perror_msg_and_die("gettimeofday() failed");
141 131
132 gettimeofday(&tv, NULL);
133 //if (gettimeofday(&tv, NULL))
134 // bb_perror_msg_and_die("gettimeofday() failed");
142 write_rtc(tv.tv_sec, utc); 135 write_rtc(tv.tv_sec, utc);
143 return 0;
144} 136}
145 137
146#ifdef CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS 138#ifdef CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS
@@ -182,8 +174,8 @@ static int check_utc(void)
182#define HWCLOCK_OPT_SYSTOHC 0x10 174#define HWCLOCK_OPT_SYSTOHC 0x10
183#define HWCLOCK_OPT_RTCFILE 0x20 175#define HWCLOCK_OPT_RTCFILE 0x20
184 176
185int hwclock_main(int argc, char **argv ); 177int hwclock_main(int argc, char **argv);
186int hwclock_main(int argc, char **argv ) 178int hwclock_main(int argc, char **argv)
187{ 179{
188 unsigned opt; 180 unsigned opt;
189 int utc; 181 int utc;
@@ -210,12 +202,14 @@ int hwclock_main(int argc, char **argv )
210 utc = check_utc(); 202 utc = check_utc();
211 203
212 if (opt & HWCLOCK_OPT_HCTOSYS) { 204 if (opt & HWCLOCK_OPT_HCTOSYS) {
213 return to_sys_clock(utc); 205 to_sys_clock(utc);
206 return 0;
214 } 207 }
215 else if (opt & HWCLOCK_OPT_SYSTOHC) { 208 if (opt & HWCLOCK_OPT_SYSTOHC) {
216 return from_sys_clock(utc); 209 from_sys_clock(utc);
217 } else { 210 return 0;
218 /* default HWCLOCK_OPT_SHOW */
219 return show_clock(utc);
220 } 211 }
212 /* default HWCLOCK_OPT_SHOW */
213 show_clock(utc);
214 return 0;
221} 215}