decode: update API to return error

In some cases, the decoding is not possible and some really invalid
packet can be created. This is in particular the case of tunnel. In
that case, it is more interesting to forget about the tunneled
packet and only consider the original packet.

DecodeTunnel function is maked as warn_unused_result because it is
meaningful for the decoder to know if the underlying data were not
correct. And in this case, only focus detection on the content.
pull/666/head
Eric Leblond 12 years ago
parent 0b0e9340dc
commit d4b7ecfbe3

@ -38,18 +38,18 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-debug.h" #include "util-debug.h"
void DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_eth, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_eth, tv->sc_perf_pca);
if (unlikely(len < ETHERNET_HEADER_LEN)) { if (unlikely(len < ETHERNET_HEADER_LEN)) {
ENGINE_SET_EVENT(p,ETHERNET_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,ETHERNET_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->ethh = (EthernetHdr *)pkt; p->ethh = (EthernetHdr *)pkt;
if (unlikely(p->ethh == NULL)) if (unlikely(p->ethh == NULL))
return; return TM_ECODE_FAILED;
SCLogDebug("p %p pkt %p ether type %04x", p, pkt, ntohs(p->ethh->eth_type)); SCLogDebug("p %p pkt %p ether type %04x", p, pkt, ntohs(p->ethh->eth_type));
@ -83,7 +83,7 @@ void DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *p
pkt, ntohs(p->ethh->eth_type)); pkt, ntohs(p->ethh->eth_type));
} }
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -39,11 +39,13 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-debug.h" #include "util-debug.h"
#include "tmqh-packetpool.h"
/** /**
* \brief Function to decode GRE packets * \brief Function to decode GRE packets
*/ */
void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
uint16_t header_len = GRE_HDR_LEN; uint16_t header_len = GRE_HDR_LEN;
GRESreHdr *gsre = NULL; GRESreHdr *gsre = NULL;
@ -52,12 +54,12 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
if(len < GRE_HDR_LEN) { if(len < GRE_HDR_LEN) {
ENGINE_SET_EVENT(p,GRE_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,GRE_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->greh = (GREHdr *)pkt; p->greh = (GREHdr *)pkt;
if(p->greh == NULL) if(p->greh == NULL)
return; return TM_ECODE_FAILED;
SCLogDebug("p %p pkt %p GRE protocol %04x Len: %d GRE version %x", SCLogDebug("p %p pkt %p GRE protocol %04x Len: %d GRE version %x",
p, pkt, GRE_GET_PROTO(p->greh), len,GRE_GET_VERSION(p->greh)); p, pkt, GRE_GET_PROTO(p->greh), len,GRE_GET_VERSION(p->greh));
@ -77,12 +79,12 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
if (GRE_FLAG_ISSET_RECUR(p->greh)) { if (GRE_FLAG_ISSET_RECUR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION0_RECUR); ENGINE_SET_EVENT(p,GRE_VERSION0_RECUR);
return; return TM_ECODE_OK;
} }
if (GREV1_FLAG_ISSET_FLAGS(p->greh)) { if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION0_FLAGS); ENGINE_SET_EVENT(p,GRE_VERSION0_FLAGS);
return; return TM_ECODE_OK;
} }
/* Adjust header length based on content */ /* Adjust header length based on content */
@ -98,7 +100,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
if (header_len > len) { if (header_len > len) {
ENGINE_SET_EVENT(p,GRE_VERSION0_HDR_TOO_BIG); ENGINE_SET_EVENT(p,GRE_VERSION0_HDR_TOO_BIG);
return; return TM_ECODE_OK;
} }
if (GRE_FLAG_ISSET_ROUTE(p->greh)) if (GRE_FLAG_ISSET_ROUTE(p->greh))
@ -107,7 +109,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{ {
if ((header_len + GRE_SRE_HDR_LEN) > len) { if ((header_len + GRE_SRE_HDR_LEN) > len) {
ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR); ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR);
return; return TM_ECODE_OK;
} }
gsre = (GRESreHdr *)(pkt + header_len); gsre = (GRESreHdr *)(pkt + header_len);
@ -120,7 +122,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
header_len += gsre->sre_length; header_len += gsre->sre_length;
if (header_len > len) { if (header_len > len) {
ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR); ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR);
return; return TM_ECODE_OK;
} }
} }
} }
@ -139,37 +141,37 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
if (GRE_FLAG_ISSET_CHKSUM(p->greh)) { if (GRE_FLAG_ISSET_CHKSUM(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_CHKSUM); ENGINE_SET_EVENT(p,GRE_VERSION1_CHKSUM);
return; return TM_ECODE_OK;
} }
if (GRE_FLAG_ISSET_ROUTE(p->greh)) { if (GRE_FLAG_ISSET_ROUTE(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_ROUTE); ENGINE_SET_EVENT(p,GRE_VERSION1_ROUTE);
return; return TM_ECODE_OK;
} }
if (GRE_FLAG_ISSET_SSR(p->greh)) { if (GRE_FLAG_ISSET_SSR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_SSR); ENGINE_SET_EVENT(p,GRE_VERSION1_SSR);
return; return TM_ECODE_OK;
} }
if (GRE_FLAG_ISSET_RECUR(p->greh)) { if (GRE_FLAG_ISSET_RECUR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_RECUR); ENGINE_SET_EVENT(p,GRE_VERSION1_RECUR);
return; return TM_ECODE_OK;
} }
if (GREV1_FLAG_ISSET_FLAGS(p->greh)) { if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_FLAGS); ENGINE_SET_EVENT(p,GRE_VERSION1_FLAGS);
return; return TM_ECODE_OK;
} }
if (GRE_GET_PROTO(p->greh) != GRE_PROTO_PPP) { if (GRE_GET_PROTO(p->greh) != GRE_PROTO_PPP) {
ENGINE_SET_EVENT(p,GRE_VERSION1_WRONG_PROTOCOL); ENGINE_SET_EVENT(p,GRE_VERSION1_WRONG_PROTOCOL);
return; return TM_ECODE_OK;
} }
if (!(GRE_FLAG_ISSET_KY(p->greh))) { if (!(GRE_FLAG_ISSET_KY(p->greh))) {
ENGINE_SET_EVENT(p,GRE_VERSION1_NO_KEY); ENGINE_SET_EVENT(p,GRE_VERSION1_NO_KEY);
return; return TM_ECODE_OK;
} }
header_len += GRE_KEY_LEN; header_len += GRE_KEY_LEN;
@ -184,13 +186,13 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
if (header_len > len) { if (header_len > len) {
ENGINE_SET_EVENT(p,GRE_VERSION1_HDR_TOO_BIG); ENGINE_SET_EVENT(p,GRE_VERSION1_HDR_TOO_BIG);
return; return TM_ECODE_OK;
} }
break; break;
default: default:
ENGINE_SET_EVENT(p,GRE_WRONG_VERSION); ENGINE_SET_EVENT(p,GRE_WRONG_VERSION);
return; return TM_ECODE_OK;
} }
switch (GRE_GET_PROTO(p->greh)) switch (GRE_GET_PROTO(p->greh))
@ -202,9 +204,12 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
len - header_len, IPPROTO_IP); len - header_len, IPPROTO_IP);
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPPROTO_IP); GET_PKT_LEN(tp), pq, IPPROTO_IP) == TM_ECODE_OK) {
PacketEnqueue(pq,tp); PacketEnqueue(pq,tp);
} else {
TmqhOutputPacketpool(tv, tp);
}
} }
} }
break; break;
@ -217,9 +222,12 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
len - header_len, PPP_OVER_GRE); len - header_len, PPP_OVER_GRE);
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, PPP_OVER_GRE); GET_PKT_LEN(tp), pq, PPP_OVER_GRE) == TM_ECODE_OK) {
PacketEnqueue(pq,tp); PacketEnqueue(pq,tp);
} else {
TmqhOutputPacketpool(tv, tp);
}
} }
} }
break; break;
@ -232,9 +240,12 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
len - header_len, IPPROTO_IPV6); len - header_len, IPPROTO_IPV6);
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPPROTO_IPV6); GET_PKT_LEN(tp), pq, IPPROTO_IPV6) == TM_ECODE_OK) {
PacketEnqueue(pq,tp); PacketEnqueue(pq,tp);
} else {
TmqhOutputPacketpool(tv, tp);
}
} }
} }
break; break;
@ -247,18 +258,21 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
len - header_len, VLAN_OVER_GRE); len - header_len, VLAN_OVER_GRE);
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, VLAN_OVER_GRE); GET_PKT_LEN(tp), pq, VLAN_OVER_GRE) == TM_ECODE_OK) {
PacketEnqueue(pq,tp); PacketEnqueue(pq,tp);
} else {
TmqhOutputPacketpool(tv, tp);
}
} }
} }
break; break;
} }
default: default:
return; return TM_ECODE_OK;
} }
return TM_ECODE_OK;
} }

@ -151,13 +151,13 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len )
/** DecodeICMPV4 /** DecodeICMPV4
* \brief Main ICMPv4 decoding function * \brief Main ICMPv4 decoding function
*/ */
void DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_icmpv4, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_icmpv4, tv->sc_perf_pca);
if (len < ICMPV4_HEADER_LEN) { if (len < ICMPV4_HEADER_LEN) {
ENGINE_SET_EVENT(p,ICMPV4_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,ICMPV4_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->icmpv4h = (ICMPV4Hdr *)pkt; p->icmpv4h = (ICMPV4Hdr *)pkt;
@ -301,7 +301,7 @@ void DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
} }
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -164,7 +164,7 @@ void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
* *
* \retval void No return value * \retval void No return value
*/ */
void DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
uint8_t *pkt, uint16_t len, PacketQueue *pq) uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
int full_hdr = 0; int full_hdr = 0;
@ -173,7 +173,7 @@ void DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
if (len < ICMPV6_HEADER_LEN) { if (len < ICMPV6_HEADER_LEN) {
SCLogDebug("ICMPV6_PKT_TOO_SMALL"); SCLogDebug("ICMPV6_PKT_TOO_SMALL");
ENGINE_SET_EVENT(p, ICMPV6_PKT_TOO_SMALL); ENGINE_SET_EVENT(p, ICMPV6_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->icmpv6h = (ICMPV6Hdr *)pkt; p->icmpv6h = (ICMPV6Hdr *)pkt;
@ -291,7 +291,7 @@ void DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
/* Flow is an integral part of us */ /* Flow is an integral part of us */
FlowHandlePacket(tv, p); FlowHandlePacket(tv, p);
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -46,6 +46,8 @@
#include "util-print.h" #include "util-print.h"
#include "util-profiling.h" #include "util-profiling.h"
#include "tmqh-packetpool.h"
/* Generic validation /* Generic validation
* *
* [--type--][--len---] * [--type--][--len---]
@ -513,8 +515,10 @@ static int DecodeIPV4Packet(Packet *p, uint8_t *pkt, uint16_t len)
return 0; return 0;
} }
void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
int ret;
SCPerfCounterIncr(dtv->counter_ipv4, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_ipv4, tv->sc_perf_pca);
SCLogDebug("pkt %p len %"PRIu16"", pkt, len); SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
@ -523,7 +527,7 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) { if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
SCLogDebug("decoding IPv4 packet failed"); SCLogDebug("decoding IPv4 packet failed");
p->ip4h = NULL; p->ip4h = NULL;
return; return TM_ECODE_FAILED;
} }
p->proto = IPV4_GET_IPPROTO(p); p->proto = IPV4_GET_IPPROTO(p);
@ -532,11 +536,15 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
Packet *rp = Defrag(tv, dtv, p); Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) { if (rp != NULL) {
/* Got re-assembled packet, re-run through decoder. */ /* Got re-assembled packet, re-run through decoder. */
DecodeIPV4(tv, dtv, rp, (void *)rp->ip4h, IPV4_GET_IPLEN(rp), pq); ret = DecodeIPV4(tv, dtv, rp, (void *)rp->ip4h, IPV4_GET_IPLEN(rp), pq);
PacketEnqueue(pq, rp); if (unlikely(ret != TM_ECODE_OK)) {
TmqhOutputPacketpool(tv, rp);
} else {
PacketEnqueue(pq, rp);
}
} }
p->flags |= PKT_IS_FRAGMENT; p->flags |= PKT_IS_FRAGMENT;
return; return TM_ECODE_OK;
} }
/* do hdr test, process hdr rules */ /* do hdr test, process hdr rules */
@ -585,11 +593,15 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4); PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4);
/* send that to the Tunnel decoder */ /* send that to the Tunnel decoder */
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), ret = DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPV4_GET_IPPROTO(p)); GET_PKT_LEN(tp), pq, IPV4_GET_IPPROTO(p));
/* add the tp to the packet queue. */ if (unlikely(ret != TM_ECODE_OK)) {
PacketEnqueue(pq,tp); TmqhOutputPacketpool(tv, tp);
} else {
/* add the tp to the packet queue. */
PacketEnqueue(pq,tp);
}
} }
} }
break; break;
@ -603,7 +615,7 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
break; break;
} }
return; return TM_ECODE_OK;
} }
/* UNITTESTS */ /* UNITTESTS */

@ -44,6 +44,8 @@
#include "util-profiling.h" #include "util-profiling.h"
#include "host.h" #include "host.h"
#include "tmqh-packetpool.h"
#define IPV6_EXTHDRS ip6eh.ip6_exthdrs #define IPV6_EXTHDRS ip6eh.ip6_exthdrs
#define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt #define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt
@ -62,11 +64,18 @@ static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, u
if (pq != NULL) { if (pq != NULL) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IP); Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IP);
if (tp != NULL) { if (tp != NULL) {
int ret;
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6); PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), ret = DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPPROTO_IP); GET_PKT_LEN(tp), pq, IPPROTO_IP);
PacketEnqueue(pq,tp); if (unlikely(ret != TM_ECODE_OK)) {
SCPerfCounterIncr(dtv->counter_ipv4inipv6, tv->sc_perf_pca); TmqhOutputPacketpool(tv, tp);
} else {
/* add the tp to the packet queue. */
PacketEnqueue(pq,tp);
SCPerfCounterIncr(dtv->counter_ipv4inipv6, tv->sc_perf_pca);
}
return; return;
} }
} }
@ -77,32 +86,34 @@ static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, u
} }
/** /**
* \brief Function to decode IPv4 in IPv6 packets * \brief Function to decode IPv6 in IPv6 packets
* *
*/ */
static void DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq) static int DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq)
{ {
if (unlikely(plen < IPV6_HEADER_LEN)) { if (unlikely(plen < IPV6_HEADER_LEN)) {
ENGINE_SET_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL); ENGINE_SET_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
if (IP_GET_RAW_VER(pkt) == 6) { if (IP_GET_RAW_VER(pkt) == 6) {
if (unlikely(pq != NULL)) { if (unlikely(pq != NULL)) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6); Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6);
if (unlikely(tp != NULL)) { if (unlikely(tp != NULL)) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6); PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPPROTO_IPV6); GET_PKT_LEN(tp), pq, IPPROTO_IPV6) == TM_ECODE_OK) {
PacketEnqueue(pq,tp); PacketEnqueue(pq,tp);
SCPerfCounterIncr(dtv->counter_ipv6inipv6, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_ipv6inipv6, tv->sc_perf_pca);
return; } else {
TmqhOutputPacketpool(tv, tp);
}
} }
} }
} else { } else {
ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER); ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER);
} }
return; return TM_ECODE_OK;
} }
static void static void
@ -528,7 +539,7 @@ static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, u
return 0; return 0;
} }
void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
int ret; int ret;
@ -538,7 +549,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); ret = DecodeIPV6Packet (tv, dtv, p, pkt, len);
if (unlikely(ret < 0)) { if (unlikely(ret < 0)) {
p->ip6h = NULL; p->ip6h = NULL;
return; return TM_ECODE_FAILED;
} }
#ifdef DEBUG #ifdef DEBUG
@ -558,27 +569,26 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
case IPPROTO_TCP: case IPPROTO_TCP:
IPV6_SET_L4PROTO (p, IPPROTO_TCP); IPV6_SET_L4PROTO (p, IPPROTO_TCP);
DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
case IPPROTO_UDP: case IPPROTO_UDP:
IPV6_SET_L4PROTO (p, IPPROTO_UDP); IPV6_SET_L4PROTO (p, IPPROTO_UDP);
DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
break;
case IPPROTO_ICMPV6: case IPPROTO_ICMPV6:
IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6); IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6);
DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
case IPPROTO_SCTP: case IPPROTO_SCTP:
IPV6_SET_L4PROTO (p, IPPROTO_SCTP); IPV6_SET_L4PROTO (p, IPPROTO_SCTP);
DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
case IPPROTO_IPIP: case IPPROTO_IPIP:
IPV6_SET_L4PROTO(p, IPPROTO_IPIP); IPV6_SET_L4PROTO(p, IPPROTO_IPIP);
DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
case IPPROTO_IPV6: case IPPROTO_IPV6:
DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
return; return TM_ECODE_OK;
case IPPROTO_FRAGMENT: case IPPROTO_FRAGMENT:
case IPPROTO_HOPOPTS: case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING: case IPPROTO_ROUTING:
@ -601,12 +611,16 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if (IPV6_EXTHDR_ISSET_FH(p)) { if (IPV6_EXTHDR_ISSET_FH(p)) {
Packet *rp = Defrag(tv, dtv, p); Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) { if (rp != NULL) {
DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq); ret = DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq);
PacketEnqueue(pq, rp); if (unlikely(ret != TM_ECODE_OK)) {
TmqhOutputPacketpool(tv, rp);
/* Not really a tunnel packet, but we're piggybacking that } else {
* functionality for now. */ /* add the tp to the packet queue. */
SET_TUNNEL_PKT(p); PacketEnqueue(pq,rp);
/* Not really a tunnel packet, but we're piggybacking that
* functionality for now. */
SET_TUNNEL_PKT(p);
}
} }
} }
@ -634,7 +648,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p)); IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p));
} }
#endif #endif
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -40,18 +40,18 @@
#include "util-unittest.h" #include "util-unittest.h"
#include "util-debug.h" #include "util-debug.h"
void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_ppp, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_ppp, tv->sc_perf_pca);
if (unlikely(len < PPP_HEADER_LEN)) { if (unlikely(len < PPP_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPP_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPP_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->ppph = (PPPHdr *)pkt; p->ppph = (PPPHdr *)pkt;
if (unlikely(p->ppph == NULL)) if (unlikely(p->ppph == NULL))
return; return TM_ECODE_FAILED;
SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "", SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "",
p, pkt, ntohs(p->ppph->protocol), len); p, pkt, ntohs(p->ppph->protocol), len);
@ -61,32 +61,34 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
case PPP_VJ_UCOMP: case PPP_VJ_UCOMP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) { if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL);
return; p->ppph = NULL;
return TM_ECODE_FAILED;
} }
if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) { if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
} } else
return TM_ECODE_FAILED;
break; break;
case PPP_IP: case PPP_IP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) { if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL);
return; p->ppph = NULL;
return TM_ECODE_FAILED;
} }
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
/* PPP IPv6 was not tested */ /* PPP IPv6 was not tested */
case PPP_IPV6: case PPP_IPV6:
if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) { if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL);
return; p->ppph = NULL;
return TM_ECODE_FAILED;
} }
DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
case PPP_VJ_COMP: case PPP_VJ_COMP:
case PPP_IPX: case PPP_IPX:
@ -117,15 +119,14 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
case PPP_LQM: case PPP_LQM:
case PPP_CHAP: case PPP_CHAP:
ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO); ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO);
break; return TM_ECODE_OK;
default: default:
SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol)); SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
ENGINE_SET_EVENT(p,PPP_WRONG_TYPE); ENGINE_SET_EVENT(p,PPP_WRONG_TYPE);
return; return TM_ECODE_OK;
} }
return;
} }
/* TESTS BELOW */ /* TESTS BELOW */

@ -47,18 +47,18 @@
/** /**
* \brief Main decoding function for PPPOE Discovery packets * \brief Main decoding function for PPPOE Discovery packets
*/ */
void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca);
if (len < PPPOE_DISCOVERY_HEADER_MIN_LEN) { if (len < PPPOE_DISCOVERY_HEADER_MIN_LEN) {
ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL); ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->pppoedh = (PPPOEDiscoveryHdr *)pkt; p->pppoedh = (PPPOEDiscoveryHdr *)pkt;
if (p->pppoedh == NULL) if (p->pppoedh == NULL)
return; return TM_ECODE_FAILED;
/* parse the PPPOE code */ /* parse the PPPOE code */
switch (p->pppoedh->pppoe_code) switch (p->pppoedh->pppoe_code)
@ -76,7 +76,7 @@ void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint
default: default:
SCLogDebug("unknown PPPOE code: 0x%0"PRIX8"", p->pppoedh->pppoe_code); SCLogDebug("unknown PPPOE code: 0x%0"PRIX8"", p->pppoedh->pppoe_code);
ENGINE_SET_EVENT(p,PPPOE_WRONG_CODE); ENGINE_SET_EVENT(p,PPPOE_WRONG_CODE);
return; return TM_ECODE_OK;
} }
/* parse any tags we have in the packet */ /* parse any tags we have in the packet */
@ -93,7 +93,7 @@ void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint
if (pppoe_length > packet_length) { if (pppoe_length > packet_length) {
SCLogDebug("malformed PPPOE tags"); SCLogDebug("malformed PPPOE tags");
ENGINE_SET_EVENT(p,PPPOE_MALFORMED_TAGS); ENGINE_SET_EVENT(p,PPPOE_MALFORMED_TAGS);
return; return TM_ECODE_OK;
} }
while (pppoedt < (PPPOEDiscoveryTag*) (pkt + (len - sizeof(PPPOEDiscoveryTag))) && pppoe_length >=4 && packet_length >=4) while (pppoedt < (PPPOEDiscoveryTag*) (pkt + (len - sizeof(PPPOEDiscoveryTag))) && pppoe_length >=4 && packet_length >=4)
@ -120,24 +120,24 @@ void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint
pppoedt = pppoedt + (4 + tag_length); pppoedt = pppoedt + (4 + tag_length);
} }
return; return TM_ECODE_OK;
} }
/** /**
* \brief Main decoding function for PPPOE Session packets * \brief Main decoding function for PPPOE Session packets
*/ */
void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca);
if (len < PPPOE_SESSION_HEADER_LEN) { if (len < PPPOE_SESSION_HEADER_LEN) {
ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL); ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
p->pppoesh = (PPPOESessionHdr *)pkt; p->pppoesh = (PPPOESessionHdr *)pkt;
if (p->pppoesh == NULL) if (p->pppoesh == NULL)
return; return TM_ECODE_FAILED;
SCLogDebug("PPPOE VERSION %" PRIu32 " TYPE %" PRIu32 " CODE %" PRIu32 " SESSIONID %" PRIu32 " LENGTH %" PRIu32 "", SCLogDebug("PPPOE VERSION %" PRIu32 " TYPE %" PRIu32 " CODE %" PRIu32 " SESSIONID %" PRIu32 " LENGTH %" PRIu32 "",
PPPOE_SESSION_GET_VERSION(p->pppoesh), PPPOE_SESSION_GET_TYPE(p->pppoesh), p->pppoesh->pppoe_code, ntohs(p->pppoesh->session_id), ntohs(p->pppoesh->pppoe_length)); PPPOE_SESSION_GET_VERSION(p->pppoesh), PPPOE_SESSION_GET_TYPE(p->pppoesh), p->pppoesh->pppoe_code, ntohs(p->pppoesh->session_id), ntohs(p->pppoesh->pppoe_length));
@ -184,7 +184,7 @@ void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_
if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL);
return; return TM_ECODE_OK;
} }
if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) { if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) {
@ -195,7 +195,7 @@ void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_
case PPP_IP: case PPP_IP:
if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL);
return; return TM_ECODE_OK;
} }
DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
@ -205,7 +205,7 @@ void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_
case PPP_IPV6: case PPP_IPV6:
if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN)) { if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL);
return; return TM_ECODE_OK;
} }
DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
@ -214,9 +214,10 @@ void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_
default: default:
SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol)); SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
ENGINE_SET_EVENT(p,PPP_WRONG_TYPE); ENGINE_SET_EVENT(p,PPP_WRONG_TYPE);
return; return TM_ECODE_OK;
} }
} }
return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -43,14 +43,14 @@
#include "host.h" #include "host.h"
void DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_raw, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_raw, tv->sc_perf_pca);
/* If it is ipv4 or ipv6 it should at least be the size of ipv4 */ /* If it is ipv4 or ipv6 it should at least be the size of ipv4 */
if (unlikely(len < IPV4_HEADER_LEN)) { if (unlikely(len < IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,IPV4_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,IPV4_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
if (IP_GET_RAW_VER(pkt) == 4) { if (IP_GET_RAW_VER(pkt) == 4) {
@ -63,7 +63,7 @@ void DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt)); SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt));
ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV); ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV);
} }
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -59,13 +59,13 @@ static int DecodeSCTPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t le
return 0; return 0;
} }
void DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_sctp, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_sctp, tv->sc_perf_pca);
if (unlikely(DecodeSCTPPacket(tv, p,pkt,len) < 0)) { if (unlikely(DecodeSCTPPacket(tv, p,pkt,len) < 0)) {
p->sctph = NULL; p->sctph = NULL;
return; return TM_ECODE_FAILED;
} }
#ifdef DEBUG #ifdef DEBUG
@ -76,7 +76,7 @@ void DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
/* Flow is an integral part of us */ /* Flow is an integral part of us */
FlowHandlePacket(tv, p); FlowHandlePacket(tv, p);
return; return TM_ECODE_OK;
} }
/** /**
* @} * @}

@ -36,18 +36,18 @@
#include "decode-events.h" #include "decode-events.h"
#include "util-debug.h" #include "util-debug.h"
void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_sll, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_sll, tv->sc_perf_pca);
if (unlikely(len < SLL_HEADER_LEN)) { if (unlikely(len < SLL_HEADER_LEN)) {
ENGINE_SET_EVENT(p,SLL_PKT_TOO_SMALL); ENGINE_SET_EVENT(p,SLL_PKT_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
SllHdr *sllh = (SllHdr *)pkt; SllHdr *sllh = (SllHdr *)pkt;
if (unlikely(sllh == NULL)) if (unlikely(sllh == NULL))
return; return TM_ECODE_FAILED;
SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol)); SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol));
@ -68,6 +68,8 @@ void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
SCLogDebug("p %p pkt %p sll type %04x not supported", p, SCLogDebug("p %p pkt %p sll type %04x not supported", p,
pkt, ntohs(sllh->sll_protocol)); pkt, ntohs(sllh->sll_protocol));
} }
return TM_ECODE_OK;
} }
/** /**
* @} * @}

@ -184,14 +184,14 @@ static int DecodeTCPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t len
return 0; return 0;
} }
void DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_tcp, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_tcp, tv->sc_perf_pca);
if (unlikely(DecodeTCPPacket(tv, p,pkt,len) < 0)) { if (unlikely(DecodeTCPPacket(tv, p,pkt,len) < 0)) {
SCLogDebug("invalid TCP packet"); SCLogDebug("invalid TCP packet");
p->tcph = NULL; p->tcph = NULL;
return; return TM_ECODE_FAILED;
} }
#ifdef DEBUG #ifdef DEBUG
@ -205,7 +205,7 @@ void DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
/* Flow is an integral part of us */ /* Flow is an integral part of us */
FlowHandlePacket(tv, p); FlowHandlePacket(tv, p);
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -37,21 +37,24 @@
#include "decode-ipv6.h" #include "decode-ipv6.h"
#include "util-debug.h" #include "util-debug.h"
#include "tmqh-packetpool.h"
#define TEREDO_ORIG_INDICATION_LENGTH 8 #define TEREDO_ORIG_INDICATION_LENGTH 8
/** /**
* \brief Function to decode Teredo packets * \brief Function to decode Teredo packets
* *
* \retval 0 if packet is not a Teredo packet, 1 if it is * \retval TM_ECODE_FAILED if packet is not a Teredo packet, TM_ECODE_OK if it is
*/ */
int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
uint8_t *start = pkt; uint8_t *start = pkt;
int ret;
/* Is this packet to short to contain an IPv6 packet ? */ /* Is this packet to short to contain an IPv6 packet ? */
if (len < IPV6_HEADER_LEN) if (len < IPV6_HEADER_LEN)
return 0; return TM_ECODE_FAILED;
/* Teredo encapsulate IPv6 in UDP and can add some custom message /* Teredo encapsulate IPv6 in UDP and can add some custom message
* part before the IPv6 packet. In our case, we just want to get * part before the IPv6 packet. In our case, we just want to get
@ -64,14 +67,14 @@ int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if (len >= TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN) if (len >= TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN)
start += TEREDO_ORIG_INDICATION_LENGTH; start += TEREDO_ORIG_INDICATION_LENGTH;
else else
return 0; return TM_ECODE_FAILED;
break; break;
/* authentication: negotiation not real tunnel */ /* authentication: negotiation not real tunnel */
case 0x1: case 0x1:
return 0; return TM_ECODE_FAILED;
/* this case is not possible in Teredo: not that protocol */ /* this case is not possible in Teredo: not that protocol */
default: default:
return 0; return TM_ECODE_FAILED;
} }
} }
@ -95,19 +98,24 @@ int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if (tp != NULL) { if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_TEREDO); PKT_SET_SRC(tp, PKT_SRC_DECODER_TEREDO);
/* send that to the Tunnel decoder */ /* send that to the Tunnel decoder */
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), GET_PKT_LEN(tp), ret = DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp), GET_PKT_LEN(tp),
pq, IPPROTO_IPV6); pq, IPPROTO_IPV6);
/* add the tp to the packet queue. */ if (unlikely(ret != TM_ECODE_OK)) {
PacketEnqueue(pq,tp); TmqhOutputPacketpool(tv, tp);
SCPerfCounterIncr(dtv->counter_teredo, tv->sc_perf_pca); return TM_ECODE_FAILED;
return 1; } else {
/* add the tp to the packet queue. */
PacketEnqueue(pq,tp);
SCPerfCounterIncr(dtv->counter_teredo, tv->sc_perf_pca);
return TM_ECODE_OK;
}
} }
} }
} }
return 0; return TM_ECODE_FAILED;
} }
return 0; return TM_ECODE_FAILED;
} }
/** /**

@ -70,23 +70,23 @@ static int DecodeUDPPacket(ThreadVars *t, Packet *p, uint8_t *pkt, uint16_t len)
return 0; return 0;
} }
void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
SCPerfCounterIncr(dtv->counter_udp, tv->sc_perf_pca); SCPerfCounterIncr(dtv->counter_udp, tv->sc_perf_pca);
if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) { if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) {
p->udph = NULL; p->udph = NULL;
return; return TM_ECODE_FAILED;
} }
SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "", SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "",
UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len); UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len);
if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == 1)) { if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) {
/* Here we have a Teredo packet and don't need to handle app /* Here we have a Teredo packet and don't need to handle app
* layer */ * layer */
FlowHandlePacket(tv, p); FlowHandlePacket(tv, p);
return; return TM_ECODE_OK;
} }
/* Flow is an integral part of us */ /* Flow is an integral part of us */
@ -97,7 +97,7 @@ void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
AppLayerHandleUdp(&dtv->udp_dp_ctx, p->flow, p); AppLayerHandleUdp(&dtv->udp_dp_ctx, p->flow, p);
} }
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -56,7 +56,7 @@
* \param pq pointer to the packet queue * \param pq pointer to the packet queue
* *
*/ */
void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
{ {
uint32_t proto; uint32_t proto;
@ -64,16 +64,16 @@ void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
if(len < VLAN_HEADER_LEN) { if(len < VLAN_HEADER_LEN) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_SMALL); ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_SMALL);
return; return TM_ECODE_FAILED;
} }
if (p->vlan_idx >= 2) { if (p->vlan_idx >= 2) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
return; return TM_ECODE_FAILED;
} }
p->vlanh[p->vlan_idx] = (VLANHdr *)pkt; p->vlanh[p->vlan_idx] = (VLANHdr *)pkt;
if(p->vlanh[p->vlan_idx] == NULL) if(p->vlanh[p->vlan_idx] == NULL)
return; return TM_ECODE_FAILED;
proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]); proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]);
@ -107,7 +107,7 @@ void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
case ETHERNET_TYPE_VLAN: case ETHERNET_TYPE_VLAN:
if (p->vlan_idx >= 2) { if (p->vlan_idx >= 2) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
return; return TM_ECODE_OK;
} else { } else {
DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN,
len - VLAN_HEADER_LEN, pq); len - VLAN_HEADER_LEN, pq);
@ -116,10 +116,10 @@ void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
default: default:
SCLogDebug("unknown VLAN type: %" PRIx32 "", proto); SCLogDebug("unknown VLAN type: %" PRIx32 "", proto);
ENGINE_SET_EVENT(p,VLAN_UNKNOWN_TYPE); ENGINE_SET_EVENT(p,VLAN_UNKNOWN_TYPE);
return; return TM_ECODE_OK;
} }
return; return TM_ECODE_OK;
} }
#ifdef UNITTESTS #ifdef UNITTESTS

@ -61,26 +61,23 @@
#include "util-profiling.h" #include "util-profiling.h"
#include "pkt-var.h" #include "pkt-var.h"
void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
uint8_t *pkt, uint16_t len, PacketQueue *pq, uint8_t proto) uint8_t *pkt, uint16_t len, PacketQueue *pq, uint8_t proto)
{ {
switch (proto) { switch (proto) {
case PPP_OVER_GRE: case PPP_OVER_GRE:
DecodePPP(tv, dtv, p, pkt, len, pq); return DecodePPP(tv, dtv, p, pkt, len, pq);
return;
case IPPROTO_IP: case IPPROTO_IP:
DecodeIPV4(tv, dtv, p, pkt, len, pq); return DecodeIPV4(tv, dtv, p, pkt, len, pq);
return;
case IPPROTO_IPV6: case IPPROTO_IPV6:
DecodeIPV6(tv, dtv, p, pkt, len, pq); return DecodeIPV6(tv, dtv, p, pkt, len, pq);
return;
case VLAN_OVER_GRE: case VLAN_OVER_GRE:
DecodeVLAN(tv, dtv, p, pkt, len, pq); return DecodeVLAN(tv, dtv, p, pkt, len, pq);
return;
default: default:
SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto); SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
break; break;
} }
return TM_ECODE_OK;
} }
/** /**

@ -826,22 +826,22 @@ const char *PktSrcToString(enum PktSrcEnum pkt_src);
DecodeThreadVars *DecodeThreadVarsAlloc(); DecodeThreadVars *DecodeThreadVarsAlloc();
/* decoder functions */ /* decoder functions */
void DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, uint8_t); int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, uint8_t) __attribute__ ((warn_unused_result));
void DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void AddressDebugPrint(Address *); void AddressDebugPrint(Address *);

@ -62,7 +62,7 @@ extern int max_pending_packets;
typedef struct PcapFileGlobalVars_ { typedef struct PcapFileGlobalVars_ {
pcap_t *pcap_handle; pcap_t *pcap_handle;
void (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); int (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *);
int datalink; int datalink;
struct bpf_program filter; struct bpf_program filter;
uint64_t cnt; /** packet counter */ uint64_t cnt; /** packet counter */

Loading…
Cancel
Save