Use MAC addr of interface when sending packets

This commit is contained in:
Joseph C. Lehner 2016-01-29 23:05:24 +02:00
parent 47c00c9002
commit cc77b55cfb
3 changed files with 63 additions and 2 deletions

View file

@ -1,3 +1,8 @@
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if_dl.h>
#include <stdbool.h>
#include <ifaddrs.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@ -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;
}

View file

@ -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);

7
nmrp.c
View file

@ -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);