ip: Reassemble across VLANs for publicly routable IPv4 addresses

Default to taking the VLAN ID into account when reassembling only
for private IPv4 addresses as defined by RFC 1918 and for link-local
addresses. Otherwise, do not take the VLAN ID into account unless
the "Enable stricter conversation tracking heuristics" preference
is enabled. Fixes #14356.
This commit is contained in:
John Thacker 2021-01-19 23:46:51 -05:00
parent 11cd298ae8
commit 4371474cc3
4 changed files with 34 additions and 3 deletions

View File

@ -72,6 +72,8 @@ They previously shipped with Npcap 1.20.
* Follow stream YAML output formats has been changed to add timestamps and peers information (for more details see the users guide,
{wireshark-users-guide-url}/ChAdvFollowStreamSection.html[Following Protocol Streams])
* IP fragments between public IPv4 addresses are now reassembled even if they have different VLAN IDs. Reassembly of IP fragments where one endpoint is a private (RFC 1918 section 3) or link-local (RFC 3927) IPv4 address continues to take the VLAN ID into account, as those addresses can be reused. To revert to the previous behavior and not reassemble fragments with different VLAN IDs, turn on the "Enable stricter conversation tracking heuristics" top level protocol preference.
// === Removed Features and Support
// === Removed Dissectors

View File

@ -2230,9 +2230,20 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
iph->ip_len > hlen &&
tvb_bytes_exist(tvb, offset, iph->ip_len - hlen) &&
ipsum == 0) {
guint32 frag_id;
frag_id = iph->ip_proto ^ iph->ip_id ^ src32 ^ dst32;
/* XXX: Should there be a way to force the VLAN ID not to
* be taken into account for reassembly even with non publicly
* routable IP addresses?
*/
if (in4_addr_is_private(dst32) || in4_addr_is_private(src32) ||
in4_addr_is_link_local(dst32) || in4_addr_is_link_local(src32) ||
prefs.strict_conversation_tracking_heuristics) {
frag_id ^= pinfo->vlan_id;
}
ipfd_head = fragment_add_check(&ip_reassembly_table, tvb, offset,
pinfo,
iph->ip_proto ^ iph->ip_id ^ src32 ^ dst32 ^ pinfo->vlan_id,
frag_id,
NULL,
(iph->ip_off & IP_OFFSET) * 8,
iph->ip_len - hlen,

View File

@ -3771,8 +3771,8 @@ prefs_register_modules(void)
prefs_register_bool_preference(protocols_module, "strict_conversation_tracking_heuristics",
"Enable stricter conversation tracking heuristics",
"Protocols may use things like VLAN ID or interface ID to narrow the potential for duplicate conversations."
"Currently only ICMP and ICMPv6 use this preference to add VLAN ID to conversation tracking",
"Protocols may use things like VLAN ID or interface ID to narrow the potential for duplicate conversations. "
"Currently ICMP and ICMPv6 use this preference to add VLAN ID to conversation tracking, and IPv4 uses this preference to take VLAN ID into account during reassembly",
&prefs.strict_conversation_tracking_heuristics);
/* Obsolete preferences

View File

@ -35,4 +35,22 @@ typedef guint32 ws_in4_addr; /* 32 bit IPv4 address, in network byte order */
#define in4_addr_is_multicast(addr) \
((addr & 0xf0000000) == 0xe0000000)
/**
* Private address
* Returns true if the address is in one of the three blocks reserved
* for private IPv4 addresses by section 3 of RFC 1918, namely:
* 10/8, 172.16/12, and 192.168/16
*/
#define in4_addr_is_private(addr) \
(((addr & 0xff000000) == 0x0a000000) || \
((addr & 0xfff00000) == 0xac100000) || \
((addr & 0xffff0000) == 0xc0a80000))
/**
* Link-local address
* Returns true if the address is in the 169.254/16 network block
*/
#define in4_addr_is_link_local(addr) \
((addr & 0xffff0000) == 0xa9fe0000)
#endif