// === CODE ===
uint16_t IP_Checksum(uint16_t Prev, size_t Length, const void *Data)
{
+ //test_trace_hexdump("IP Checksum", Data, Length);
+
const uint16_t *words = Data;
- uint32_t ret = ~Prev;
+ uint32_t ret = 0;
for( int i = 0; i < Length/2; i ++ )
{
ret += ntohs(*words);
while( ret >> 16 )
ret = (ret & 0xFFFF) + (ret >> 16);
+ //test_trace("IP Checksum = %04x + 0x%x", ret, (~Prev) & 0xFFFF);
+
+ ret += (~Prev) & 0xFFFF;
+ while( ret >> 16 )
+ ret = (ret & 0xFFFF) + (ret >> 16);
+
return ~ret;
}
}
}
-bool IP_Pkt_Check(size_t len, const void *data, size_t *ofs_out, int AF, const void *Src, const void *Dst, uint8_t proto)
+bool IP_Pkt_Check(size_t len, const void *data, size_t *ofs_out, size_t *len_out, int AF, const void *Src, const void *Dst, uint8_t proto)
{
size_t ofs;
if( AF == 4 ) {
TEST_ASSERT_REL(IP_Checksum(IP_CHECKSUM_START, sizeof(hdr), &hdr), ==, 0);
TEST_ASSERT_REL(ntohs(hdr.TotalLength), <=, len - ofs);
+ TEST_ASSERT_REL(ntohs(hdr.TotalLength), >, (hdr.VerLen & 0xF) * 4);
TEST_ASSERT_REL(ntohs(hdr.FragmentInfo), ==, 0);
TEST_ASSERT_REL(hdr.TTL, >, 1); // >1 because there's no intervening hops
TEST_ASSERT_REL(hdr.Protocol, ==, proto);
- TEST_ASSERT( memcmp(hdr.SrcAddr, Src, 4) == 0 );
- TEST_ASSERT( memcmp(hdr.DstAddr, Dst, 4) == 0 );
-
+ if(Src) TEST_ASSERT( memcmp(hdr.SrcAddr, Src, 4) == 0 );
+ if(Dst) TEST_ASSERT( memcmp(hdr.DstAddr, Dst, 4) == 0 );
+
+ *len_out = ntohs(hdr.TotalLength) - sizeof(hdr);
*ofs_out = ofs + (hdr.VerLen & 0xF) * 4;
return true;
}