From fa004fc38a52d7f425c93aa15cec61c88bed1030 Mon Sep 17 00:00:00 2001 From: Malcolm Robb Date: Fri, 4 Oct 2013 10:34:26 +0100 Subject: [PATCH] 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. --- mode_s.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/mode_s.c b/mode_s.c index fbccf0a..8be941d 100644 --- a/mode_s.c +++ b/mode_s.c @@ -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 (mm->correctedbits) { - uint32_t addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); - if (!ICAOAddressWasRecentlySeen(addr)) + uint32_t ulAddr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); + if (!ICAOAddressWasRecentlySeen(ulAddr)) 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. // if (mm->msgtype == 11) { // DF 11 - mm->crcok = (mm->crc < 80); mm->iid = mm->crc; mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); 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. 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 - mm->crcok = (mm->crc == 0); mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); 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. addRecentlySeenICAOAddr(mm->addr); } } else if (mm->msgtype == 18) { // DF 18 - mm->crcok = (mm->crc == 0); mm->addr = (msg[1] << 16) | (msg[2] << 8) | (msg[3]); 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. addRecentlySeenICAOAddr(mm->addr); } @@ -885,8 +887,7 @@ void decodeModesMessage(struct modesMessage *mm, unsigned char *msg) { } else { // All other DF's // Compare the checksum with the whitelist of recently seen ICAO // addresses. If it matches one, then declare the message as valid - mm->addr = mm->crc; - mm->crcok = ICAOAddressWasRecentlySeen(mm->crc); + mm->crcok = ICAOAddressWasRecentlySeen(mm->addr = mm->crc); } // Fields for DF0, DF16