mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-10-29 17:54:14 +08:00
igmp: mask the port number before shifting by it
The RTL tag carries a 4-bit port number for received frames, and the two places that turn it into a mask bit take the whole byte: entry.pmask |= (1L << (IGMP_I->rtl_tag.pmask >> 8)); The comment beside it already says only the low four bits count, but nothing takes them. rtl837x_stp.c:424 does the same extraction and does mask: stp_scratch = ((uint8_t)HTONS(STP_I->rtl_tag.pmask)) & 0x0f; With a count above 15 the result is not a bit at all. SDCC narrows the 1L to 16 bits and emits the shift as a djnz loop, so a count of 200 spins the loop 200 times and leaves zero behind: the join adds no port and the leave clears none, neither saying anything. It also spends those iterations inside packet handling. Mask to four bits and shift a uint16_t, which is the width the surrounding code works in. Six bytes of BANK1. Worth saying that this does not make snooping work on its own. struct igmp_pkt has no vlan_tag field while struct eth_in describes the same frame with one, so every IP and IGMP field below rtl_tag is read four bytes early.
This commit is contained in:
1 parent
5ecce86ef1
commit
624f93a28a
1 file changed
+2
-2
+2
-2
@@ -295,7 +295,7 @@ void igmp_packet_handler(void) __banked
|
||||
entry.pmask |= ((uint16_t)sfr_data[3]) << 2;
|
||||
}
|
||||
// Update (found) entry with portmask from trapped Packet
|
||||
entry.pmask |= (1L << (IGMP_I->rtl_tag.pmask >> 8)); // Swap bytes from network order, only 4 LSB count
|
||||
entry.pmask |= ((uint16_t)1) << ((IGMP_I->rtl_tag.pmask >> 8) & 0x0f); // Swap bytes from network order, only 4 LSB count
|
||||
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
||||
} else if (IGMP_I->igmp_rtype == 0x3){ // Leave group
|
||||
if (sfr_data[2] & 0x10) {
|
||||
@@ -312,7 +312,7 @@ void igmp_packet_handler(void) __banked
|
||||
write_char('\n');
|
||||
#endif
|
||||
// Remove portmask of IGMP packet from entry
|
||||
entry.pmask &= ~(1L << (IGMP_I->rtl_tag.pmask >> 8)); // Swap bytes from network order, only 4 LSB count
|
||||
entry.pmask &= ~(((uint16_t)1) << ((IGMP_I->rtl_tag.pmask >> 8) & 0x0f)); // Swap bytes from network order, only 4 LSB count
|
||||
// print_string("\nPort-Mask: "); print_short(entry.pmask); write_char('\n');
|
||||
} else {
|
||||
print_string("IGMP Entry already deleted\n");
|
||||
|
||||
Reference in new issue
Block a user