Merge pull request #2 from cathugger/ipv6-tun

proper IPv6 option processing
This commit is contained in:
Jeff 2019-06-11 20:06:45 -04:00 committed by GitHub
commit 0bf5aa88cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -196,11 +196,11 @@ namespace llarp
#undef SUB32CS
static void
deltaChecksumIPv4TCP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
size_t fragoff, size_t chksumoff, nuint32_t oSrcIP,
nuint32_t oDstIP, nuint32_t nSrcIP, nuint32_t nDstIP)
deltaChecksumIPv4TCP(byte_t *pld, size_t psz, size_t fragoff,
size_t chksumoff, nuint32_t oSrcIP, nuint32_t oDstIP,
nuint32_t nSrcIP, nuint32_t nDstIP)
{
if(fragoff > chksumoff)
if(fragoff > chksumoff || psz < chksumoff - fragoff + 2)
return;
auto check = (nuint16_t *)(pld + chksumoff - fragoff);
@ -215,12 +215,12 @@ namespace llarp
}
static void
deltaChecksumIPv6TCP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
size_t fragoff, size_t chksumoff,
const uint32_t oSrcIP[4], const uint32_t oDstIP[4],
const uint32_t nSrcIP[4], const uint32_t nDstIP[4])
deltaChecksumIPv6TCP(byte_t *pld, size_t psz, size_t fragoff,
size_t chksumoff, const uint32_t oSrcIP[4],
const uint32_t oDstIP[4], const uint32_t nSrcIP[4],
const uint32_t nDstIP[4])
{
if(fragoff > chksumoff)
if(fragoff > chksumoff || psz < chksumoff - fragoff + 2)
return;
auto check = (nuint16_t *)(pld + chksumoff - fragoff);
@ -235,11 +235,11 @@ namespace llarp
}
static void
deltaChecksumIPv4UDP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
size_t fragoff, nuint32_t oSrcIP, nuint32_t oDstIP,
nuint32_t nSrcIP, nuint32_t nDstIP)
deltaChecksumIPv4UDP(byte_t *pld, size_t psz, size_t fragoff,
nuint32_t oSrcIP, nuint32_t oDstIP, nuint32_t nSrcIP,
nuint32_t nDstIP)
{
if(fragoff > 6)
if(fragoff > 6 || psz < 6 + 2)
return;
auto check = (nuint16_t *)(pld + 6);
@ -258,12 +258,11 @@ namespace llarp
}
static void
deltaChecksumIPv6UDP(byte_t *pld, ABSL_ATTRIBUTE_UNUSED size_t psz,
size_t fragoff, const uint32_t oSrcIP[4],
const uint32_t oDstIP[4], const uint32_t nSrcIP[4],
const uint32_t nDstIP[4])
deltaChecksumIPv6UDP(byte_t *pld, size_t psz, size_t fragoff,
const uint32_t oSrcIP[4], const uint32_t oDstIP[4],
const uint32_t nSrcIP[4], const uint32_t nDstIP[4])
{
if(fragoff > 6)
if(fragoff > 6 || psz < 6 + 2)
return;
auto check = (nuint16_t *)(pld + 6);
@ -337,7 +336,7 @@ namespace llarp
void
IPPacket::UpdateIPv6Address(huint128_t src, huint128_t dst)
{
const size_t ihs = 40;
const size_t ihs = 4 + 4 + 16 + 16;
// XXX should've been checked at upper level?
if(sz <= ihs)
@ -359,9 +358,53 @@ namespace llarp
// TODO IPv6 header options
auto pld = buf + ihs;
auto psz = sz - ihs;
const size_t fragoff = 0;
switch(hdr->proto)
size_t fragoff = 0;
auto nextproto = hdr->proto;
for(;;)
{
switch(nextproto)
{
case 0: // Hop-by-Hop Options
case 43: // Routing Header
case 60: // Destination Options
{
nextproto = pld[0];
auto addlen = (size_t(pld[1]) + 1) * 8;
if(psz < addlen)
return;
pld += addlen;
psz -= addlen;
break;
}
case 44: // Fragment Header
/*
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header | Reserved | Fragment Offset |Res|M|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
nextproto = pld[0];
fragoff = (uint16_t(pld[2]) << 8) | (uint16_t(pld[3]) & 0xFC);
if(psz < 8)
return;
pld += 8;
psz -= 8;
// jump straight to payload processing
if(fragoff != 0)
goto endprotohdrs;
break;
default:
goto endprotohdrs;
}
}
endprotohdrs:
switch(nextproto)
{
case 6: // TCP
deltaChecksumIPv6TCP(pld, psz, fragoff, 16, oSrcIP, oDstIP, nSrcIP,