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
|
dstIp = qFromBigEndian<quint32>(pktData + 12); // srcIp in original pkt
|
||||||
srcIp = qFromBigEndian<quint32>(pktData + 16); // dstIp 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*(quint32*)(pktData + 12) = qToBigEndian(srcIp);
|
*(quint32*)(pktData + 12) = qToBigEndian(srcIp);
|
||||||
*(quint32*)(pktData + 16) = qToBigEndian(dstIp);
|
*(quint32*)(pktData + 16) = qToBigEndian(dstIp);
|
||||||
@ -727,7 +730,7 @@ bool Device::sendIp6(PacketBuffer *pktBuf, UInt128 dstIp, quint8 protocol)
|
|||||||
{
|
{
|
||||||
int payloadLen = pktBuf->length();
|
int payloadLen = pktBuf->length();
|
||||||
uchar *p = pktBuf->push(kIp6HdrLen);
|
uchar *p = pktBuf->push(kIp6HdrLen);
|
||||||
quint64 dstMac = kBcastMac;
|
quint64 dstMac = ndpTable_.value(dstIp);
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
qWarning("%s: failed to push %d bytes [0x%p, 0x%p]", __FUNCTION__,
|
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;
|
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)
|
// Ver(4), TrfClass(8), FlowLabel(8)
|
||||||
*(quint32*)(p ) = qToBigEndian(quint32(0x60000000));
|
*(quint32*)(p ) = qToBigEndian(quint32(0x60000000));
|
||||||
*(quint16*)(p+ 4) = qToBigEndian(quint16(payloadLen));
|
*(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+ 8, ip6_.toArray(), 16); // Source IP
|
||||||
memcpy(p+24, dstIp.toArray(), 16); // Destination 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
|
// FIXME: both these functions should return success/failure
|
||||||
encap(pktBuf, dstMac, kEthTypeIp6);
|
encap(pktBuf, dstMac, kEthTypeIp6);
|
||||||
transmitPacket(pktBuf);
|
transmitPacket(pktBuf);
|
||||||
@ -771,8 +781,12 @@ void Device::sendIp6Reply(PacketBuffer *pktBuf)
|
|||||||
dstIp = qFromBigEndian<UInt128>(pktData + 8); // srcIp in original pkt
|
dstIp = qFromBigEndian<UInt128>(pktData + 8); // srcIp in original pkt
|
||||||
srcIp = qFromBigEndian<UInt128>(pktData + 24); // dstIp 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(pktData + 8, srcIp.toArray(), 16); // Source IP
|
memcpy(pktData + 8, srcIp.toArray(), 16); // Source IP
|
||||||
memcpy(pktData + 24, dstIp.toArray(), 16); // Destination 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
|
// NA should be sent to All nodes address
|
||||||
srcIp = UInt128(quint64(0xff02) << 48, quint64(1));
|
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 = new PacketBuffer;
|
||||||
naPkt->reserve(encapSize() + kIp6HdrLen);
|
naPkt->reserve(encapSize() + kIp6HdrLen);
|
||||||
|
Loading…
Reference in New Issue
Block a user