feature:add ipv6 conflict check function
This commit is contained in:
parent
c2a1efa633
commit
bcad10d46f
|
@ -9,6 +9,7 @@ HEADERS += \
|
|||
$$PWD/kylin-dbus-interface.h \
|
||||
$$PWD/kylin-network-interface.h \
|
||||
$$PWD/kylinipv4arping.h \
|
||||
$$PWD/kylinipv6arping.h \
|
||||
$$PWD/sysdbusregister.h \
|
||||
$$PWD/utils.h \
|
||||
$$PWD/wifi-auth-thread.h
|
||||
|
@ -20,6 +21,7 @@ SOURCES += \
|
|||
$$PWD/kylin-dbus-interface.cpp \
|
||||
$$PWD/kylin-network-interface.c \
|
||||
$$PWD/kylinipv4arping.cpp \
|
||||
$$PWD/kylinipv6arping.cpp \
|
||||
$$PWD/sysdbusregister.cpp \
|
||||
$$PWD/utils.cpp \
|
||||
$$PWD/wifi-auth-thread.cpp
|
||||
|
|
|
@ -91,7 +91,7 @@ int KyIpv4Arping::sendIpv4Packet()
|
|||
memcpy(p, &p_me->sll_addr, ah->ar_hln);
|
||||
p += p_me->sll_halen;
|
||||
|
||||
qWarning()<<"m_src address:" << inet_ntoa(m_srcAddress);
|
||||
qWarning()<<"[KyIpv4Arping]" <<"m_src address:" << inet_ntoa(m_srcAddress);
|
||||
memcpy(p, &m_srcAddress, 4);
|
||||
p += 4;
|
||||
|
||||
|
@ -237,7 +237,7 @@ int KyIpv4Arping::ipv4EventLoop()
|
|||
case POLLFD_TIMER:
|
||||
bytes = read(tfd, &exp, sizeof(uint64_t));
|
||||
if (bytes != sizeof(uint64_t)) {
|
||||
qWarning() << "could not read timerfd";
|
||||
qWarning() <<"[KyIpv4Arping]" << "could not read timerfd";
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ int KyIpv4Arping::ipv4EventLoop()
|
|||
bytes = recvfrom(m_ipv4Socket, packet, sizeof(packet), 0,
|
||||
(struct sockaddr *)&from, &addr_len);
|
||||
if (bytes < 0) {
|
||||
qWarning() << "recvfrom function failed, errno" << errno;
|
||||
qWarning()<<"[KyIpv4Arping]" << "recvfrom function failed, errno" << errno;
|
||||
continue;
|
||||
}
|
||||
if (ipv4PacketProcess(packet, bytes, (struct sockaddr_ll *)&from) == FINAL_PACKS) {
|
||||
|
@ -263,7 +263,7 @@ int KyIpv4Arping::ipv4EventLoop()
|
|||
}
|
||||
break;
|
||||
default:
|
||||
qWarning()<<"the fd index is undefine" << index;
|
||||
qWarning()<<"[KyIpv4Arping]" <<"the fd index is undefine" << index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -278,12 +278,12 @@ int KyIpv4Arping::ipv4EventLoop()
|
|||
int KyIpv4Arping::checkIfflags(unsigned int ifflags)
|
||||
{
|
||||
if (!(ifflags & IFF_UP)) {
|
||||
qWarning()<<"the iface" << m_ifaceName <<" is down.";
|
||||
qWarning()<<"[KyIpv4Arping]" <<"the iface" << m_ifaceName <<" is down.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ifflags & (IFF_NOARP | IFF_LOOPBACK)) {
|
||||
qWarning()<< "Interface" << m_ifaceName << "is not ARPable.";
|
||||
qWarning()<<"[KyIpv4Arping]" << "Interface" << m_ifaceName << "is not ARPable.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,394 @@
|
|||
#include "kylinipv6arping.h"
|
||||
|
||||
#include <sys/times.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
|
||||
KyIpv6Arping::KyIpv6Arping(QString ifaceName, QString ipAddress, int retryCount, int timeout, QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_ifaceName = ifaceName;
|
||||
m_ipv6Address = ipAddress;
|
||||
m_retryCount = retryCount;
|
||||
m_timeoutMs = timeout;
|
||||
|
||||
m_ipv6Conflict = false;
|
||||
}
|
||||
|
||||
KyIpv6Arping::~KyIpv6Arping()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void KyIpv6Arping::monoGetTime (struct timespec *ts)
|
||||
{
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
if (clock_gettime (CLOCK_MONOTONIC, ts))
|
||||
#endif
|
||||
{
|
||||
static long freq = 0;
|
||||
if (freq == 0)
|
||||
freq = sysconf (_SC_CLK_TCK);
|
||||
|
||||
struct tms dummy;
|
||||
clock_t t = times (&dummy);
|
||||
ts->tv_sec = t / freq;
|
||||
ts->tv_nsec = (t % freq) * (1000000000 / freq);
|
||||
}
|
||||
}
|
||||
|
||||
int KyIpv6Arping::getLocalMacAddress(const char *ifname, unsigned char *addr)
|
||||
{
|
||||
# ifdef SIOCGIFHWADDR
|
||||
struct ifreq req;
|
||||
memset (&req, 0, sizeof (req));
|
||||
|
||||
if (((unsigned)strlen (ifname)) >= (unsigned)IFNAMSIZ) {
|
||||
return -1; /* buffer overflow = local root */
|
||||
}
|
||||
|
||||
strcpy (req.ifr_name, ifname);
|
||||
|
||||
int fd = socket (AF_INET6, SOCK_DGRAM, 0);
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl (fd, SIOCGIFHWADDR, &req)) {
|
||||
qWarning()<<"[KyIpv6Arping]"<<"get local mac address failed, errno" << errno;
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
close (fd);
|
||||
|
||||
memcpy (addr, req.ifr_hwaddr.sa_data, 6);
|
||||
return 0;
|
||||
# else
|
||||
/* No SIOCGIFHWADDR, which seems Linux specific. */
|
||||
struct ifaddrs *ifa = NULL;
|
||||
struct ifaddrs *ifp = NULL;
|
||||
getifaddrs(&ifa);
|
||||
ifp = ifa; /* preserve the address of ifa to free memory later */
|
||||
while (ifp != NULL) {
|
||||
if (ifp->ifa_addr->sa_family == AF_LINK && strcmp(ifp->ifa_name, ifname) == 0) {
|
||||
const struct sockaddr_dl* sdl = (const struct sockaddr_dl*) ifp->ifa_addr;
|
||||
memcpy(addr, sdl->sdl_data + sdl->sdl_nlen, 6);
|
||||
freeifaddrs(ifa);
|
||||
return 0;
|
||||
}
|
||||
ifp = ifp->ifa_next;
|
||||
}
|
||||
freeifaddrs(ifa);
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
int KyIpv6Arping::getIpv6ByName(struct sockaddr_in6 *addr)
|
||||
{
|
||||
struct addrinfo hints, *res;
|
||||
memset (&hints, 0, sizeof (hints));
|
||||
hints.ai_family = PF_INET6;
|
||||
hints.ai_socktype = SOCK_DGRAM; /* dummy */
|
||||
hints.ai_flags = 0;
|
||||
|
||||
int val = getaddrinfo (m_ipv6Address.toUtf8(), NULL, &hints, &res);
|
||||
if (val) {
|
||||
qWarning()<<"[KyIpv6Arping]" << m_ipv6Address <<"get addrinfo failed, errno" << val;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy (addr, res->ai_addr, sizeof (struct sockaddr_in6));
|
||||
freeaddrinfo (res);
|
||||
|
||||
val = if_nametoindex (m_ifaceName.toUtf8());
|
||||
if (val == 0) {
|
||||
qWarning()<<"[KyIpv6Arping]" <<"if_nametoindex failed, errno" << errno;
|
||||
return -1;
|
||||
}
|
||||
addr->sin6_scope_id = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KyIpv6Arping::buildSolicitationPacket(solicit_packet *ns, struct sockaddr_in6 *tgt, const char *ifname)
|
||||
{
|
||||
/* builds ICMPv6 Neighbor Solicitation packet */
|
||||
ns->hdr.nd_ns_type = ND_NEIGHBOR_SOLICIT;
|
||||
ns->hdr.nd_ns_code = 0;
|
||||
ns->hdr.nd_ns_cksum = 0; /* computed by the kernel */
|
||||
ns->hdr.nd_ns_reserved = 0;
|
||||
memcpy (&ns->hdr.nd_ns_target, &tgt->sin6_addr, 16);
|
||||
|
||||
/* determines actual multicast destination address */
|
||||
memcpy (&tgt->sin6_addr.s6_addr, "\xff\x02\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x01\xff", 13);
|
||||
|
||||
/* gets our own interface's link-layer address (MAC) */
|
||||
if (getLocalMacAddress (m_ifaceName.toUtf8().constData(), ns->hw_addr)) {
|
||||
return sizeof (ns->hdr);
|
||||
}
|
||||
|
||||
ns->opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR;
|
||||
ns->opt.nd_opt_len = 1; /* 8 bytes */
|
||||
return sizeof (*ns);
|
||||
}
|
||||
|
||||
void KyIpv6Arping::saveMacAddress (const uint8_t *ptr, size_t len)
|
||||
{
|
||||
int index;
|
||||
char macAddress[64] = {0};
|
||||
|
||||
for (index = 0; index < len; index++) {
|
||||
snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%02X", ptr[index]);
|
||||
if (index != len - 1) {
|
||||
snprintf(&macAddress[strlen(macAddress)], sizeof(macAddress) - strlen(macAddress), "%s", ":");
|
||||
}
|
||||
}
|
||||
|
||||
m_conflictMacAddress = QString(macAddress);
|
||||
return ;
|
||||
}
|
||||
|
||||
int KyIpv6Arping::parseIpv6Packet(const uint8_t *buf, size_t len, const struct sockaddr_in6 *tgt)
|
||||
{
|
||||
const struct nd_neighbor_advert *na =
|
||||
(const struct nd_neighbor_advert *)buf;
|
||||
const uint8_t *ptr;
|
||||
|
||||
/* checks if the packet is a Neighbor Advertisement, and
|
||||
* if the target IPv6 address is the right one */
|
||||
if ((len < sizeof (struct nd_neighbor_advert))
|
||||
|| (na->nd_na_type != ND_NEIGHBOR_ADVERT)
|
||||
|| (na->nd_na_code != 0)
|
||||
|| memcmp (&na->nd_na_target, &tgt->sin6_addr, 16)) {
|
||||
return -1;
|
||||
}
|
||||
len -= sizeof (struct nd_neighbor_advert);
|
||||
|
||||
/* looks for Target Link-layer address option */
|
||||
ptr = buf + sizeof (struct nd_neighbor_advert);
|
||||
|
||||
while (len >= 8)
|
||||
{
|
||||
uint16_t optlen;
|
||||
|
||||
optlen = ((uint16_t)(ptr[1])) << 3;
|
||||
if (optlen == 0)
|
||||
break; /* invalid length */
|
||||
|
||||
if (len < optlen) /* length > remaining bytes */
|
||||
break;
|
||||
len -= optlen;
|
||||
|
||||
|
||||
/* skips unrecognized option */
|
||||
if (ptr[0] != ND_OPT_TARGET_LINKADDR)
|
||||
{
|
||||
ptr += optlen;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Found! displays link-layer address */
|
||||
ptr += 2;
|
||||
optlen -= 2;
|
||||
|
||||
saveMacAddress (ptr, optlen);
|
||||
setIpv6ConflictFlag(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int KyIpv6Arping::readIpv6Packet(void *buf,
|
||||
size_t len,
|
||||
int flags,
|
||||
struct sockaddr_in6 *addr)
|
||||
{
|
||||
char cbuf[CMSG_SPACE (sizeof (int))];
|
||||
|
||||
struct iovec iov = {
|
||||
.iov_base = buf,
|
||||
.iov_len = len
|
||||
};
|
||||
|
||||
struct msghdr hdr = {
|
||||
.msg_name = addr,
|
||||
.msg_namelen = sizeof (*addr),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = cbuf,
|
||||
.msg_controllen = sizeof (cbuf)
|
||||
};
|
||||
|
||||
ssize_t val = recvmsg (m_ipv6Socket, &hdr, flags);
|
||||
if (val == -1) {
|
||||
return val;
|
||||
}
|
||||
|
||||
/* ensures the hop limit is 255 */
|
||||
for (struct cmsghdr *cmsg = CMSG_FIRSTHDR (&hdr);
|
||||
cmsg != NULL; cmsg = CMSG_NXTHDR (&hdr, cmsg)) {
|
||||
if ((cmsg->cmsg_level == IPPROTO_IPV6)
|
||||
&& (cmsg->cmsg_type == IPV6_HOPLIMIT)) {
|
||||
if (255 != *(int *)CMSG_DATA (cmsg)) {
|
||||
// pretend to be a spurious wake-up
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int KyIpv6Arping::reciveAndProcessIpv6Packet(const struct sockaddr_in6 *tgt, unsigned wait_ms)
|
||||
{
|
||||
struct timespec end;
|
||||
struct pollfd fds;
|
||||
|
||||
/* computes deadline time */
|
||||
monoGetTime (&end);
|
||||
div_t d;
|
||||
d = div (wait_ms, 1000);
|
||||
end.tv_sec = end.tv_sec + d.quot;
|
||||
end.tv_nsec = end.tv_nsec + (d.rem * 1000000);
|
||||
|
||||
/* receive loop */
|
||||
for (;;)
|
||||
{
|
||||
/* waits for reply until deadline */
|
||||
struct timespec now;
|
||||
int val = 0;
|
||||
|
||||
monoGetTime (&now);
|
||||
if (end.tv_sec >= now.tv_sec) {
|
||||
val = (end.tv_sec - now.tv_sec) * 1000
|
||||
+ (int)((end.tv_nsec - now.tv_nsec) / 1000000);
|
||||
if (val < 0) {
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fds.fd = m_ipv6Socket;
|
||||
fds.events = POLLIN;
|
||||
val = poll (&fds, 1, val);
|
||||
if (val < 0)
|
||||
break;
|
||||
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
/* receives an ICMPv6 packet */
|
||||
// TODO: use interface MTU as buffer size
|
||||
uint8_t buf[1460];
|
||||
struct sockaddr_in6 addr;
|
||||
|
||||
val = readIpv6Packet(buf, sizeof (buf), MSG_DONTWAIT, &addr);
|
||||
if (val < 0) {
|
||||
if (errno != EAGAIN)
|
||||
qWarning()<<"[KyIpv6Arping]"<<"Receiving ICMPv6 packet failed";
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ensures the response came through the right interface */
|
||||
if (addr.sin6_scope_id
|
||||
&& (addr.sin6_scope_id != tgt->sin6_scope_id))
|
||||
continue;
|
||||
|
||||
if (parseIpv6Packet(buf, val, tgt) == 0) {
|
||||
return 1 /* = responses */;
|
||||
}
|
||||
}
|
||||
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
|
||||
int KyIpv6Arping::ipv6ConflictCheck()
|
||||
{
|
||||
struct sockaddr_in6 tgt;
|
||||
struct icmp6_filter filter;
|
||||
int retry = 0;
|
||||
|
||||
m_ipv6Socket = socket (PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
|
||||
if (m_ipv6Socket < 0) {
|
||||
qDebug()<<"[KyIpv6Arping]" <<"create ipv6 socket failed:";
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl (m_ipv6Socket, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* set ICMPv6 filter */
|
||||
ICMP6_FILTER_SETBLOCKALL (&filter);
|
||||
ICMP6_FILTER_SETPASS (ND_NEIGHBOR_ADVERT, &filter);
|
||||
setsockopt (m_ipv6Socket, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof (filter));
|
||||
|
||||
int soDontRoute = 1;
|
||||
setsockopt (m_ipv6Socket, SOL_SOCKET, SO_DONTROUTE, &soDontRoute, sizeof(soDontRoute));
|
||||
|
||||
/* sets Hop-by-hop limit to 255 */
|
||||
int multicastHopLimit = 255;
|
||||
setsockopt (m_ipv6Socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
|
||||
&multicastHopLimit, sizeof (multicastHopLimit));
|
||||
|
||||
int unicastHops = 255;
|
||||
setsockopt (m_ipv6Socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
|
||||
&unicastHops, sizeof (unicastHops));
|
||||
|
||||
int recvHopLimit = 1;
|
||||
setsockopt(m_ipv6Socket, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
|
||||
&recvHopLimit, sizeof (recvHopLimit));
|
||||
|
||||
/* resolves target's IPv6 address */
|
||||
int ret = getIpv6ByName(&tgt);
|
||||
if (ret < 0) {
|
||||
qWarning()<<"[KyIpv6Arping]"<<"get ipv6 by name failed.";
|
||||
close (m_ipv6Socket);
|
||||
return ret;
|
||||
}
|
||||
|
||||
solicit_packet packet;
|
||||
struct sockaddr_in6 dst;
|
||||
ssize_t plen;
|
||||
|
||||
memcpy (&dst, &tgt, sizeof (dst));
|
||||
plen = buildSolicitationPacket(&packet, &dst, m_ifaceName.toUtf8().constData());
|
||||
if (plen == -1) {
|
||||
qWarning()<<"[KyIpv6Arping]"<<"build solicit packet failed.";
|
||||
close (m_ipv6Socket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (retry < m_retryCount) {
|
||||
/* sends a Solitication */
|
||||
if (sendto (m_ipv6Socket, &packet, plen, MSG_DONTROUTE,
|
||||
(const struct sockaddr *)&dst,
|
||||
sizeof (dst)) != plen) {
|
||||
qWarning()<<"[KyIpv6Arping]"<<"Sending ICMPv6 packet failed.";
|
||||
close (m_ipv6Socket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
retry++;
|
||||
|
||||
/* receives an Advertisement */
|
||||
ssize_t val = reciveAndProcessIpv6Packet(&tgt, m_timeoutMs);
|
||||
if (val > 0) {
|
||||
close (m_ipv6Socket);
|
||||
return 0;
|
||||
} else if (val == 0) {
|
||||
continue;
|
||||
} else {
|
||||
close (m_ipv6Socket);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
close(m_ipv6Socket);
|
||||
|
||||
if (retry == m_retryCount) {
|
||||
return 0;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef KYLINIPV6ARPING_H
|
||||
#define KYLINIPV6ARPING_H
|
||||
|
||||
//#include <gettext.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> /* div() */
|
||||
#include <inttypes.h> /* uint8_t */
|
||||
#include <limits.h> /* UINT_MAX */
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <errno.h> /* EMFILE */
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h> /* close() */
|
||||
#include <time.h> /* clock_gettime() */
|
||||
#include <poll.h> /* poll() */
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
//#include "gettime.h"
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include <netdb.h> /* getaddrinfo() */
|
||||
#include <arpa/inet.h> /* inet_ntop() */
|
||||
#include <net/if.h> /* if_nametoindex() */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#ifndef IPV6_RECVHOPLIMIT
|
||||
/* Using obsolete RFC 2292 instead of RFC 3542 */
|
||||
# define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
|
||||
#endif
|
||||
|
||||
/* BSD-like systems define ND_RA_FLAG_HA instead of ND_RA_FLAG_HOME_AGENT */
|
||||
#ifndef ND_RA_FLAG_HOME_AGENT
|
||||
# ifdef ND_RA_FLAG_HA
|
||||
# define ND_RA_FLAG_HOME_AGENT ND_RA_FLAG_HA
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef AI_IDN
|
||||
# define AI_IDN 0
|
||||
#endif
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct nd_neighbor_solicit hdr;
|
||||
struct nd_opt_hdr opt;
|
||||
uint8_t hw_addr[6];
|
||||
} solicit_packet;
|
||||
|
||||
class KyIpv6Arping: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KyIpv6Arping(QString ifaceName, QString ipAddress, int retryCount=3, int timeout=1000, QObject *parent = nullptr);
|
||||
~KyIpv6Arping();
|
||||
|
||||
public:
|
||||
bool ipv6IsConflict() {
|
||||
return m_ipv6Conflict;
|
||||
}
|
||||
|
||||
void setIpv6ConflictFlag(bool conflict) {
|
||||
m_ipv6Conflict = conflict;
|
||||
}
|
||||
|
||||
QString getConflictMacAddress() {
|
||||
return m_conflictMacAddress;
|
||||
}
|
||||
|
||||
int ipv6ConflictCheck();
|
||||
|
||||
private:
|
||||
void monoGetTime (struct timespec *ts);
|
||||
void saveMacAddress (const uint8_t *ptr, size_t len);
|
||||
int getLocalMacAddress(const char *ifname, unsigned char *addr);
|
||||
|
||||
int getIpv6ByName(struct sockaddr_in6 *addr);
|
||||
int buildSolicitationPacket(solicit_packet *ns, struct sockaddr_in6 *tgt, const char *ifname);
|
||||
int parseIpv6Packet(const uint8_t *buf, size_t len, const struct sockaddr_in6 *tgt);
|
||||
int readIpv6Packet(void *buf, size_t len, int flags, struct sockaddr_in6 *addr);
|
||||
int reciveAndProcessIpv6Packet(const struct sockaddr_in6 *tgt, unsigned wait_ms);
|
||||
|
||||
private:
|
||||
int m_ipv6Socket = 0;
|
||||
|
||||
QString m_ifaceName;
|
||||
QString m_ipv6Address;
|
||||
int m_retryCount;
|
||||
int m_timeoutMs;
|
||||
|
||||
bool m_ipv6Conflict = false;
|
||||
QString m_conflictMacAddress = nullptr;
|
||||
};
|
||||
|
||||
#endif // KYLINIPV6ARPING_H
|
Loading…
Reference in New Issue