From d5fe92208415235006432fc340a1336138ef95d5 Mon Sep 17 00:00:00 2001 From: luis Date: Fri, 29 Mar 2013 13:46:14 +0000 Subject: [PATCH] Merged r27646 from nmap-npingchages: Add function to determine the tranport layer protocol in a chain of PacketElements --- libnetutil/PacketParser.cc | 56 ++++++++++++++++++++++++++++++++++++++ libnetutil/PacketParser.h | 1 + 2 files changed, 57 insertions(+) diff --git a/libnetutil/PacketParser.cc b/libnetutil/PacketParser.cc index 7f905f732..693b83fa0 100644 --- a/libnetutil/PacketParser.cc +++ b/libnetutil/PacketParser.cc @@ -1708,3 +1708,59 @@ bool PacketParser::is_response(PacketElement *sent, PacketElement *rcvd){ if(PKTPARSERDEBUG)printf("%s(): The received packet was successfully matched with the sent packet.\n", __func__); return true; } + +/* Tries to find a transport layer header in the supplied chain of + * protocol headers. On success it returns a pointer to a PacketElement + * of one of these types: + * + * HEADER_TYPE_TCP + * HEADER_TYPE_UDP + * HEADER_TYPE_ICMPv4 + * HEADER_TYPE_ICMPv6 + * HEADER_TYPE_SCTP + * HEADER_TYPE_ARP + * + * It returns NULL if no transport layer header is found. + * + * Note that this method onyl understands IPv4, IPv6 (and its + * extension headers) and Ethernet. If the supplied packet contains + * something different before the tranport layer, NULL will be returned. + * */ +PacketElement *PacketParser::find_transport_layer(PacketElement *chain){ + PacketElement *aux=chain; + /* Traverse the chain of PacketElements */ + while(aux!=NULL){ + switch(aux->protocol_id()){ + /* If we have a link or a network layer header, skip it. */ + case HEADER_TYPE_IPv6_HOPOPT: + case HEADER_TYPE_IPv4: + case HEADER_TYPE_IPv6: + case HEADER_TYPE_IPv6_ROUTE: + case HEADER_TYPE_IPv6_FRAG: + case HEADER_TYPE_IPv6_NONXT: + case HEADER_TYPE_IPv6_OPTS: + case HEADER_TYPE_ETHERNET: + case HEADER_TYPE_IPv6_MOBILE: + aux=aux->getNextElement(); + break; + + /* If we found the transport layer, return it. */ + case HEADER_TYPE_TCP: + case HEADER_TYPE_UDP: + case HEADER_TYPE_ICMPv4: + case HEADER_TYPE_ICMPv6: + case HEADER_TYPE_SCTP: + case HEADER_TYPE_ARP: + return aux; + break; + + /* Otherwise, the packet contains headers we don't understand + * so we just return NULL to indicate that no valid transport + * layer was found. */ + default: + return NULL; + break; + } + } + return NULL; +} /* End of find_transport_layer() */ diff --git a/libnetutil/PacketParser.h b/libnetutil/PacketParser.h index 6854cb233..418b42f6f 100644 --- a/libnetutil/PacketParser.h +++ b/libnetutil/PacketParser.h @@ -158,6 +158,7 @@ class PacketParser { static int freePacketChain(PacketElement *first); static const char *test_packet_parser(PacketElement *test_pkt); static bool is_response(PacketElement *sent, PacketElement *rcvd); + static PacketElement *find_transport_layer(PacketElement *chain); }; /* End of class PacketParser */