From 04ccfda6398820ccc570497ea76aea5966dc368c Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 13 Apr 2015 12:12:46 +0200 Subject: [PATCH] pcap: implement LINKTYPE_NULL Implement LINKTYPE_NULL for pcap live and pcap file. From: http://www.tcpdump.org/linktypes.html "BSD loopback encapsulation; the link layer header is a 4-byte field, in host byte order, containing a PF_ value from socket.h for the network-layer protocol of the packet. Note that ``host byte order'' is the byte order of the machine on which the packets are captured, and the PF_ values are for the OS of the machine on which the packets are captured; if a live capture is being done, ``host byte order'' is the byte order of the machine capturing the packets, and the PF_ values are those of the OS of the machine capturing the packets, but if a ``savefile'' is being read, the byte order and PF_ values are not necessarily those of the machine reading the capture file." Feature ticket #1445 --- rules/decoder-events.rules | 7 ++- src/Makefile.am | 1 + src/decode-events.h | 4 ++ src/decode-null.c | 89 ++++++++++++++++++++++++++++++++++++++ src/decode-null.h | 27 ++++++++++++ src/decode.c | 2 + src/decode.h | 8 ++++ src/detect-engine-event.h | 4 ++ src/source-pcap-file.c | 3 ++ src/source-pcap.c | 3 ++ 10 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/decode-null.c create mode 100644 src/decode-null.h diff --git a/rules/decoder-events.rules b/rules/decoder-events.rules index d731dc8ddd..dc74a8160b 100644 --- a/rules/decoder-events.rules +++ b/rules/decoder-events.rules @@ -123,5 +123,10 @@ alert pkthdr any any -> any any (msg:"SURICATA MPLS bad implicit null label"; de alert pkthdr any any -> any any (msg:"SURICATA MPLS reserved label"; decode-event:mpls.bad_label_reserved; sid: 2200100; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA MPLS unknown payload type"; decode-event:mpls.unknown_payload_type; sid: 2200101; rev:1;) -# next sid is 2200103 +# linktype null +alert pkthdr any any -> any any (msg:"SURICATA NULL pkt too small"; decode-event:ltnull.pkt_too_small; sid: 2200103; rev:1;) +# packet has type not supported by Suricata's decoders +alert pkthdr any any -> any any (msg:"SURICATA NULL unsupported type"; decode-event:ltnull.unsupported_type; sid: 2200104; rev:1;) + +# next sid is 2200105 diff --git a/src/Makefile.am b/src/Makefile.am index 01c94375b4..d802d21174 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,7 @@ decode-icmpv4.c decode-icmpv4.h \ decode-icmpv6.c decode-icmpv6.h \ decode-ipv4.c decode-ipv4.h \ decode-ipv6.c decode-ipv6.h \ +decode-null.c decode-null.h \ decode-ppp.c decode-ppp.h \ decode-pppoe.c decode-pppoe.h \ decode-raw.c decode-raw.h \ diff --git a/src/decode-events.h b/src/decode-events.h index d9cceb1648..7ad23d9f72 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -146,6 +146,10 @@ enum { /* RAW EVENTS */ IPRAW_INVALID_IPV, /**< invalid ip version in ip raw */ + /* LINKTYPE NULL EVENTS */ + LTNULL_PKT_TOO_SMALL, /**< pkt too small for lt:null */ + LTNULL_UNSUPPORTED_TYPE, /**< pkt has a type that the decoder doesn't support */ + /* STREAM EVENTS */ STREAM_3WHS_ACK_IN_WRONG_DIR, STREAM_3WHS_ASYNC_WRONG_SEQ, diff --git a/src/decode-null.c b/src/decode-null.c new file mode 100644 index 0000000000..8bb76ca79b --- /dev/null +++ b/src/decode-null.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2015 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \ingroup decode + * + * @{ + */ + + +/** + * \file + * + * \author Victor Julien + * + * Decode linkype null: + * http://www.tcpdump.org/linktypes.html + */ + +#include "suricata-common.h" +#include "decode.h" +#include "decode-raw.h" +#include "decode-events.h" + +#include "util-unittest.h" +#include "util-debug.h" + +#include "pkt-var.h" +#include "util-profiling.h" +#include "host.h" + +#define HDR_SIZE 4 + +int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) +{ + SCPerfCounterIncr(dtv->counter_null, tv->sc_perf_pca); + + if (unlikely(len < HDR_SIZE)) { + ENGINE_SET_INVALID_EVENT(p, LTNULL_PKT_TOO_SMALL); + return TM_ECODE_FAILED; + } + + uint32_t type = *((uint32_t *)pkt); + switch(type) { + case AF_INET: + SCLogDebug("IPV4 Packet"); + DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p)+HDR_SIZE, GET_PKT_LEN(p)-HDR_SIZE, pq); + break; + case AF_INET6: + SCLogDebug("IPV6 Packet"); + DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p)+HDR_SIZE, GET_PKT_LEN(p)-HDR_SIZE, pq); + break; + default: + SCLogDebug("Unknown Null packet type version %" PRIu32 "", type); + ENGINE_SET_EVENT(p, LTNULL_UNSUPPORTED_TYPE); + break; + } + return TM_ECODE_OK; +} + +#ifdef UNITTESTS + +#endif /* UNITTESTS */ + +/** + * \brief Registers Null unit tests + */ +void DecodeNullRegisterTests(void) +{ +#ifdef UNITTESTS +#endif /* UNITTESTS */ +} +/** + * @} + */ diff --git a/src/decode-null.h b/src/decode-null.h new file mode 100644 index 0000000000..22d988c724 --- /dev/null +++ b/src/decode-null.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2007-2010 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \file + * + * \author Victor Julien + */ + +#ifndef __DECODE_NULL_H__ +#define __DECODE_NULL_H__ +void DecodeNullRegisterTests(void); +#endif /* __DECODE_NULL_H__ */ diff --git a/src/decode.c b/src/decode.c index c2c31cf14a..4d656691c5 100644 --- a/src/decode.c +++ b/src/decode.c @@ -384,6 +384,8 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_raw = SCPerfTVRegisterCounter("decoder.raw", tv, SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_null = SCPerfTVRegisterCounter("decoder.null", tv, + SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, SC_PERF_TYPE_UINT64, "NULL"); dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, diff --git a/src/decode.h b/src/decode.h index 0ea4c15f7a..11501cdffc 100644 --- a/src/decode.h +++ b/src/decode.h @@ -78,6 +78,7 @@ enum PktSrcEnum { #include "decode-udp.h" #include "decode-sctp.h" #include "decode-raw.h" +#include "decode-null.h" #include "decode-vlan.h" #include "decode-mpls.h" @@ -591,6 +592,7 @@ typedef struct DecodeThreadVars_ uint16_t counter_eth; uint16_t counter_sll; uint16_t counter_raw; + uint16_t counter_null; uint16_t counter_tcp; uint16_t counter_udp; uint16_t counter_sctp; @@ -854,6 +856,7 @@ int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, P int DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, uint8_t) __attribute__ ((warn_unused_result)); +int DecodeNull(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); @@ -962,8 +965,13 @@ void AddressDebugPrint(Address *); #endif #endif +#ifndef DLT_NULL +#define DLT_NULL 0 +#endif + /** libpcap shows us the way to linktype codes * \todo we need more & maybe put them in a separate file? */ +#define LINKTYPE_NULL DLT_NULL #define LINKTYPE_ETHERNET DLT_EN10MB #define LINKTYPE_LINUX_SLL 113 #define LINKTYPE_PPP 9 diff --git a/src/detect-engine-event.h b/src/detect-engine-event.h index 6270ca094b..5d51d6834d 100644 --- a/src/detect-engine-event.h +++ b/src/detect-engine-event.h @@ -155,6 +155,10 @@ struct DetectEngineEvents_ { /* RAW EVENTS */ { "ipraw.invalid_ip_version",IPRAW_INVALID_IPV, }, + /* LINKTYPE NULL EVENTS */ + { "ltnull.pkt_too_small", LTNULL_PKT_TOO_SMALL, }, + { "ltnull.unsupported_type", LTNULL_UNSUPPORTED_TYPE, }, + /* STREAM EVENTS */ { "stream.3whs_ack_in_wrong_dir", STREAM_3WHS_ACK_IN_WRONG_DIR, }, { "stream.3whs_async_wrong_seq", STREAM_3WHS_ASYNC_WRONG_SEQ, }, diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index f7dcb4c062..a9d55659e2 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -318,6 +318,9 @@ TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) case LINKTYPE_RAW: pcap_g.Decoder = DecodeRaw; break; + case LINKTYPE_NULL: + pcap_g.Decoder = DecodeNull; + break; default: SCLogError(SC_ERR_UNIMPLEMENTED, "datalink type %" PRId32 " not " diff --git a/src/source-pcap.c b/src/source-pcap.c index bf51ff91ea..634cc8117c 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -743,6 +743,9 @@ TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Packe case LINKTYPE_RAW: DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); break; + case LINKTYPE_NULL: + DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); + break; default: SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodePcap", p->datalink); break; -- 2.47.2