[mac] change address filter and seek function to accept frame without PAN ID (#5389)

In 802.15.4-2015 spec Table 7-2, it is possible to receive frame with
destination address but without destination PAN ID. This commit
changes the address filter function to avoid dropping such frames.
This commit is contained in:
Jintao Lin
2020-08-17 22:34:38 -07:00
committed by GitHub
parent 5e34b5062d
commit 3f38068a71
5 changed files with 85 additions and 68 deletions
+6 -8
View File
@@ -39,7 +39,7 @@ bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
const otExtAddress *aExtAddress)
{
const Mac::Frame &frame = *static_cast<const Mac::Frame *>(aFrame);
bool rval = false;
bool rval = true;
Mac::Address dst;
Mac::PanId panid;
@@ -48,22 +48,20 @@ bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
switch (dst.GetType())
{
case Mac::Address::kTypeShort:
SuccessOrExit(frame.GetDstPanId(panid));
rval = (panid == Mac::kPanIdBroadcast || panid == aPanId) &&
(dst.GetShort() == Mac::kShortAddrBroadcast || dst.GetShort() == aShortAddress);
VerifyOrExit(dst.GetShort() == Mac::kShortAddrBroadcast || dst.GetShort() == aShortAddress, rval = false);
break;
case Mac::Address::kTypeExtended:
SuccessOrExit(frame.GetDstPanId(panid));
rval = (panid == Mac::kPanIdBroadcast || panid == aPanId) &&
dst.GetExtended() == *static_cast<const Mac::ExtAddress *>(aExtAddress);
VerifyOrExit(dst.GetExtended() == *static_cast<const Mac::ExtAddress *>(aExtAddress), rval = false);
break;
case Mac::Address::kTypeNone:
rval = true;
break;
}
SuccessOrExit(frame.GetDstPanId(panid));
VerifyOrExit(panid == Mac::kPanIdBroadcast || panid == aPanId, rval = false);
exit:
return rval;
}
+19 -8
View File
@@ -242,7 +242,11 @@ otError Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, Active
VerifyOrExit(address.IsExtended(), error = OT_ERROR_PARSE);
aResult.mExtAddress = address.GetExtended();
IgnoreError(aBeaconFrame->GetSrcPanId(aResult.mPanId));
if (OT_ERROR_NONE != aBeaconFrame->GetSrcPanId(aResult.mPanId))
{
IgnoreError(aBeaconFrame->GetDstPanId(aResult.mPanId));
}
aResult.mChannel = aBeaconFrame->GetChannel();
aResult.mRssi = aBeaconFrame->GetRssi();
aResult.mLqi = aBeaconFrame->GetLqi();
@@ -847,7 +851,12 @@ otError Mac::PrepareDataRequest(TxFrame &aFrame)
}
aFrame.InitMacHeader(fcf, Frame::kKeyIdMode1 | Frame::kSecEncMic32);
aFrame.SetDstPanId(GetPanId());
if (aFrame.IsDstPanIdPresent())
{
aFrame.SetDstPanId(GetPanId());
}
aFrame.SetSrcAddr(src);
aFrame.SetDstAddr(dst);
IgnoreError(aFrame.SetCommandId(Frame::kMacCmdDataRequest));
@@ -1574,9 +1583,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
break;
case Address::kTypeShort:
IgnoreError(aFrame->GetDstPanId(panid));
VerifyOrExit((panid == kShortAddrBroadcast || panid == mPanId) &&
((mRxOnWhenIdle && dstaddr.IsBroadcast()) || dstaddr.GetShort() == GetShortAddress()),
VerifyOrExit((mRxOnWhenIdle && dstaddr.IsBroadcast()) || dstaddr.GetShort() == GetShortAddress(),
error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
#if OPENTHREAD_FTD
@@ -1590,12 +1597,16 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
break;
case Address::kTypeExtended:
IgnoreError(aFrame->GetDstPanId(panid));
VerifyOrExit(panid == mPanId && dstaddr.GetExtended() == GetExtAddress(),
error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
VerifyOrExit(dstaddr.GetExtended() == GetExtAddress(), error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
break;
}
// Verify destination PAN ID if present
if (OT_ERROR_NONE == aFrame->GetDstPanId(panid))
{
VerifyOrExit(panid == kShortAddrBroadcast || panid == mPanId, error = OT_ERROR_DESTINATION_ADDRESS_FILTERED);
}
// Source Address Filtering
switch (srcaddr.GetType())
{
+28 -31
View File
@@ -118,7 +118,7 @@ uint8_t Frame::FindDstPanIdIndex(void) const
{
uint8_t index;
VerifyOrExit((GetFrameControlField() & kFcfDstAddrMask) != kFcfDstAddrNone, index = kInvalidIndex);
VerifyOrExit(IsDstPanIdPresent(), index = kInvalidIndex);
index = kFcfSize + kDsnSize;
@@ -180,11 +180,7 @@ void Frame::SetDstPanId(PanId aPanId)
uint8_t Frame::FindDstAddrIndex(void) const
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
return kFcfSize + kDsnSize + (IsDstPanIdPresent() ? sizeof(PanId) : 0);
#else
return kFcfSize + kDsnSize + sizeof(PanId);
#endif
}
otError Frame::GetDstAddr(Address &aAddress) const
@@ -252,23 +248,24 @@ uint8_t Frame::FindSrcPanIdIndex(void) const
uint8_t index = 0;
uint16_t fcf = GetFrameControlField();
VerifyOrExit((fcf & kFcfDstAddrMask) != kFcfDstAddrNone || (fcf & kFcfSrcAddrMask) != kFcfSrcAddrNone,
index = kInvalidIndex);
VerifyOrExit(IsSrcPanIdPresent(), index = kInvalidIndex);
index += kFcfSize + kDsnSize;
if ((fcf & kFcfPanidCompression) == 0)
if (IsDstPanIdPresent(fcf))
{
switch (fcf & kFcfDstAddrMask)
{
case kFcfDstAddrShort:
index += sizeof(PanId) + sizeof(ShortAddress);
break;
index += sizeof(PanId);
}
case kFcfDstAddrExt:
index += sizeof(PanId) + sizeof(ExtAddress);
break;
}
switch (fcf & kFcfDstAddrMask)
{
case kFcfDstAddrShort:
index += sizeof(ShortAddress);
break;
case kFcfDstAddrExt:
index += sizeof(ExtAddress);
break;
}
exit:
@@ -1099,22 +1096,22 @@ otError TxFrame::GenerateEnhAck(const RxFrame &aFrame, bool aIsFramePending, con
// Set sequence number
mPsdu[kSequenceIndex] = aFrame.GetSequence();
// Set address field
if (aFrame.IsSrcPanIdPresent())
{
SuccessOrExit(error = aFrame.GetSrcPanId(panId));
}
else if (aFrame.IsDstPanIdPresent())
{
SuccessOrExit(error = aFrame.GetDstPanId(panId));
}
else
{
ExitNow(error = OT_ERROR_PARSE);
}
if (IsDstPanIdPresent())
{
// Set address field
if (aFrame.IsSrcPanIdPresent())
{
SuccessOrExit(error = aFrame.GetSrcPanId(panId));
}
else if (aFrame.IsDstPanIdPresent())
{
SuccessOrExit(error = aFrame.GetDstPanId(panId));
}
else
{
ExitNow(error = OT_ERROR_PARSE);
}
SetDstPanId(panId);
}
+13 -18
View File
@@ -58,7 +58,12 @@ namespace ot {
void ThreadLinkInfo::SetFrom(const Mac::RxFrame &aFrame)
{
Clear();
IgnoreError(aFrame.GetSrcPanId(mPanId));
if (OT_ERROR_NONE != aFrame.GetSrcPanId(mPanId))
{
IgnoreError(aFrame.GetDstPanId(mPanId));
}
mChannel = aFrame.GetChannel();
mRss = aFrame.GetRssi();
mLqi = aFrame.GetLqi();
@@ -560,26 +565,16 @@ start:
if (dstpan == Get<Mac::Mac>().GetPanId())
{
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
// Handle a special case in IEEE 802.15.4-2015, when PAN ID
// Compression is 0, but Src PAN ID is not present:
// Dest Address: Extended
// Src Address: Extended
// Dest Pan ID: Present
// Src Pan ID: Not Present
// Pan ID Compression: 0
if ((fcf & Mac::Frame::kFcfFrameVersionMask) != Mac::Frame::kFcfFrameVersion2015 ||
(fcf & Mac::Frame::kFcfDstAddrMask) != Mac::Frame::kFcfDstAddrExt ||
(fcf & Mac::Frame::kFcfSrcAddrMask) != Mac::Frame::kFcfSrcAddrExt)
#endif
{
fcf |= Mac::Frame::kFcfPanidCompression;
}
fcf |= Mac::Frame::kFcfPanidCompression;
}
aFrame.InitMacHeader(fcf, secCtl);
aFrame.SetDstPanId(dstpan);
if (aFrame.IsDstPanIdPresent())
{
aFrame.SetDstPanId(dstpan);
}
IgnoreError(aFrame.SetSrcPanId(Get<Mac::Mac>().GetPanId()));
aFrame.SetDstAddr(aMacDest);
aFrame.SetSrcAddr(aMacSource);
+19 -3
View File
@@ -217,9 +217,25 @@ class MacFrame:
self.payload = None
return
# Presence of PAN Ids is not fully implemented yet but should be enough
# for Thread.
dest_pan_id = struct.unpack("<H", data.read(2))[0]
dest_addr_present = dest_addr_mode != MacHeader.AddressMode.NOT_PRESENT
src_addr_present = source_addr_mode != MacHeader.AddressMode.NOT_PRESENT
if frame_version < 2:
dest_pan_present = dest_addr_present
else:
dest_pan_present = True
if not src_addr_present:
dest_pan_present = src_pan_present != panid_compression
elif not dest_addr_present:
dest_pan_present = False
else:
if dest_addr_mode == MacHeader.AddressMode.EXTENDED and source_addr_mode == MacHeader.AddressMode.EXTENDED and panid_compression:
dest_pan_present = False
if dest_pan_present:
dest_pan_id = struct.unpack("<H", data.read(2))[0]
else:
dest_pan_id = None
dest_address = self._parse_address(data, dest_addr_mode)