[Snort-devel] snort with openbsd pflog on linux box
Ronaldo Maia
romaia at ...2474...
Thu Jul 26 10:39:23 EDT 2007
Hello there!
Sometime ago, we were using a openbsd box with snort to parse
openbsd's pflogs and that was working fine, but recently we move to a
linux box, and snort was not able to parse that correctly anymore.
Investigating the source, I found quite a few issues:
- openbsd pfloghdr changed, and snort PflogHdr is no longer up-to-date
with that. [http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_pflog.h]
- given this change, snort should be able to parse pflogs with
different headers. just like tcpdump can.
- openbsd and linux sa_family_t types are different:
linux: typedef unsigned short sa_family_t;
openbsd: typedef u_int8_t sa_family_t;
So, a snort compiled on linux wouldn't parse pflogs correctly.
- on this two systems, AF_INET6 differ too:
linux: #define AF_INET6 10
openbsd: #define AF_INET6 24
Again, we have a problem.
So, based on tcpdump code, I came up with a patch (attached), that
fixes all this problems.
I hope I did the right thing, and would like to see some thoughts on it.
--
Ronaldo Maia
-------------- next part --------------
Index: src/decode.c
===================================================================
RCS file: /cvsroot/snort/src/decode.c,v
retrieving revision 1.139
diff -u -p -r1.139 decode.c
--- src/decode.c 6 Jul 2007 15:57:47 -0000 1.139
+++ src/decode.c 26 Jul 2007 14:09:47 -0000
@@ -1252,6 +1252,9 @@ void DecodeOldPflog(Packet * p, struct p
return;
}
+#define OPENBSD_AF_INET 2
+#define OPENBSD_AF_INET6 24
+
/*
* Function: DecodePflog(Packet *, struct pcap_pkthdr *, u_int8_t *)
*
@@ -1268,6 +1271,7 @@ void DecodePflog(Packet * p, struct pcap
{
u_int32_t pkt_len; /* suprisingly, the length of the packet */
u_int32_t cap_len; /* caplen value */
+ u_int hdrlen;
PROFILE_VARS;
PREPROC_PROFILE_START(decodePerfStats);
@@ -1289,7 +1293,7 @@ void DecodePflog(Packet * p, struct pcap
(unsigned long)cap_len, (unsigned long)pkt_len););
/* do a little validation */
- if(p->pkth->caplen < PFLOG_HDRLEN)
+ if(p->pkth->caplen < MIN_PFLOG_HDRLEN)
{
if(pv.verbose_flag)
{
@@ -1302,22 +1306,30 @@ void DecodePflog(Packet * p, struct pcap
/* lay the pf header structure over the packet data */
p->pfh = (PflogHdr *) pkt;
+ /* depending on OpenBSD version, pflog header may have different sizes. */
+ hdrlen = BPF_WORDALIGN(p->pfh->length);
/* get the network type - should only be AF_INET or AF_INET6 */
/* p->pfh->af is sa_family_t which is a u_int8_t */
switch(p->pfh->af)
{
case AF_INET: /* IPv4 */
+#if OPENBSD_AF_INET != AF_INET
+ case OPENBSD_AF_INET: /* XXX: read pcap files */
+#endif
DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu "
"bytes\n", (unsigned long)(cap_len - PFLOG_HDRLEN)););
- DecodeIP(p->pkt + PFLOG_HDRLEN, cap_len - PFLOG_HDRLEN, p);
+ DecodeIP(p->pkt + hdrlen, cap_len - hdrlen, p);
PREPROC_PROFILE_END(decodePerfStats);
return;
#ifdef AF_INET6
case AF_INET6: /* IPv6 */
- DecodeIPV6(p->pkt + PFLOG_HDRLEN, (cap_len - PFLOG_HDRLEN), p);
+#if OPENBSD_AF_INET6 != AF_INET6
+ case OPENBSD_AF_INET6: /* XXX: read pcap files */
+#endif
+ DecodeIPV6(p->pkt + hdrlen, (cap_len - hdrlen), p);
PREPROC_PROFILE_END(decodePerfStats);
return;
#endif
Index: src/decode.h
===================================================================
RCS file: /cvsroot/snort/src/decode.h,v
retrieving revision 1.104
diff -u -p -r1.104 decode.h
--- src/decode.h 6 Jul 2007 15:57:47 -0000 1.104
+++ src/decode.h 26 Jul 2007 14:09:48 -0000
@@ -735,23 +735,33 @@ typedef struct _OldPflog_hdr
/* OpenBSD pf firewall pflog0 header
* (information from pf source in kernel)
* the rule, reason, and action codes tell why the firewall dropped it -fleck
+ *
+ * Note that on OpenBSD, af type is sa_family_t. On linux, that's a unsigned short, but
+ * on OpenBSD, that's a u_int8_t, so we should explicitly use u_int8_t here.
*/
typedef struct _Pflog_hdr
{
- int8_t length;
- sa_family_t af;
+ u_int8_t length;
+ u_int8_t af;
u_int8_t action;
u_int8_t reason;
char ifname[IFNAMSIZ];
char ruleset[16];
u_int32_t rulenr;
u_int32_t subrulenr;
+ uid_t uid;
+ pid_t pid;
+ uid_t rule_uid;
+ pid_t rule_pid;
u_int8_t dir;
u_int8_t pad[3];
} PflogHdr;
-#define PFLOG_HDRLEN sizeof(struct _Pflog_hdr)
+#define PFLOG_HDRLEN sizeof(struct _Pflog_hdr)
+#define MIN_PFLOG_HDRLEN 45
+
+
/*
* ssl_pkttype values.
More information about the Snort-devel
mailing list