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