1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // layer.h author Josh Rosenbaum <jrosenba@cisco.com>
19 
20 #ifndef PROTOCOLS_LAYER_H
21 #define PROTOCOLS_LAYER_H
22 
23 #include "main/snort_types.h"
24 #include "protocols/protocol_ids.h"
25 
26 namespace snort
27 {
28 struct Layer
29 {
30     const uint8_t* start;
31     ProtocolId prot_id;
32     uint16_t length;
33 };
34 
35 // forward declaring relevant structs. Since we're only returning a pointer,
36 // there is no need for the actual header files
37 
38 namespace arp
39 {
40 struct EtherARP;
41 }
42 
43 namespace cisco_meta_data
44 {
45 struct CiscoMetaDataHdr;
46 }
47 
48 namespace eapol
49 {
50 struct EtherEapol;
51 }
52 
53 namespace eth
54 {
55 struct EtherHdr;
56 }
57 
58 namespace geneve
59 {
60 struct GeneveHdr;
61 }
62 
63 namespace gre
64 {
65 struct GREHdr;
66 }
67 
68 namespace icmp
69 {
70 struct ICMPHdr;
71 }
72 
73 namespace ip
74 {
75 class IpApi;
76 struct IP6Frag;
77 }
78 
79 namespace tcp
80 {
81 struct TCPHdr;
82 }
83 
84 namespace udp
85 {
86 struct UDPHdr;
87 }
88 
89 namespace vlan
90 {
91 struct VlanTagHdr;
92 }
93 
94 namespace wlan
95 {
96 struct WifiHdr;
97 }
98 
99 struct Packet;
100 
101 namespace layer
102 {
103 //  Set by PacketManager.  Ensure you can call layer:: without a packet pointers
104 void set_packet_pointer(const Packet* const);
105 
106 SO_PUBLIC const uint8_t* get_root_layer(const Packet* const);
107 
108 SO_PUBLIC const uint8_t* get_inner_layer(const Packet*, ProtocolId proto);
109 SO_PUBLIC const uint8_t* get_outer_layer(const Packet*, ProtocolId proto);
110 
111 SO_PUBLIC const arp::EtherARP* get_arp_layer(const Packet*);
112 SO_PUBLIC const cisco_meta_data::CiscoMetaDataHdr* get_cisco_meta_data_layer(const Packet* const);
113 SO_PUBLIC const eapol::EtherEapol* get_eapol_layer(const Packet*);
114 SO_PUBLIC const eth::EtherHdr* get_eth_layer(const Packet*);
115 SO_PUBLIC const geneve::GeneveHdr* get_geneve_layer(const Packet*);
116 SO_PUBLIC const gre::GREHdr* get_gre_layer(const Packet*);
117 SO_PUBLIC const vlan::VlanTagHdr* get_vlan_layer(const Packet*);
118 SO_PUBLIC const wlan::WifiHdr* get_wifi_layer(const Packet*);
119 
120 /* return a pointer to the outermost UDP layer */
121 SO_PUBLIC const udp::UDPHdr* get_outer_udp_lyr(const Packet* const);
122 // return the inner ip layer's index in the p->layers array
123 SO_PUBLIC int get_inner_ip_lyr_index(const Packet* const);
124 SO_PUBLIC const Layer* get_mpls_layer(const Packet* const);
125 
126 // Two versions of this because ip_defrag:: wants to call this on
127 // its rebuilt packet, not on the current packet.  Extra function
128 // header will be removed once layer is a part of the Packet struct
129 SO_PUBLIC const ip::IP6Frag* get_inner_ip6_frag();
130 SO_PUBLIC const ip::IP6Frag* get_inner_ip6_frag(const Packet* const);
131 
132 // returns -1 on failure if no frag layer exists.
133 // else, returns zero based ip6 index
134 SO_PUBLIC int get_inner_ip6_frag_index(const Packet* const);
135 
136 // ICMP with Embedded IP layer
137 
138 // Sets the Packet's api to be the IP layer which is
139 // embedded inside an ICMP layer.
140 // RETURN:
141 //          true - ip layer found and api set
142 //          false - ip layer NOT found, api reset
143 SO_PUBLIC bool set_api_ip_embed_icmp(const Packet*, ip::IpApi& api);
144 
145 /*
146  *When a protocol is embedded in ICMP, these functions
147  * will return a pointer to the layer.  Use the
148  * proto_bits before calling these function to determine
149  * what this layer is!
150  */
151 SO_PUBLIC const tcp::TCPHdr* get_tcp_embed_icmp(const ip::IpApi&);
152 SO_PUBLIC const udp::UDPHdr* get_udp_embed_icmp(const ip::IpApi&);
153 SO_PUBLIC const icmp::ICMPHdr* get_icmp_embed_icmp(const ip::IpApi&);
154 /*
155  * Starting from layer 'curr_layer', continuing looking at increasingly
156  * outermost layer for another IP protocol.  If an IP protocol is found,
157  * set the given ip_api to that layer.
158  * PARAMS:
159  *          Packet* = packet struct containing data
160  *          ip::Api = ip api to be set
161  *          uint8_t& next_ip_proto = The ip_protocol after the current IP
162  *                              layer refer to packet get_next_ip_proto()
163  *                              for more information.
164  *          int8_t curr_layer = the current, zero based layer from which to
165  *                              start searching inward. After the function returns,
166  *                              This field will be set to the layer before
167  *                              the Ip Api.  If no IP layer is found,
168  *                              it will be set to -1.
169  *
170  *                               0 <= curr_layer < p->num_layers
171  * RETURNS:
172  *          true:  if the api is set
173  *          false: if the api has NOT been set
174  *
175  * NOTE: curr_layer is zero based.  That means to get all of the ip
176  *       layers (starting from the innermost layer), during the first call
177  *       'curr_layer == p->num_layers'.
178  *
179  * NOTE: This functions is extremely useful in a loop
180  *          while (set_inner_ip_api(p, api, layer)) { ... }
181  */
182 SO_PUBLIC bool set_inner_ip_api(const Packet* const, ip::IpApi&, int8_t& curr_layer);
183 SO_PUBLIC bool set_inner_ip_api(const Packet* const, ip::IpApi&,
184     IpProtocol& next_ip_proto, int8_t& curr_layer);
185 
186 /*
187  * Identical to above function except will begin searching from the
188  * outermost layer until the innermost layer.
189  *
190  * NOTE: curr_layer is zero based.  That means to get all of the ip
191  *       layers (starting from the OUTERMOST layer), during the first call
192  *       'curr_layer == 0'.
193  */
194 SO_PUBLIC bool set_outer_ip_api(const Packet* const, ip::IpApi&, int8_t& curr_layer);
195 SO_PUBLIC bool set_outer_ip_api(const Packet* const, ip::IpApi&,
196     IpProtocol& next_ip_proto, int8_t& curr_layer);
197 } // namespace layer
198 } // namespace snort
199 #endif
200 
201