diff --git a/.gitignore b/.gitignore index 46c3668..6fb5d60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,3 @@ -*.la -*.lo +echoc *.o *~ -.deps -.libs -m4/*.m4 -Makefile -Makefile.in -aclocal.m4 -autom4te.cache -compile -config.guess -config.h -config.h.in -config.log -config.status -config.sub -configure -depcomp -install-sh -libtool -ltmain.sh -missing -stamp-* -obj* diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 914ee49..0000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ - Copyright (c) 2012-2015 Matthieu Herrb - - Permission to use, copy, modify, and distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ac8c90b --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +# + +PROG= echoc +SRCS= echoc.c + +OBJS= $(SRCS:%.c=%.o) + +LIBS= + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o $@ $(OBJS) $(LIBS) + +clean: + rm -f $(OBJS) $(PROG) + +.c.o: + $(CC) -c $(CFLAGS) -o $@ $< diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index c30d877..0000000 --- a/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -bin_PROGRAMS = echoc - -AM_CFLAGS = -g -Wall - -dist_man_MANS = echoc.1 diff --git a/README b/README new file mode 100644 index 0000000..d3b4dc8 --- /dev/null +++ b/README @@ -0,0 +1,21 @@ +echoc is a small network test program that sends UDP packets to the +echo service (it should be activated in [x]inetd on the target host). +echoc displays the start/end date of loss of connectivity. + +It's distributed under the ISC license: + +/* + * Copyright (c) 2012 Matthieu Herrb + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/README.md b/README.md deleted file mode 100644 index 9c3fb52..0000000 --- a/README.md +++ /dev/null @@ -1,45 +0,0 @@ -echoc -===== - -echoc is a small network test program that sends UDP packets to the -echo service (it should be activated in [x]inetd on the target host). -echoc displays the start/end date of loss of connectivity. - -Building --------- - -From git, run: - -``` -./autogen.sh -make -make install -``` - -From a source tarball, run: - -``` -./configure -make -make install -``` - -Licence -------- - -Echoc is distributed under the ISC license: - - Copyright (c) 2012-2015 Matthieu Herrb - - Permission to use, copy, modify, and distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index bb05f17..0000000 --- a/autogen.sh +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/sh -srcdir=`dirname "$0"` -test -z "$srcdir" && srcdir=. - -ORIGDIR=`pwd` -cd "$srcdir" - -autoreconf -v --install || exit 1 -cd "$ORIGDIR" || exit $? - -if test -z "$NOCONFIGURE"; then - exec "$srcdir"/configure "$@" -fi diff --git a/configure.ac b/configure.ac deleted file mode 100644 index f4e1c5d..0000000 --- a/configure.ac +++ /dev/null @@ -1,11 +0,0 @@ -AC_PREREQ([2.71]) -AC_INIT([echoc],[0.6.99],[https://gitlab.laas.fr/matthieu/echoc],[echoc]) -AM_INIT_AUTOMAKE([foreign dist-bzip2]) -AC_CONFIG_MACRO_DIR([m4]) -AC_PROG_CC - -AC_CHECK_HEADERS([bsd/stdlib.h]) -AC_SEARCH_LIBS(strtonum, [bsd]) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/echoc.1 b/echoc.1 deleted file mode 100644 index 9cada97..0000000 --- a/echoc.1 +++ /dev/null @@ -1,80 +0,0 @@ -.\" -.\" Copyright (c) 2012-2015 Matthieu Herrb -.\" -.\" Permission to use, copy, modify, and distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above -.\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -.\" -.Dd $Mdocdate: September 29 2015 $ -.Dt ECHOC 1 -.Os -.Sh NAME -.Nm echoc -.Nd send UDP packets to network hosts and wait for replies -.Sh SYNOPSYS -.Nm echoc -.Bk -words -.Op Fl dv -.Op Fl c Ar count -.Op Fl i Ar ms -.Op Fl l Ar len -.Op Fl p Ar port -.Op Fl t Ar ms -.Ar host -.Ek -.Sh DESCRIPTION -.Nm -sends UDP packets to the -.Dv ECHO -service on the remote -.Ar host . -.Nm -displays the start/end date of loss of connectivity. -The options are as follow: -.Bl -tag -width Ds -.It Fl c Ar count -Stop sending after -.Ar count -packets have been sent. -.It Fl d -Set the -.Dv Don't Fragment -bit on outgoing datagrams, on systems that allow programs to control it. -On some systems (MacOSX, OpenBSD) this option will do nothing and the -generated datagrams will have the DF bit set or not, depending on -system settings. -.It Fl i Ar ms -wait -.Ar ms -milliseconds between every packet (default: 100 ms). -.It Fl l Ar len -Send packets of length -.Ar len -bytes (default: 10). -.It Fl p Ar port -Set destination port to -.Ar port -(default: 7 - echo). -.It Fl t Ar ms -Wait at most -.Ar ms -milliseconds for the reply before declaring the connection dead -(default: 500ms). -.El -.Sh SEE ALSO -.Xr nc 1 , -.Xr ping 8 , -.Xr ping6 8 -.Sh AUTHOR -The -.Nm -utility was written for tetaneutral.net by Matthieu Herrb. - diff --git a/echoc.c b/echoc.c index 269f4f6..f5ddb69 100644 --- a/echoc.c +++ b/echoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 Matthieu Herrb + * Copyright (c) 2012 Matthieu Herrb * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,11 +18,6 @@ #include #include -#include -#ifdef HAVE_BSD_STDLIB_H -#include -#endif - #include #include #include @@ -37,38 +32,25 @@ int sock = -1; int verbose = 0; -int aborting = 0; struct sockaddr *server; socklen_t serverlen; unsigned int seq = 0; -size_t len = 10; static void usage(void) { - errx(2, "usage: echoc [-c nbr][-d][-i ms][-l len][-p port][-t ms][-v] server"); -} - -static void -sigint_handler(int unused) -{ - aborting = 1; + errx(2, "usage: echoc [-i ms][-t ms][-v] server"); } static void send_packet(int unused) { - char *buf; - buf = malloc(len); - if (buf == NULL) - return; - snprintf(buf, len, "%d", seq); - if (sendto(sock, buf, len, 0, server, - serverlen) != len) { + if (sendto(sock, &seq, sizeof(seq), 0, server, + serverlen) != sizeof(seq)) { if (verbose) warn("sendto"); } - if (verbose) + if (verbose) printf("sent %d\n", seq); seq++; } @@ -77,10 +59,7 @@ int main(int argc, char *argv[]) { char name[NI_MAXHOST]; - char *recvbuf; - const char *errstr; - char date[80]; - char *port = "echo"; + char buf[80]; struct sockaddr_storage client; struct addrinfo hints, *res, *res0; struct itimerval itv; @@ -89,35 +68,20 @@ main(int argc, char *argv[]) struct tm *tm; struct pollfd pfd[1]; socklen_t addrlen; - long interval = 100; /* default interval (ms) */ + long interval = 100; /* default interval (ms) */ long timeout = 500; /* default timeout (ms) */ int ch; int nfds, received = 0; - int error, last = -1; + int error, buffer, last = -1; int disconnected; - int nofragment = 0; - int we_count = 0, counter = 0; /* don't loop forever */ extern int optind; setbuf(stdout, NULL); - while ((ch = getopt(argc, argv, "c:di:l:p:t:v")) != -1) { + while ((ch = getopt(argc, argv, "i:t:v")) != -1) { switch (ch) { - case 'c': - we_count++; - counter = atoi(optarg); - break; - case 'd': - nofragment++; - break; case 'i': interval = atoi(optarg); break; - case 'l': - len = atoi(optarg); - break; - case 'p': - port = optarg; - break; case 't': timeout = atoi(optarg); break; @@ -135,8 +99,7 @@ main(int argc, char *argv[]) if (interval <= 0 || timeout <= 0) errx(2, "interval and timeout must be > 0"); - if (we_count && counter < 2) - errx(2, "can't count down from nothing"); + /* force timeout >= interval */ if (timeout < interval) { timeout = interval; @@ -148,7 +111,7 @@ main(int argc, char *argv[]) memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; - error = getaddrinfo(argv[0], port, &hints, &res0); + error = getaddrinfo(argv[0], "echo", &hints, &res0); if (error) errx(1, "%s: %s", argv[0], gai_strerror(error)); @@ -167,38 +130,21 @@ main(int argc, char *argv[]) disconnected = 0; memset(&client, 0, sizeof(client)); - recvbuf = malloc(len); - if (recvbuf == NULL) - err(2, "malloc receive buffer"); - -#ifdef IP_MTU_DISCOVER - /* set the DF flag ? */ - if (nofragment) - ch = IP_PMTUDISC_DO; - else - ch = IP_PMTUDISC_DONT; - if (setsockopt(sock, IPPROTO_IP, IP_MTU_DISCOVER, &ch, sizeof(ch)) < 0) - err(2, "setsockopt IP_MTU_DISCOVER"); -#endif - signal(SIGALRM, send_packet); - signal(SIGINT, sigint_handler); - /* timer values */ - itv.it_interval.tv_usec = interval*1000; + itv.it_interval.tv_usec = interval*1000; itv.it_interval.tv_sec = 0; itv.it_value.tv_usec = interval*1000; itv.it_value.tv_sec = 0; - if (setitimer(ITIMER_REAL, &itv, NULL) == -1) + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) err(2, "setitimer"); - gettimeofday(&last_ts, NULL); - tm = localtime((time_t *)&last_ts.tv_sec); - strftime(date, sizeof(date), "%F %T", tm); - printf("%s.%06ld: starting\n", date, last_ts.tv_usec); + signal(SIGALRM, send_packet); - while (!aborting) { + gettimeofday(&last_ts, NULL); + + while (1) { /* poll() loop to handle interruptions by SIGALRM */ - while (!aborting) { + while (1) { pfd[0].fd = sock; pfd[0].events = POLLIN; nfds = poll(pfd, 1, timeout); @@ -214,33 +160,31 @@ main(int argc, char *argv[]) break; } } - if (aborting) - break; if ((nfds == 0)) { - if (verbose) + if (verbose) printf("%d packet(s) dropped in %ld.%06ld s\n", - seq - last, (long)diff.tv_sec, diff.tv_usec); - + seq - last, diff.tv_sec, diff.tv_usec); + if (disconnected == 1) { tm = localtime((time_t *)&last_ts.tv_sec); - strftime(date, sizeof(date), "%F %T", tm); + strftime(buf, sizeof(buf), "%F %T", tm); printf("%s.%06ld: lost connection\n", - date, last_ts.tv_usec); + buf, last_ts.tv_usec); } continue; } addrlen = sizeof(client); - if ((received = recvfrom(sock, recvbuf, len, + if ((received = recvfrom(sock, &buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr *) &client, - &addrlen)) != len) { + &addrlen)) != sizeof(buffer)) { warn("recvfrom"); } if (verbose && (serverlen != addrlen || memcmp(&client, server, addrlen) != 0)) { if ((error = getnameinfo((struct sockaddr *)&client, - addrlen, name, sizeof(name), + addrlen, name, sizeof(name), NULL, 0, NI_DGRAM)) != 0) { warnx("%s", gai_strerror(error)); } else { @@ -250,32 +194,17 @@ main(int argc, char *argv[]) } if (disconnected) { tm = localtime((time_t *)&now.tv_sec); - strftime(date, sizeof(date), "%F %T", tm); + strftime(buf, sizeof(buf), "%F %T", tm); printf("%s.%06ld: connection is back " "dropped %d packets\n", - date, now.tv_usec, seq - last); + buf, now.tv_usec, seq - last); disconnected = 0; } - last = strtonum(recvbuf, 0, INT_MAX, &errstr); - if (errstr) - errx(1, "invalid reply %s", errstr); + last = buffer; memcpy(&last_ts, &now, sizeof(struct timeval)); if (verbose) - printf("received %d %ld.%06ld\n", last, + printf("received %d %ld.%06ld\n", buffer, (long)diff.tv_sec, diff.tv_usec); - if (we_count) { - counter--; - if (counter == 0) { - printf("all job done\n"); - break; - } - } - } - if (aborting) { - gettimeofday(&now, NULL); - tm = localtime((time_t *)&now.tv_sec); - strftime(date, sizeof(date), "%F %T", tm); - printf("%s.%06ld: aborting\n", date, now.tv_usec); } close(sock); exit(0);