- WinDivertHelperParsePacket() now skips IPv6 extension headers.

This commit is contained in:
basil00
2014-11-10 19:16:33 +08:00
parent 7952724127
commit 7235b687b3
2 changed files with 51 additions and 2 deletions
+50
View File
@@ -204,6 +204,7 @@ static BOOL WinDivertParseFilter(FILTER_TOKEN *tokens, UINT16 *tp,
windivert_ioctl_filter_t filter, UINT16 *fp, FILTER_TOKEN_KIND op);
static void WinDivertFilterUpdate(windivert_ioctl_filter_t filter, UINT16 s,
UINT16 e, UINT16 success, UINT16 failure);
static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len);
static void WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header,
PWINDIVERT_PSEUDOHDR pseudo_header, UINT8 protocol, UINT len);
static void WinDivertInitPseudoHeaderV6(PWINDIVERT_IPV6HDR ipv6_header,
@@ -1402,6 +1403,53 @@ static void WinDivertFilterUpdate(windivert_ioctl_filter_t filter, UINT16 s,
/* WINDIVERT HELPER IMPLEMENTATION */
/****************************************************************************/
/*
* Skip well-known IPv6 extension headers.
*/
static UINT8 WinDivertSkipExtHeaders(UINT8 proto, UINT8 **header, UINT *len)
{
UINT hdrlen;
while (TRUE)
{
if (*len <= 2)
{
return IPPROTO_NONE;
}
hdrlen = (UINT)*(*header + 1);
switch (proto)
{
case IPPROTO_FRAGMENT:
hdrlen = 8;
break;
case IPPROTO_AH:
hdrlen += 2;
hdrlen *= 4;
break;
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_ROUTING:
hdrlen++;
hdrlen *= 8;
break;
case IPPROTO_NONE:
return proto;
default:
return proto;
}
if (hdrlen >= *len)
{
return IPPROTO_NONE;
}
proto = **header;
*header += hdrlen;
*len -= hdrlen;
}
}
/*
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
*/
@@ -1460,6 +1508,8 @@ extern BOOL WinDivertHelperParsePacket(PVOID pPacket, UINT packetLen,
trans_proto = ipv6_header->NextHdr;
data = (PVOID)((UINT8 *)data + sizeof(WINDIVERT_IPV6HDR));
data_len -= sizeof(WINDIVERT_IPV6HDR);
trans_proto = WinDivertSkipExtHeaders(trans_proto, (UINT8 **)&data,
&data_len);
break;
default:
ip_header = NULL;
+1 -2
View File
@@ -2543,7 +2543,6 @@ static UINT16 windivert_checksum(const void *pseudo_header,
*/
static UINT8 windivert_skip_headers(UINT8 proto, UINT8 **header, size_t *len)
{
UINT8 *hdrlen_ptr;
size_t hdrlen;
while (TRUE)
@@ -2669,7 +2668,7 @@ static void windivert_update_checksums(void *header, size_t len,
// Skip extension headers:
proto = windivert_skip_headers(ipv6_header->NextHdr,
&(UINT8 *)trans_header, &trans_len);
(UINT8 **)&trans_header, &trans_len);
break;
default: