1 
2 /***************************************************************************
3  * PacketElement.h -- The PacketElement Class is a generic class that      *
4  * represents a protocol header or a part of a network packet. Many other  *
5  * classes inherit from it (NetworkLayerElement, TransportLayerElement,    *
6  * etc).                                                                   *
7  *                                                                         *
8  ***********************IMPORTANT NMAP LICENSE TERMS************************
9  *                                                                         *
10  * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap  *
11  * Project"). Nmap is also a registered trademark of the Nmap Project.     *
12  *                                                                         *
13  * This program is distributed under the terms of the Nmap Public Source   *
14  * License (NPSL). The exact license text applying to a particular Nmap    *
15  * release or source code control revision is contained in the LICENSE     *
16  * file distributed with that version of Nmap or source code control       *
17  * revision. More Nmap copyright/legal information is available from       *
18  * https://nmap.org/book/man-legal.html, and further information on the    *
19  * NPSL license itself can be found at https://nmap.org/npsl. This header  *
20  * summarizes some key points from the Nmap license, but is no substitute  *
21  * for the actual license text.                                            *
22  *                                                                         *
23  * Nmap is generally free for end users to download and use themselves,    *
24  * including commercial use. It is available from https://nmap.org.        *
25  *                                                                         *
26  * The Nmap license generally prohibits companies from using and           *
27  * redistributing Nmap in commercial products, but we sell a special Nmap  *
28  * OEM Edition with a more permissive license and special features for     *
29  * this purpose. See https://nmap.org/oem                                  *
30  *                                                                         *
31  * If you have received a written Nmap license agreement or contract       *
32  * stating terms other than these (such as an Nmap OEM license), you may   *
33  * choose to use and redistribute Nmap under those terms instead.          *
34  *                                                                         *
35  * The official Nmap Windows builds include the Npcap software             *
36  * (https://npcap.org) for packet capture and transmission. It is under    *
37  * separate license terms which forbid redistribution without special      *
38  * permission. So the official Nmap Windows builds may not be              *
39  * redistributed without special permission (such as an Nmap OEM           *
40  * license).                                                               *
41  *                                                                         *
42  * Source is provided to this software because we believe users have a     *
43  * right to know exactly what a program is going to do before they run it. *
44  * This also allows you to audit the software for security holes.          *
45  *                                                                         *
46  * Source code also allows you to port Nmap to new platforms, fix bugs,    *
47  * and add new features.  You are highly encouraged to submit your         *
48  * changes as a Github PR or by email to the dev@nmap.org mailing list     *
49  * for possible incorporation into the main distribution. Unless you       *
50  * specify otherwise, it is understood that you are offering us very       *
51  * broad rights to use your submissions as described in the Nmap Public    *
52  * Source License Contributor Agreement. This is important because we      *
53  * fund the project by selling licenses with various terms, and also       *
54  * because the inability to relicense code has caused devastating          *
55  * problems for other Free Software projects (such as KDE and NASM).       *
56  *                                                                         *
57  * The free version of Nmap is distributed in the hope that it will be     *
58  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  *
59  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,        *
60  * indemnification and commercial support are all available through the    *
61  * Npcap OEM program--see https://nmap.org/oem.                            *
62  *                                                                         *
63  ***************************************************************************/
64 /* This code was originally part of the Nping tool.                        */
65 
66 #ifndef PACKETELEMENT_H
67 #define PACKETELEMENT_H  1
68 
69 #include "nbase.h"
70 #include "netutil.h"
71 
72 #define HEADER_TYPE_IPv6_HOPOPT   0  /* IPv6 Hop-by-Hop Option                */
73 #define HEADER_TYPE_ICMPv4        1  /* ICMP Internet Control Message         */
74 #define HEADER_TYPE_IGMP          2  /* IGMP Internet Group Management        */
75 #define HEADER_TYPE_IPv4          4  /* IPv4 IPv4 encapsulation               */
76 #define HEADER_TYPE_TCP           6  /* TCP Transmission Control              */
77 #define HEADER_TYPE_EGP           8  /* EGP Exterior Gateway Protocol         */
78 #define HEADER_TYPE_UDP           17 /* UDP User Datagram                     */
79 #define HEADER_TYPE_IPv6          41 /* IPv6 IPv6 encapsulation               */
80 #define HEADER_TYPE_IPv6_ROUTE    43 /* IPv6-Route Routing Header for IPv6    */
81 #define HEADER_TYPE_IPv6_FRAG     44 /* IPv6-Frag Fragment Header for IPv6    */
82 #define HEADER_TYPE_GRE           47 /* GRE General Routing Encapsulation     */
83 #define HEADER_TYPE_ESP           50 /* ESP Encap Security Payload            */
84 #define HEADER_TYPE_AH            51 /* AH Authentication Header              */
85 #define HEADER_TYPE_ICMPv6        58 /* IPv6-ICMP ICMP for IPv6               */
86 #define HEADER_TYPE_IPv6_NONXT    59 /* IPv6-NoNxt No Next Header for IPv6    */
87 #define HEADER_TYPE_IPv6_OPTS     60 /* IPv6-Opts IPv6 Destination Options    */
88 #define HEADER_TYPE_EIGRP         88 /* EIGRP                                 */
89 #define HEADER_TYPE_ETHERNET      97 /* Ethernet                              */
90 #define HEADER_TYPE_L2TP         115 /* L2TP Layer Two Tunneling Protocol     */
91 #define HEADER_TYPE_SCTP         132 /* SCTP Stream Control Transmission P.   */
92 #define HEADER_TYPE_IPv6_MOBILE  135 /* Mobility Header                       */
93 #define HEADER_TYPE_MPLS_IN_IP   137 /* MPLS-in-IP                            */
94 #define HEADER_TYPE_ARP         2054 /* ARP Address Resolution Protocol       */
95 #define HEADER_TYPE_ICMPv6_OPTION 9997 /* ICMPv6 option                       */
96 #define HEADER_TYPE_NEP         9998 /* Nping Echo Protocol                   */
97 #define HEADER_TYPE_RAW_DATA    9999 /* Raw unknown data                      */
98 
99 #define PRINT_DETAIL_LOW   1
100 #define PRINT_DETAIL_MED   2
101 #define PRINT_DETAIL_HIGH  3
102 
103 #define DEFAULT_PRINT_DETAIL (PRINT_DETAIL_LOW)
104 #define DEFAULT_PRINT_DESCRIPTOR stdout
105 
106 class PacketElement {
107 
108   protected:
109 
110     int length;
111     PacketElement *next;    /**< Next PacketElement (next proto header)      */
112     PacketElement *prev;    /**< Prev PacketElement (previous proto header)  */
113 
114   public:
115 
116     PacketElement();
117 
~PacketElement()118     virtual ~PacketElement(){
119 
120     } /* End of PacketElement destructor */
121 
122     /** This function MUST be overwritten on ANY class that inherits from
123       *  this one. Otherwise getBinaryBuffer will fail */
getBufferPointer()124     virtual u8 * getBufferPointer(){
125         netutil_fatal("getBufferPointer(): Attempting to use superclass PacketElement method.\n");
126         return NULL;
127      } /* End of getBufferPointer() */
128 
129 
130     /** Returns a buffer that contains the header of the packet + all the
131      *  lower level headers and payload. Returned buffer should be ok to be
132      *  passes to a send() call to be transferred trough a socket.
133      *  @return a pointer to a free()able buffer that contains packet's binary
134      *  data.
135      *  @warning If there are linked elements, their getBinaryBuffer() method
136      *  will be called recursively and the buffers that they return WILL be
137      *  free()d as soon as we copy the data in our own allocated buffer.
138      *  @warning Calls to this method may not ve very efficient since they
139      *  always involved a few malloc()s and free()s. If you want efficiency
140      *  use dumpToBinaryBuffer(); */
getBinaryBuffer()141     virtual u8 * getBinaryBuffer(){
142       u8 *ourbuff=NULL;
143       u8 *othersbuff=NULL;
144       u8 *totalbuff=NULL;
145       long otherslen=0;
146 
147       /* Get our own buffer address */
148       if ( (ourbuff=getBufferPointer()) == NULL ){
149           netutil_fatal("getBinaryBuffer(): Couldn't get own data pointer\n");
150       }
151       if( next != NULL ){ /* There is some other packet element */
152         othersbuff = next->getBinaryBuffer();
153         otherslen=next->getLen();
154         totalbuff=(u8 *)safe_zalloc(otherslen + length);
155         memcpy(totalbuff, ourbuff, length);
156         memcpy(totalbuff+length, othersbuff, otherslen);
157         free(othersbuff);
158       }else{
159            totalbuff=(u8 *)safe_zalloc(length);
160            memcpy(totalbuff, ourbuff, length);
161       }
162       return totalbuff;
163     } /* End of getBinaryBuffer() */
164 
165 
dumpToBinaryBuffer(u8 * dst,int maxlen)166     virtual int dumpToBinaryBuffer(u8* dst, int maxlen){
167       u8 *ourbuff=NULL;
168       long ourlength=0;
169       /* Get our own buffer address and length */
170       if ( (ourbuff=getBufferPointer()) == NULL ||  (ourlength=this->length) < 0 )
171             netutil_fatal("getBinaryBuffer(): Couldn't get own data pointer\n");
172       /* Copy our part of the buffer */
173       if ( maxlen < ourlength )
174             netutil_fatal("getBinaryBuffer(): Packet exceeds maximum length %d\n", maxlen);
175       memcpy( dst, ourbuff, ourlength);
176        /* If there are more elements, tell them to copy their part */
177        if( next!= NULL ){
178             next->dumpToBinaryBuffer(dst+ourlength, maxlen-ourlength);
179        }
180        return this->getLen();
181     } /* End of dumpToBinaryBuffer() */
182 
183 
184     /** Does the same as the previous one but it stores the length of the
185      *  return buffer on the memory pointed by the supplied int pointer.     */
getBinaryBuffer(int * len)186     virtual u8 * getBinaryBuffer(int *len){
187       u8 *buff = getBinaryBuffer();
188       if( len != NULL )
189          *len = getLen();
190       return buff;
191     } /* End of getBinaryBuffer() */
192 
193 
194     /** Returns the length of this PacketElement + the length of all the
195      *  PacketElements that are next to it (are linked trough the "next"
196      *  attribute). So for example, if we have IPv4Header p1, linked to
197      *  a TCPHeader p2, representing a simple TCP SYN with no options,
198      *  a call to p1.getLen() will return 20 (IP header with no options) + 20
199      *  (TCP header with no options) = 40 bytes.                             */
getLen()200     int getLen() const {
201         /* If we have some other packet element linked, get its length */
202         if (next!=NULL)
203             return length + next->getLen();
204         else
205             return length;
206     } /* End of getLen() */
207 
208 
209     /** Returns the address of the next PacketElement that is linked to this */
getNextElement()210     virtual PacketElement *getNextElement() const {
211       return next;
212     } /* End of getNextElement() */
213 
214 
215     /** Links current object with the next header in the protocol chain. Note
216      * that this method also links the next element with this one, calling
217      * setPrevElement(). */
setNextElement(PacketElement * n)218     virtual int setNextElement(PacketElement *n){
219       next=n;
220       if(next!=NULL)
221           next->setPrevElement(this);
222       return OP_SUCCESS;
223     } /* End of setNextElement() */
224 
225     /** Sets attribute prev with the supplied pointer value.
226      *  @warning Supplied pointer must point to a PacketElement object or
227      *  an object that inherits from it.                                     */
setPrevElement(PacketElement * n)228     virtual int setPrevElement(PacketElement *n){
229       this->prev=n;
230       return OP_SUCCESS;
231     } /* End of setPrevElement() */
232 
233 
234     /** Returns the address of the previous PacketElement that is linked to
235      *  this one.
236      *  @warning In many cases this function will return NULL since there is
237      *  a high probability that the user of this class does not link
238      *  PacketElements in both directions. Normally one would set attribute
239      *  "next" of an IPHeader object to the TCPHeader that follows it, but
240      *  not the other way around. */
getPrevElement()241     virtual PacketElement *getPrevElement(){
242       return prev;
243     } /* End of getPrevElement() */
244 
245     /** This method should be overwritten by any class that inherits from
246       * PacketElement. It should print the object contents and then call
247       * this->next->print(), providing this->next!=NULL */
print(FILE * output,int detail)248     virtual int print(FILE *output, int detail) const {
249         if(this->next!=NULL)
250             this->next->print(output, detail);
251         return OP_SUCCESS;
252     } /* End of printf() */
253 
print()254     virtual int print() const {
255         return print(DEFAULT_PRINT_DESCRIPTOR, DEFAULT_PRINT_DETAIL);
256     }
257 
print(int detail)258     virtual int print(int detail) const {
259         return print(DEFAULT_PRINT_DESCRIPTOR, detail);
260     }
261 
print_separator(FILE * output,int detail)262     virtual void print_separator(FILE *output, int detail) const {
263         fprintf(output, " ");
264     }
265 
266     /* Returns the type of protocol an object represents. This method MUST
267      * be overwritten by all children. */
268     virtual int protocol_id() const = 0;
269 };
270 
271 #endif
272