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 // packet.cc author Josh Rosenbaum <jrosenba@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "packet.h"
25
26 #include "detection/ips_context.h"
27 #include "flow/expect_cache.h"
28 #include "framework/endianness.h"
29 #include "log/obfuscator.h"
30 #include "packet_io/active.h"
31 #include "managers/codec_manager.h"
32
33 #include "packet_manager.h"
34 #include "vlan.h"
35 #include "geneve.h"
36
37 namespace snort
38 {
Packet(bool packet_data)39 Packet::Packet(bool packet_data)
40 {
41 layers = new Layer[CodecManager::get_max_layers()];
42 allocated = packet_data;
43
44 if (!packet_data)
45 {
46 pkt = nullptr;
47 pkth = nullptr;
48 }
49 else
50 {
51 pkth = new DAQ_PktHdr_t();
52 pkt = new uint8_t[Codec::PKT_MAX];
53 }
54
55 obfuscator = nullptr;
56 endianness = nullptr;
57 active_inst = new Active();
58 action_inst = nullptr;
59 reset();
60 }
61
~Packet()62 Packet::~Packet()
63 {
64 release_helpers();
65
66 if (allocated)
67 {
68 delete pkth;
69 delete[] pkt;
70 }
71 delete active_inst;
72 delete[] layers;
73 }
74
reset()75 void Packet::reset()
76 {
77 flow = nullptr;
78 packet_flags = 0;
79 ts_packet_flags = 0;
80 xtradata_mask = 0;
81 proto_bits = 0;
82 alt_dsize = 0;
83 num_layers = 0;
84 ip_proto_next = IpProtocol::PROTO_NOT_SET;
85 disable_inspect = false;
86 ExpectFlow::reset_expect_flows();
87
88 release_helpers();
89 ptrs.reset();
90
91 iplist_id = 0;
92 user_inspection_policy_id = 0;
93 user_ips_policy_id = 0;
94 user_network_policy_id = 0;
95 vlan_idx = 0;
96 filtering_state.clear();
97 }
98
release_helpers()99 void Packet::release_helpers()
100 {
101 if ( obfuscator )
102 {
103 delete obfuscator;
104 obfuscator = nullptr;
105 }
106
107 if ( endianness )
108 {
109 delete endianness;
110 endianness = nullptr;
111 }
112 }
113
get_ip_proto_next(uint8_t & lyr,IpProtocol & proto) const114 bool Packet::get_ip_proto_next(uint8_t& lyr, IpProtocol& proto) const
115 {
116 if (lyr > num_layers)
117 return false;
118
119 while (lyr < num_layers)
120 {
121 switch (layers[lyr].prot_id)
122 {
123 case ProtocolId::IPV6:
124 case ProtocolId::ETHERTYPE_IPV6:
125 // move past this IP layer and any IPv6 extensions.
126 while ( ((lyr + 1) < num_layers) && is_ip6_extension(layers[lyr+1].prot_id) )
127 ++lyr;
128
129 if ( (layers[lyr].prot_id == ProtocolId::IPV6) || (layers[lyr].prot_id ==
130 ProtocolId::ETHERTYPE_IPV6) )
131 proto = reinterpret_cast<const ip::IP6Hdr*>(layers[lyr++].start)->next();
132 else
133 proto = reinterpret_cast<const ip::IP6Extension*>(layers[lyr++].start)->ip6e_nxt;
134
135 return true;
136
137 case ProtocolId::ETHERTYPE_IPV4:
138 case ProtocolId::IPIP:
139 proto = reinterpret_cast<const ip::IP4Hdr*>(layers[lyr++].start)->proto();
140 return true;
141
142 default:
143 ++lyr;
144 }
145 }
146
147 return false;
148 }
149
get_type() const150 const char* Packet::get_type() const
151 {
152 switch ( ptrs.get_pkt_type() )
153 {
154 case PktType::IP:
155 return "IP";
156
157 case PktType::ICMP:
158 return "ICMP";
159
160 case PktType::TCP:
161 return "TCP";
162
163 case PktType::UDP:
164 return "UDP";
165
166 case PktType::PDU:
167 case PktType::FILE:
168 if ( proto_bits & PROTO_BIT__TCP )
169 return "TCP";
170
171 if ( proto_bits & PROTO_BIT__UDP )
172 return "UDP";
173
174 assert(false);
175 return "Error";
176
177 case PktType::NONE:
178 if ( proto_bits & PROTO_BIT__ARP )
179 return "ARP";
180
181 if ( num_layers > 0 )
182 return PacketManager::get_proto_name(layers[num_layers-1].prot_id);
183
184 return "None";
185
186 default:
187 break;
188 }
189 assert(false);
190 return "Error";
191 }
192
get_pseudo_type() const193 const char* Packet::get_pseudo_type() const
194 {
195 if ( !(packet_flags & PKT_PSEUDO) )
196 return "raw";
197
198 switch ( pseudo_type )
199 {
200 case PSEUDO_PKT_IP:
201 return "stream_ip";
202
203 case PSEUDO_PKT_TCP:
204 return "stream_tcp";
205
206 case PSEUDO_PKT_USER:
207 return "stream_user";
208
209 case PSEUDO_PKT_DCE_SEG:
210 return "dce2_rpc_deseg";
211
212 case PSEUDO_PKT_DCE_FRAG:
213 return "dce2_rpc_defrag";
214
215 case PSEUDO_PKT_SMB_SEG:
216 return "dce2_smb_deseg";
217
218 case PSEUDO_PKT_SMB_TRANS:
219 return "dce2_smb_transact";
220
221 default: break;
222 }
223 return "other";
224 }
225
226 // Things that are set prior to PDU creation and used after PDU creation
get_session_flags(const Packet & p)227 static inline uint32_t get_session_flags(const Packet& p)
228 {
229 if ( p.ptrs.get_pkt_type() == PktType::PDU )
230 return p.context->get_session_flags();
231
232 return p.flow ? p.flow->get_session_flags() : 0;
233 }
234
is_detection_enabled(bool to_server)235 bool Packet::is_detection_enabled(bool to_server)
236 {
237 uint32_t session_flags = get_session_flags(*this);
238
239 if ( to_server )
240 return !(session_flags & SSNFLAG_NO_DETECT_TO_SERVER);
241
242 return !(session_flags & SSNFLAG_NO_DETECT_TO_CLIENT);
243 }
244
test_session_flags(uint32_t flags)245 bool Packet::test_session_flags(uint32_t flags)
246 { return (get_session_flags(*this) & flags) != 0; }
247
get_snort_protocol_id()248 SnortProtocolId Packet::get_snort_protocol_id()
249 {
250 if ( ptrs.get_pkt_type() == PktType::PDU )
251 return context->get_snort_protocol_id();
252
253 return flow ? flow->ssn_state.snort_protocol_id : UNKNOWN_PROTOCOL_ID;
254 }
255
get_flow_vlan_id() const256 uint16_t Packet::get_flow_vlan_id() const
257 {
258 uint16_t vid = 0;
259
260 if (flow)
261 vid = flow->key->vlan_tag;
262 else if ( !context->conf->get_vlan_agnostic() and (proto_bits & PROTO_BIT__VLAN) )
263 vid = layer::get_vlan_layer(this)->vid();
264
265 return vid;
266 }
267
get_flow_geneve_vni() const268 uint32_t Packet::get_flow_geneve_vni() const
269 {
270 uint32_t vni = 0;
271
272 if (proto_bits & PROTO_BIT__GENEVE)
273 vni = layer::get_geneve_layer(this)->vni();
274
275 return vni;
276 }
277
is_from_application_client() const278 bool Packet::is_from_application_client() const
279 {
280 if (flow)
281 return flow->flags.app_direction_swapped ? is_from_server() : is_from_client();
282 else
283 return is_from_client();
284 }
285
is_from_application_server() const286 bool Packet::is_from_application_server() const
287 {
288 if (flow)
289 return flow->flags.app_direction_swapped ? is_from_client() : is_from_server();
290 else
291 return is_from_server();
292 }
293
294 } // namespace snort
295
296