Device Emulation (contd.): Create/Update NDP entry when NS with source TLV received; check for NDP entry when sending IPv6 packet
This commit is contained in:
parent
46a09a82e4
commit
21197146e2
@ -625,8 +625,11 @@ void Device::sendIp4Reply(PacketBuffer *pktBuf)
|
||||
dstIp = qFromBigEndian<quint32>(pktData + 12); // srcIp in original pkt
|
||||
srcIp = qFromBigEndian<quint32>(pktData + 16); // dstIp in original pkt
|
||||
|
||||
if (!arpTable_.contains(dstIp))
|
||||
if (!arpTable_.contains(dstIp)) {
|
||||
qWarning("%s: mac not found for %s; unable to send IPv4 packet",
|
||||
__FUNCTION__, qPrintable(QHostAddress(dstIp).toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
*(quint32*)(pktData + 12) = qToBigEndian(srcIp);
|
||||
*(quint32*)(pktData + 16) = qToBigEndian(dstIp);
|
||||
@ -727,7 +730,7 @@ bool Device::sendIp6(PacketBuffer *pktBuf, UInt128 dstIp, quint8 protocol)
|
||||
{
|
||||
int payloadLen = pktBuf->length();
|
||||
uchar *p = pktBuf->push(kIp6HdrLen);
|
||||
quint64 dstMac = kBcastMac;
|
||||
quint64 dstMac = ndpTable_.value(dstIp);
|
||||
|
||||
if (!p) {
|
||||
qWarning("%s: failed to push %d bytes [0x%p, 0x%p]", __FUNCTION__,
|
||||
@ -735,6 +738,17 @@ bool Device::sendIp6(PacketBuffer *pktBuf, UInt128 dstIp, quint8 protocol)
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
// In case of mcast, derive dstMac
|
||||
if ((dstIp.hi64() >> 56) == 0xff)
|
||||
dstMac = (quint64(0x3333) << 32) | (dstIp.lo64() & 0xffffffff);
|
||||
|
||||
if (!dstMac) {
|
||||
qWarning("%s: mac not found for %s; unable to send IPv6 packet",
|
||||
__FUNCTION__,
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()));
|
||||
goto _error_exit;
|
||||
}
|
||||
|
||||
// Ver(4), TrfClass(8), FlowLabel(8)
|
||||
*(quint32*)(p ) = qToBigEndian(quint32(0x60000000));
|
||||
*(quint16*)(p+ 4) = qToBigEndian(quint16(payloadLen));
|
||||
@ -743,10 +757,6 @@ bool Device::sendIp6(PacketBuffer *pktBuf, UInt128 dstIp, quint8 protocol)
|
||||
memcpy(p+ 8, ip6_.toArray(), 16); // Source IP
|
||||
memcpy(p+24, dstIp.toArray(), 16); // Destination IP
|
||||
|
||||
// In case of mcast, derive dstMac
|
||||
if ((dstIp.hi64() >> 56) == 0xff)
|
||||
dstMac = (quint64(0x3333) << 32) | (dstIp.lo64() & 0xffffffff);
|
||||
|
||||
// FIXME: both these functions should return success/failure
|
||||
encap(pktBuf, dstMac, kEthTypeIp6);
|
||||
transmitPacket(pktBuf);
|
||||
@ -771,8 +781,12 @@ void Device::sendIp6Reply(PacketBuffer *pktBuf)
|
||||
dstIp = qFromBigEndian<UInt128>(pktData + 8); // srcIp in original pkt
|
||||
srcIp = qFromBigEndian<UInt128>(pktData + 24); // dstIp in original pkt
|
||||
|
||||
if (!ndpTable_.contains(dstIp))
|
||||
if (!ndpTable_.contains(dstIp)) {
|
||||
qWarning("%s: mac not found for %s; unable to send IPv6 packet",
|
||||
__FUNCTION__,
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(pktData + 8, srcIp.toArray(), 16); // Source IP
|
||||
memcpy(pktData + 24, dstIp.toArray(), 16); // Destination IP
|
||||
@ -970,6 +984,14 @@ void Device::sendNeighborAdvertisement(PacketBuffer *pktBuf)
|
||||
// NA should be sent to All nodes address
|
||||
srcIp = UInt128(quint64(0xff02) << 48, quint64(1));
|
||||
}
|
||||
else if (pktBuf->length() >= 32) { // have TLVs?
|
||||
if ((pktData[24] == 0x01) && (pktData[25] == 0x01)) { // Source TLV
|
||||
quint64 mac;
|
||||
mac = qFromBigEndian<quint32>(pktData + 26);
|
||||
mac = (mac << 16) | qFromBigEndian<quint16>(pktData + 30);
|
||||
ndpTable_.insert(srcIp, mac);
|
||||
}
|
||||
}
|
||||
|
||||
naPkt = new PacketBuffer;
|
||||
naPkt->reserve(encapSize() + kIp6HdrLen);
|
||||
|
Loading…
Reference in New Issue
Block a user