diff --git sbin/ping/ping.c sbin/ping/ping.c index a3b3d650eb5..78b571b95b4 100644 --- sbin/ping/ping.c +++ sbin/ping/ping.c @@ -79,6 +79,7 @@ #include #include +#include #include #include @@ -95,6 +96,7 @@ #include #include #include +#include #include #include #include @@ -217,6 +219,8 @@ const char *pr_addr(struct sockaddr *, socklen_t); void pr_pack(u_char *, int, struct msghdr *); __dead void usage(void); +void output(char *, u_char *, int); + /* IPv4 specific functions */ void pr_ipopt(int, u_char *); int in_cksum(u_short *, int); @@ -255,7 +259,7 @@ main(int argc, char *argv[]) int df = 0, tos = 0, bufspace = IP_MAXPACKET, hoplimit = -1, mflag = 0; u_char *datap, *packet; u_char ttl = MAXTTL; - char *e, *target, hbuf[NI_MAXHOST], *source = NULL; + char *e, *target, hbuf[NI_MAXHOST], *source = NULL, *output_path = NULL; char rspace[3 + 4 * NROUTES + 1]; /* record route space */ const char *errstr; double fraction, integral, seconds; @@ -264,11 +268,13 @@ main(int argc, char *argv[]) u_int rtableid = 0; extern char *__progname; +#if 0 /* Cannot pledge due to special setsockopt()s below */ if (unveil("/", "r") == -1) err(1, "unveil /"); if (unveil(NULL, NULL) == -1) err(1, "unveil"); +#endif if (strcmp("ping6", __progname) == 0) { v6flag = 1; @@ -297,8 +303,8 @@ main(int argc, char *argv[]) preload = 0; datap = &outpack[ECHOLEN + ECHOTMLEN]; while ((ch = getopt(argc, argv, v6flag ? - "c:DdEefgHh:I:i:Ll:mNnp:qS:s:T:V:vw:" : - "DEI:LRS:c:defgHi:l:np:qs:T:t:V:vw:")) != -1) { + "c:DdEefgHh:I:i:Ll:mNno:p:qS:s:T:V:vw:" : + "DEI:LRS:c:defgHi:l:no:p:qs:T:t:V:vw:")) != -1) { switch(ch) { case 'c': npackets = strtonum(optarg, 0, INT64_MAX, &errstr); @@ -375,6 +381,9 @@ main(int argc, char *argv[]) case 'n': options &= ~F_HOSTNAME; break; + case 'o': + output_path = optarg; + break; case 'p': /* fill buffer with user pattern */ options |= F_PINGFILLED; fill((char *)datap, optarg); @@ -768,10 +777,10 @@ main(int argc, char *argv[]) } if (options & F_HOSTNAME) { - if (pledge("stdio inet dns", NULL) == -1) + if (pledge("stdio inet dns wpath cpath", NULL) == -1) err(1, "pledge"); } else { - if (pledge("stdio inet", NULL) == -1) + if (pledge("stdio inet wpath cpath", NULL) == -1) err(1, "pledge"); } @@ -960,8 +969,11 @@ main(int argc, char *argv[]) } } continue; - } else + } else { + if (output_path != NULL) + output(output_path, packet, cc); pr_pack(packet, cc, &m); + } if (npackets && nreceived >= npackets) break; @@ -2274,3 +2286,29 @@ usage(void) } exit(1); } + +void +output(char *path, u_char *pack, int len) +{ + size_t bsz, off; + ssize_t nw; + int fd; + char *fname; + + bsz = len; + if (asprintf(&fname, "%s/ping_%lld_%d.out", path, time(NULL), + getpid()) == -1) + err(1, NULL); + + fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | + S_IROTH); + free(fname); + + if (fd == -1) + err(1, "open"); + + for (off = 0; off < bsz; off += nw) + if ((nw = write(fd, pack + off, bsz - off)) == 0 || nw == -1) + err(1, "write"); + close(fd); +}