From e51916b54cbd2c26c5349c514563caa08972d5b2 Mon Sep 17 00:00:00 2001 From: John Thacker Date: Wed, 10 Aug 2022 07:30:32 -0400 Subject: L2TP: Fix UDP conversation handling. RFCs 2661 and 3931 say that L2TPv2 and L2TPv3 use a TFTP-like method of selecting ports. The initiator picks a source port (which may or may not be 1701, the IANA assigned L2TP port), and sends a message to 1701; the recipient picks a free port (which may or may not be 1701) and replies to the initiator's chosen port and address, and the conversation from then on uses the chosen ports. In practice, due to NAT, firewalls, etc., most implementations just use a symmetric predetermined L2TP port. To support both methods we use one-sided conversations with one port omitted. Fix the lookup of the reverse conversation. Part of #16565. --- epan/dissectors/packet-l2tp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/epan/dissectors/packet-l2tp.c b/epan/dissectors/packet-l2tp.c index ede7cb8713..c32834ffbd 100644 --- a/epan/dissectors/packet-l2tp.c +++ b/epan/dissectors/packet-l2tp.c @@ -2933,12 +2933,18 @@ dissect_l2tp_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data return 0; } + /* RFCs 2661 and 3931 say that L2TPv2 and v3 use a TFTP-like method + * of each side choosing their own port and only using the L2TP port + * to establish the connection. In common practice, both parties use + * the assigned L2TP port the entire time, due to NAT, firewalls, etc. + * We support both methods by using conversations with no second port. + */ conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, ENDPOINT_UDP, pinfo->srcport, pinfo->destport, NO_PORT_B); - if (conv == NULL) { - conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, ENDPOINT_UDP, - pinfo->srcport, pinfo->destport, 0); + if (conv == NULL || (conversation_get_dissector(conv, pinfo->num) != l2tp_udp_handle)) { + conv = find_conversation(pinfo->num, &pinfo->dst, &pinfo->src, ENDPOINT_UDP, + pinfo->destport, pinfo->srcport, NO_PORT_B); } if ((conv == NULL) || (conversation_get_dissector(conv, pinfo->num) != l2tp_udp_handle)) { -- cgit v1.2.3