"Fossies" - the Fresh Open Source Software Archive 
Member "snort3_extra-3.1.53.0/src/codecs/cd_pflog/cd_pflog.cc" (20 Dec 2022, 6644 Bytes) of package /linux/misc/snort3_extra-3.1.53.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cd_pflog.cc" see the
Fossies "Dox" file reference documentation.
1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2002-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation. You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //--------------------------------------------------------------------------
19
20 #include <net/if.h>
21 #include <daq_dlt.h>
22
23 #include "framework/codec.h"
24
25 using namespace snort;
26
27 #define PFLOG_NAME "pflog"
28 #define PFLOG_HELP_STR "support for OpenBSD PF log"
29
30 #define PFLOG_HELP ADD_DLT(PFLOG_HELP_STR, DLT_PFLOG)
31
32 namespace
33 {
34 /*
35 * Snort supports 3 versions of the OpenBSD pflog header:
36 *
37 * Pflog1_Hdr: CVS = 1.3, DLT_OLD_PFLOG = 17, Length = 28
38 * Pflog2_Hdr: CVS = 1.8, DLT_PFLOG = 117, Length = 48
39 * Pflog3_Hdr: CVS = 1.12, DLT_PFLOG = 117, Length = 64
40 * Pflog4_Hdr: CVS = 1.172, DLT_PFLOG = 117, Length = 100
41 *
42 * Since they have the same DLT, Pflog{2,3,4}Hdr are distinguished
43 * by their actual length. The minimum required length excludes
44 * padding.
45 */
46 /* Old OpenBSD pf firewall pflog0 header (information from pf source in kernel)
47 * the rule, reason, and action codes tell why the firewall dropped it -fleck
48 */
49
50 class PflogCodec : public Codec
51 {
52 public:
53 PflogCodec() : Codec(PFLOG_NAME) { }
54
55 bool decode(const RawData&, CodecData&, DecodeData&) override;
56 void get_data_link_type(std::vector<int>&) override;
57 };
58
59 struct Pflog1Hdr
60 {
61 uint32_t af;
62 char intf[IFNAMSIZ];
63 int16_t rule;
64 uint16_t reason;
65 uint16_t action;
66 uint16_t dir;
67 };
68
69 #define PFLOG1_HDRLEN (sizeof(struct _Pflog1_hdr))
70
71 /*
72 * Note that on OpenBSD, af type is sa_family_t. On Linux, that's an unsigned
73 * short, but on OpenBSD, that's a uint8_t, so we should explicitly use uint8_t
74 * here. - ronaldo
75 */
76
77 #define PFLOG_RULELEN 16
78 #define PFLOG_PADLEN 3
79
80 struct Pflog2Hdr
81 {
82 int8_t length;
83 uint8_t af;
84 uint8_t action;
85 uint8_t reason;
86 char ifname[IFNAMSIZ];
87 char ruleset[PFLOG_RULELEN];
88 uint32_t rulenr;
89 uint32_t subrulenr;
90 uint8_t dir;
91 uint8_t pad[PFLOG_PADLEN];
92 };
93
94 #define PFLOG2_HDRLEN (sizeof(Pflog2Hdr))
95 #define PFLOG2_HDRMIN (PFLOG2_HDRLEN - PFLOG_PADLEN)
96
97 struct Pflog3Hdr
98 {
99 int8_t length;
100 uint8_t af;
101 uint8_t action;
102 uint8_t reason;
103 char ifname[IFNAMSIZ];
104 char ruleset[PFLOG_RULELEN];
105 uint32_t rulenr;
106 uint32_t subrulenr;
107 uint32_t uid;
108 uint32_t pid;
109 uint32_t rule_uid;
110 uint32_t rule_pid;
111 uint8_t dir;
112 uint8_t pad[PFLOG_PADLEN];
113 };
114
115 #define PFLOG3_HDRLEN (sizeof(Pflog3Hdr))
116 #define PFLOG3_HDRMIN (PFLOG3_HDRLEN - PFLOG_PADLEN)
117
118 struct Pflog4Hdr
119 {
120 uint8_t length;
121 uint8_t af;
122 uint8_t action;
123 uint8_t reason;
124 char ifname[IFNAMSIZ];
125 char ruleset[PFLOG_RULELEN];
126 uint32_t rulenr;
127 uint32_t subrulenr;
128 uint32_t uid;
129 uint32_t pid;
130 uint32_t rule_uid;
131 uint32_t rule_pid;
132 uint8_t dir;
133 uint8_t rewritten;
134 uint8_t pad[2];
135 uint8_t saddr[16];
136 uint8_t daddr[16];
137 uint16_t sport;
138 uint16_t dport;
139 };
140
141 #define PFLOG4_HDRLEN sizeof(struct Pflog4Hdr)
142 #define PFLOG4_HDRMIN sizeof(struct Pflog4Hdr)
143 } // namespace
144
145 void PflogCodec::get_data_link_type(std::vector<int>& v)
146 { v.push_back(DLT_PFLOG); }
147
148 bool PflogCodec::decode(const RawData& raw, CodecData& codec, DecodeData&)
149 {
150 const uint32_t cap_len = raw.len;
151 uint8_t af, pflen;
152 uint32_t hlen;
153 uint32_t padlen = PFLOG_PADLEN;
154
155 if (cap_len < PFLOG2_HDRMIN)
156 return false;
157
158 /* lay the pf header structure over the packet data */
159 switch (*((const uint8_t*)raw.data))
160 {
161 case PFLOG2_HDRMIN:
162 {
163 const Pflog2Hdr* const pf2h =
164 reinterpret_cast<const Pflog2Hdr*>(raw.data);
165 pflen = pf2h->length;
166 hlen = PFLOG2_HDRLEN;
167 af = pf2h->af;
168 break;
169 }
170 case PFLOG3_HDRMIN:
171 {
172 const Pflog3Hdr* const pf3h =
173 reinterpret_cast<const Pflog3Hdr*>(raw.data);
174 pflen = pf3h->length;
175 hlen = PFLOG3_HDRLEN;
176 af = pf3h->af;
177 break;
178 }
179 case PFLOG4_HDRMIN:
180 {
181 const Pflog4Hdr* const pf4h =
182 reinterpret_cast<const Pflog4Hdr*>(raw.data);
183 pflen = pf4h->length;
184 hlen = PFLOG4_HDRLEN;
185 af = pf4h->af;
186 padlen = sizeof(pf4h->pad);
187 break;
188 }
189 default:
190 return false;
191 }
192
193 /* now that we know a little more, do a little more validation */
194 if (cap_len < hlen)
195 return false;
196
197 /* note that the pflen may exclude the padding which is always present */
198 if (pflen < hlen - padlen || pflen > hlen)
199 return false;
200
201 /* check the network type - should only be AF_INET or AF_INET6 */
202 switch (af)
203 {
204 case AF_INET: /* IPv4 */
205 codec.next_prot_id = ProtocolId::ETHERTYPE_IPV4;
206 break;
207
208 case AF_INET6: /* IPv6 */
209 codec.next_prot_id = ProtocolId::ETHERTYPE_IPV6;
210 break;
211
212 default:
213 /* FIXIT-L add decoder drop event for unknown pflog network type
214 * To my knowledge, pflog devices can only
215 * pass IP and IP6 packets. -fleck
216 */
217 break;
218 }
219
220 codec.lyr_len = hlen;
221 return true;
222 }
223
224 //-------------------------------------------------------------------------
225 // api
226 //-------------------------------------------------------------------------
227
228 static Codec* ctor(Module*)
229 { return new PflogCodec(); }
230
231 static void dtor(Codec* cd)
232 { delete cd; }
233
234 static const CodecApi pflog_api =
235 {
236 {
237 PT_CODEC,
238 sizeof(CodecApi),
239 CDAPI_VERSION,
240 0,
241 API_RESERVED,
242 API_OPTIONS,
243 PFLOG_NAME,
244 PFLOG_HELP,
245 nullptr, // mod_ctor
246 nullptr // mod_dtor
247 },
248 nullptr, // ginit
249 nullptr, // gterm
250 nullptr, // tinit
251 nullptr, // tterm
252 ctor,
253 dtor,
254 };
255
256 SO_PUBLIC const BaseApi* snort_plugins[] =
257 {
258 &pflog_api.base,
259 nullptr
260 };