diff options
author | Thomas Habets <thomas@habets.se> | 2019-12-20 14:48:47 +0000 |
---|---|---|
committer | Thomas Habets <thomas@habets.se> | 2019-12-20 14:48:47 +0000 |
commit | 24860ea35d94ae53c0c978e0757449b6ede7e623 (patch) | |
tree | da856ff8e1ae3d94edbb2e9f3a103c01df979c10 | |
parent | 0ec71e7bf46ad82124ba4b1f95b3609b28135498 (diff) | |
download | arping-24860ea35d94ae53c0c978e0757449b6ede7e623.tar.gz |
Add timestamp and magic suffix as payload to mac ping (ICMP PING)
Fixes #7
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/arping.c | 79 |
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" |