Use MAC addr of interface when sending packets
This commit is contained in:
parent
47c00c9002
commit
cc77b55cfb
3 changed files with 63 additions and 2 deletions
57
ethsock.c
57
ethsock.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
7
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue