+#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>
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];
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;
}
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);
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;
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);