From cc77b55cfbe61e30a451944d41d9d999838ffffb Mon Sep 17 00:00:00 2001 From: "Joseph C. Lehner" Date: Fri, 29 Jan 2016 23:05:24 +0200 Subject: [PATCH] Use MAC addr of interface when sending packets --- ethsock.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- ethsock.h | 1 + nmrp.c | 7 ++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/ethsock.c b/ethsock.c index 97d2cb5..40d992c 100644 --- a/ethsock.c +++ b/ethsock.c @@ -1,3 +1,8 @@ +#include +#include +#include +#include +#include #include #include #include @@ -13,8 +18,54 @@ struct ethsock pcap_t *pcap; struct timeval timeout; int fd; + uint8_t hwaddr[6]; }; +static bool ethsock_fill_hwaddr(struct ethsock *sock, const char *interface) +{ + struct ifaddrs *ifas, *ifa; + void *src; + bool found; + + if (getifaddrs(&ifas) != 0) { + perror("getifaddrs"); + return false; + } + + found = false; + + for (ifa = ifas; ifa; ifa = ifa->ifa_next) { + if (!strcmp(ifa->ifa_name, interface)) { +#ifdef __linux__ + if (ifa->ifa_addr->sa_family != AF_PACKET) { + continue; + } + src = ((struct sockaddr_ll*)ifa->ifa_addr)->sll_addr; +#else + if (ifa->ifa_addr->sa_family != AF_LINK) { + continue; + } + src = LLADDR((struct sockaddr_dl*)ifa->ifa_addr); +#endif + memcpy(sock->hwaddr, src, 6); + found = true; + break; + } + } + + if (!found) { + fprintf(stderr, "Failed to get MAC address of interface %s.\n", interface); + } + + freeifaddrs(ifas); + return found; +} + +inline uint8_t *ethsock_get_hwaddr(struct ethsock *sock) +{ + return sock->hwaddr; +} + struct ethsock *ethsock_create(const char *interface, uint16_t protocol) { char buf[PCAP_ERRBUF_SIZE]; @@ -28,11 +79,15 @@ struct ethsock *ethsock_create(const char *interface, uint16_t protocol) return NULL; } + if (!ethsock_fill_hwaddr(sock, interface)) { + goto cleanup_malloc; + } + buf[0] = '\0'; sock->pcap = pcap_open_live(interface, BUFSIZ, 1, 1, buf); if (!sock->pcap) { - fprintf(stderr, "pcap_open_live: %s\n", buf); + fprintf(stderr, "%s\n", buf); goto cleanup_malloc; } diff --git a/ethsock.h b/ethsock.h index 458a2d5..6e2c50f 100644 --- a/ethsock.h +++ b/ethsock.h @@ -7,3 +7,4 @@ int ethsock_close(struct ethsock *sock); int ethsock_send(struct ethsock *sock, void *buf, size_t len); ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len); int ethsock_set_timeout(struct ethsock *sock, unsigned msec); +uint8_t *ethsock_get_hwaddr(struct ethsock *sock); diff --git a/nmrp.c b/nmrp.c index dd2388f..43519fc 100644 --- a/nmrp.c +++ b/nmrp.c @@ -249,7 +249,7 @@ static const char *spinner = "\\|/-"; int nmrp_do(struct nmrpd_args *args) { struct nmrp_pkt tx, rx; - uint8_t src[6], dest[6]; + uint8_t *src, dest[6]; struct in_addr ipaddr, ipmask; time_t beg; int i, err, ulreqs, expect; @@ -291,6 +291,11 @@ int nmrp_do(struct nmrpd_args *args) return 1; } + src = ethsock_get_hwaddr(sock); + if (!src) { + return 1; + } + memcpy(tx.eh.ether_shost, src, 6); memcpy(tx.eh.ether_dhost, dest, 6); tx.eh.ether_type = htons(ETH_P_NMRP); -- 2.25.1