summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2019-12-20 14:48:47 +0000
committerThomas Habets <thomas@habets.se>2019-12-20 14:48:47 +0000
commit24860ea35d94ae53c0c978e0757449b6ede7e623 (patch)
treeda856ff8e1ae3d94edbb2e9f3a103c01df979c10
parent0ec71e7bf46ad82124ba4b1f95b3609b28135498 (diff)
downloadarping-24860ea35d94ae53c0c978e0757449b6ede7e623.tar.gz
Add timestamp and magic suffix as payload to mac ping (ICMP PING)
Fixes #7
-rw-r--r--configure.ac3
-rw-r--r--src/arping.c79
2 files changed, 77 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index 03ed4cb..b13f883 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,7 @@ sys/capability.h \
stdint.h \
libnet.h \
win32/libnet.h \
+sys/random.h \
net/bpf.h \
pwd.h \
unistd.h])
@@ -75,7 +76,7 @@ AC_FUNC_SETVBUF_REVERSED
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([gettimeofday memset select strchr strdup strerror strstr \
getifaddrs cap_init pcap_create pcap_list_tstamp_types pcap_set_immediate_mode \
-pledge unveil pcap_findalldevs])
+pledge unveil pcap_findalldevs getrandom])
if test x$ac_cv_func_getifaddrs = xyes; then
AC_LIBOBJ([findif_getifaddrs])
diff --git a/src/arping.c b/src/arping.c
index d1855a1..2f00da9 100644
--- a/src/arping.c
+++ b/src/arping.c
@@ -73,6 +73,10 @@
#include <sys/param.h>
#endif
+#if HAVE_SYS_RANDOM_H
+#include <sys/random.h>
+#endif
+
#if HAVE_GRP_H
#include <grp.h>
#endif
@@ -165,6 +169,9 @@ uint32_t dstip;
*/
static uint8_t dstmac[ETH_ALEN];
+static char* payload_suffix = NULL;
+static ssize_t payload_suffix_size = -1;
+
uint32_t srcip; /* autodetected, override with -S/-b/-0 */
uint8_t srcmac[ETH_ALEN]; /* autodetected, override with -s */
@@ -212,6 +219,20 @@ int verbose = 0; /* Increase with -v */
/* Doesn't really need to be volatile, but doesn't hurt. */
static volatile sig_atomic_t time_to_die = 0;
+static ssize_t
+xgetrandom(void *buf, const size_t buflen, const unsigned int flags)
+{
+#ifdef HAVE_GETRANDOM
+ return getrandom(buf, buflen, flags);
+#else
+ char* p = buf;
+ for (int n = 0; n < buflen; n++) {
+ p[n] = random() & 0xff;
+ }
+ return buflen;
+#endif
+}
+
/**
* If possible, chroot.
*
@@ -958,8 +979,6 @@ static char *ts2str(const struct timespec *tv, const struct timespec *tv2,
return buf;
}
-
-
/** Send directed IPv4 ICMP echo request.
*
* \param id IP id
@@ -974,7 +993,16 @@ pingmac_send(uint16_t id, uint16_t seq)
// Without this padding some systems (e.g. Raspberry Pi 3
// wireless interface) failed. dmesg said:
// arping: packet size is too short (42 <= 50)
- const uint8_t padding[16] = {0};
+ const size_t padding_size = sizeof(struct timespec) + payload_suffix_size;
+ uint8_t padding[padding_size];
+ memset(padding, 0, padding_size);
+ {
+ struct timespec ts;
+ getclock(&ts);
+ memcpy(padding, &ts, sizeof(struct timespec));
+ memcpy(&padding[sizeof(struct timespec)],
+ payload_suffix, payload_suffix_size);
+ }
int c;
@@ -1398,8 +1426,19 @@ pingmac_recv(const char* unused, struct pcap_pkthdr *h, uint8_t *packet)
if (payload_size < 0) {
return;
}
+ if (payload_size < sizeof(struct timespec) + payload_suffix_size) {
+ return;
+ }
+ if (verbose > 3) {
+ printf("arping: ... correct payload size (%d)\n",
+ payload_size);
+ }
+ if (memcmp(&payload[sizeof(struct timespec)],
+ payload_suffix, payload_suffix_size)) {
+ return;
+ }
if (verbose > 3) {
- printf("arping: ... payload size: %d\n", payload_size);
+ printf("arping: ... correct payload suffix\n");
}
update_stats(timespec2dbl(&arrival) - timespec2dbl(&lastpacketsent));
@@ -1646,6 +1685,7 @@ arping_main(int argc, char **argv)
double deadline = -1;
char bpf_filter[64];
ebuf[0] = 0;
+ srandom(time(NULL));
for (c = 1; c < argc; c++) {
if (!strcmp(argv[c], "--help")) {
@@ -1800,6 +1840,37 @@ arping_main(int argc, char **argv)
exit(1);
}
+ // Generate random payload suffix for MAC pings, to be able to
+ // differentiate from unrelated ping replies.
+ if (payload_suffix_size < 0) {
+ payload_suffix_size = 4;
+ payload_suffix = malloc(payload_suffix_size);
+ if (payload_suffix) {
+ const ssize_t rc = xgetrandom(payload_suffix, payload_suffix_size, 0);
+ if (rc == -1) {
+ fprintf(stderr,
+ "arping: failed to get %d random bytes: %s\n",
+ payload_suffix_size,
+ strerror(errno));
+ free(payload_suffix);
+ payload_suffix = NULL;
+ } else if (payload_suffix_size != rc) {
+ fprintf(stderr,
+ "arping: only got %d out of %d bytes for random suffix\n",
+ rc, payload_suffix_size);
+ }
+ } else {
+ fprintf(stderr, "arping: failed to allocate %d bytes for payload suffix.\n",
+ payload_suffix_size);
+ }
+
+ if (!payload_suffix) {
+ fprintf(stderr, "arping: Using constant suffix.\n");
+ payload_suffix = "arping";
+ payload_suffix_size = strlen(payload_suffix);
+ }
+ }
+
if (((mode == PINGIP) && opt_T)
|| ((mode == PINGMAC) && (opt_B || dstmac_opt || opt_U))) {
fprintf(stderr, "arping: -T can only be used to ping MAC"