ip: support DCCP and UDP-Lite, TCP chksum twx; tun: more filtering

pull/31/head
cathugger 6 years ago
parent d0c35803a5
commit ca01daa89a
No known key found for this signature in database
GPG Key ID: 9BADDA2DAF6F01A8

@ -340,10 +340,12 @@ namespace llarp
// - non-IPv4 packets
// - packets with weird src/dst addresses
// (0.0.0.0/8 but not 0.0.0.0)
// - packets with 0 src but non-0 dst and oposite
auto hdr = pkt.Header();
if(pkt.sz < sizeof(*hdr) || hdr->version != 4
|| (hdr->saddr && *(byte_t *)&(hdr->saddr) == 0)
|| (hdr->daddr && *(byte_t *)&(hdr->daddr) == 0))
|| (hdr->saddr != 0 && *(byte_t *)&(hdr->saddr) == 0)
|| (hdr->daddr != 0 && *(byte_t *)&(hdr->daddr) == 0)
|| ((hdr->saddr == 0) != (hdr->daddr == 0)))
{
return false;
}

@ -90,15 +90,22 @@ namespace llarp
}
static void
checksumDstTCP(byte_t *pld, size_t psz, size_t fragoff, huint32_t oSrcIP,
huint32_t oDstIP, huint32_t nSrcIP, huint32_t nDstIP)
checksumDstTCP(byte_t *pld, size_t psz, size_t fragoff, size_t chksumoff,
huint32_t oSrcIP, huint32_t oDstIP, huint32_t nSrcIP,
huint32_t nDstIP)
{
if(fragoff > 16)
if(fragoff > chksumoff)
return;
uint16_t *check = (uint16_t *)(pld + 16 - fragoff);
uint16_t *check = (uint16_t *)(pld + chksumoff - fragoff);
*check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP);
// usually, TCP checksum field cannot be 0xFFff,
// because one's complement addition cannot result in 0x0000,
// and there's inversion in the end;
// emulate that.
if(*check == 0xFFff)
*check = 0x0000;
}
static void
@ -114,7 +121,6 @@ namespace llarp
return; // 0 is used to indicate "no checksum", don't change
*check = deltachksum(*check, oSrcIP, oDstIP, nSrcIP, nDstIP);
// 0 is used to indicate "no checksum"
// 0xFFff and 0 are equivalent in one's complement math
// 0xFFff + 1 = 0x10000 -> 0x0001 (same as 0 + 1)
@ -147,13 +153,19 @@ namespace llarp
switch(hdr->protocol)
{
case 6:
checksumDstTCP(pld, psz, fragoff, oSrcIP, oDstIP, nSrcIP, nDstIP);
case 6: // TCP
checksumDstTCP(pld, psz, fragoff, 16, oSrcIP, oDstIP, nSrcIP,
nDstIP);
break;
case 17:
case 17: // UDP
case 136: // UDP-Lite - same checksum place, same 0->0xFFff condition
checksumDstUDP(hdr, pld, psz, fragoff, oSrcIP, oDstIP, nSrcIP,
nDstIP);
break;
case 33: // DCCP
checksumDstTCP(pld, psz, fragoff, 6, oSrcIP, oDstIP, nSrcIP,
nDstIP);
break;
}
}
@ -163,15 +175,21 @@ namespace llarp
}
static void
checksumSrcTCP(byte_t *pld, size_t psz, size_t fragoff, huint32_t oSrcIP,
huint32_t oDstIP)
checksumSrcTCP(byte_t *pld, size_t psz, size_t fragoff, size_t chksumoff,
huint32_t oSrcIP, huint32_t oDstIP)
{
if(fragoff > 16)
if(fragoff > chksumoff)
return;
uint16_t *check = (uint16_t *)(pld + 16 - fragoff);
uint16_t *check = (uint16_t *)(pld + chksumoff - fragoff);
*check = deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, huint32_t{0});
// usually, TCP checksum field cannot be 0xFFff,
// because one's complement addition cannot result in 0x0000,
// and there's inversion in the end;
// emulate that.
if(*check == 0xFFff)
*check = 0x0000;
}
static void
@ -186,7 +204,6 @@ namespace llarp
return; // 0 is used to indicate "no checksum", don't change
*check = deltachksum(*check, oSrcIP, oDstIP, huint32_t{0}, huint32_t{0});
// 0 is used to indicate "no checksum"
// 0xFFff and 0 are equivalent in one's complement math
// 0xFFff + 1 = 0x10000 -> 0x0001 (same as 0 + 1)
@ -216,12 +233,16 @@ namespace llarp
switch(hdr->protocol)
{
case 6:
checksumSrcTCP(pld, psz, fragoff, oSrcIP, oDstIP);
case 6: // TCP
checksumSrcTCP(pld, psz, fragoff, 16, oSrcIP, oDstIP);
break;
case 17:
case 17: // UDP
case 136: // UDP-Lite
checksumSrcUDP(hdr, pld, psz, fragoff, oSrcIP, oDstIP);
break;
case 33: // DCCP
checksumSrcTCP(pld, psz, fragoff, 6, oSrcIP, oDstIP);
break;
}
}

Loading…
Cancel
Save