DF-11 SI/II Detection changes

Don't allow detection of DF-11 SI/II until we have received at least one
DF-11 for the aircraft with an SI/II of zero.

Previous versions would allow an ICAOAddr to be marked as valid if a
DF-11 was received where the crc was less than 80. This is required for
SI/II detection where the SI/II is overlaid on the crc field. However,
this also decreaces the security of the crc. It is possible for a
corrupt message to result in a crc value of between 1 and 79, and this
will lead to an invalid ICAOAddr being marked as received.

To try and prevent this, do not allow detection of DF-11 II/SI fields
until at least one DF-11 crc=0 has been received. Once this happens, we
ca be fairly sure that this aircraft really is within range, and so
II/SI detection can e used.
This commit is contained in:
Malcolm Robb 2013-10-04 10:34:26 +01:00
parent f50744b11b
commit fa004fc38a

View file

@ -842,8 +842,8 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
// If we correct, validate ICAO addr to help filter birthday paradox solutions. // If we correct, validate ICAO addr to help filter birthday paradox solutions.
if (mm->correctedbits) { if (mm->correctedbits) {
uint32_t addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); uint32_t ulAddr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
if (!ICAOAddressWasRecentlySeen(addr)) if (!ICAOAddressWasRecentlySeen(ulAddr))
mm->correctedbits = 0; mm->correctedbits = 0;
} }
} }
@ -852,32 +852,34 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
// single/two bit errors, otherwise we would need to recompute the fields again. // single/two bit errors, otherwise we would need to recompute the fields again.
// //
if (mm->msgtype == 11) { // DF 11 if (mm->msgtype == 11) { // DF 11
mm->crcok = (mm->crc < 80);
mm->iid = mm->crc; mm->iid = mm->crc;
mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
mm->ca = (msg[0] & 0x07); // Responder capabilities mm->ca = (msg[0] & 0x07); // Responder capabilities
if (0 == mm->crc) { if ((mm->crcok = (0 == mm->crc))) {
// DF 11 : if crc == 0 try to populate our ICAO addresses whitelist. // DF 11 : if crc == 0 try to populate our ICAO addresses whitelist.
addRecentlySeenICAOAddr(mm->addr); addRecentlySeenICAOAddr(mm->addr);
} else if (mm->crc < 80) {
mm->crcok = ICAOAddressWasRecentlySeen(mm->addr);
if (mm->crcok) {
addRecentlySeenICAOAddr(mm->addr);
}
} }
} else if (mm->msgtype == 17) { // DF 17 } else if (mm->msgtype == 17) { // DF 17
mm->crcok = (mm->crc == 0);
mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
mm->ca = (msg[0] & 0x07); // Responder capabilities mm->ca = (msg[0] & 0x07); // Responder capabilities
if (0 == mm->crc) { if ((mm->crcok = (0 == mm->crc))) {
// DF 17 : if crc == 0 try to populate our ICAO addresses whitelist. // DF 17 : if crc == 0 try to populate our ICAO addresses whitelist.
addRecentlySeenICAOAddr(mm->addr); addRecentlySeenICAOAddr(mm->addr);
} }
} else if (mm->msgtype == 18) { // DF 18 } else if (mm->msgtype == 18) { // DF 18
mm->crcok = (mm->crc == 0);
mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]);
mm->ca = (msg[0] & 0x07); // Control Field mm->ca = (msg[0] & 0x07); // Control Field
if (0 == mm->crc) { if ((mm->crcok = (0 == mm->crc))) {
// DF 18 : if crc == 0 try to populate our ICAO addresses whitelist. // DF 18 : if crc == 0 try to populate our ICAO addresses whitelist.
addRecentlySeenICAOAddr(mm->addr); addRecentlySeenICAOAddr(mm->addr);
} }
@ -885,8 +887,7 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) {
} else { // All other DF's } else { // All other DF's
// Compare the checksum with the whitelist of recently seen ICAO // Compare the checksum with the whitelist of recently seen ICAO
// addresses. If it matches one, then declare the message as valid // addresses. If it matches one, then declare the message as valid
mm->addr = mm->crc; mm->crcok = ICAOAddressWasRecentlySeen(mm->addr = mm->crc);
mm->crcok = ICAOAddressWasRecentlySeen(mm->crc);
} }
// Fields for DF0, DF16 // Fields for DF0, DF16