#include "util-unittest.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);
if (unlikely(len < ETHERNET_HEADER_LEN)) {
ENGINE_SET_EVENT(p,ETHERNET_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->ethh = (EthernetHdr *)pkt;
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));
pkt, ntohs(p->ethh->eth_type));
}
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#include "util-unittest.h"
#include "util-debug.h"
+#include "tmqh-packetpool.h"
+
/**
* \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;
GRESreHdr *gsre = NULL;
if(len < GRE_HDR_LEN) {
ENGINE_SET_EVENT(p,GRE_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->greh = (GREHdr *)pkt;
if(p->greh == NULL)
- return;
+ return TM_ECODE_FAILED;
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));
if (GRE_FLAG_ISSET_RECUR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION0_RECUR);
- return;
+ return TM_ECODE_OK;
}
if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION0_FLAGS);
- return;
+ return TM_ECODE_OK;
}
/* Adjust header length based on content */
if (header_len > len) {
ENGINE_SET_EVENT(p,GRE_VERSION0_HDR_TOO_BIG);
- return;
+ return TM_ECODE_OK;
}
if (GRE_FLAG_ISSET_ROUTE(p->greh))
{
if ((header_len + GRE_SRE_HDR_LEN) > len) {
ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR);
- return;
+ return TM_ECODE_OK;
}
gsre = (GRESreHdr *)(pkt + header_len);
header_len += gsre->sre_length;
if (header_len > len) {
ENGINE_SET_EVENT(p, GRE_VERSION0_MALFORMED_SRE_HDR);
- return;
+ return TM_ECODE_OK;
}
}
}
if (GRE_FLAG_ISSET_CHKSUM(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_CHKSUM);
- return;
+ return TM_ECODE_OK;
}
if (GRE_FLAG_ISSET_ROUTE(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_ROUTE);
- return;
+ return TM_ECODE_OK;
}
if (GRE_FLAG_ISSET_SSR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_SSR);
- return;
+ return TM_ECODE_OK;
}
if (GRE_FLAG_ISSET_RECUR(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_RECUR);
- return;
+ return TM_ECODE_OK;
}
if (GREV1_FLAG_ISSET_FLAGS(p->greh)) {
ENGINE_SET_EVENT(p,GRE_VERSION1_FLAGS);
- return;
+ return TM_ECODE_OK;
}
if (GRE_GET_PROTO(p->greh) != GRE_PROTO_PPP) {
ENGINE_SET_EVENT(p,GRE_VERSION1_WRONG_PROTOCOL);
- return;
+ return TM_ECODE_OK;
}
if (!(GRE_FLAG_ISSET_KY(p->greh))) {
ENGINE_SET_EVENT(p,GRE_VERSION1_NO_KEY);
- return;
+ return TM_ECODE_OK;
}
header_len += GRE_KEY_LEN;
if (header_len > len) {
ENGINE_SET_EVENT(p,GRE_VERSION1_HDR_TOO_BIG);
- return;
+ return TM_ECODE_OK;
}
break;
default:
ENGINE_SET_EVENT(p,GRE_WRONG_VERSION);
- return;
+ return TM_ECODE_OK;
}
switch (GRE_GET_PROTO(p->greh))
len - header_len, IPPROTO_IP);
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, IPPROTO_IP);
- PacketEnqueue(pq,tp);
+ if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, IPPROTO_IP) == TM_ECODE_OK) {
+ PacketEnqueue(pq,tp);
+ } else {
+ TmqhOutputPacketpool(tv, tp);
+ }
}
}
break;
len - header_len, PPP_OVER_GRE);
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, PPP_OVER_GRE);
- PacketEnqueue(pq,tp);
+ if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, PPP_OVER_GRE) == TM_ECODE_OK) {
+ PacketEnqueue(pq,tp);
+ } else {
+ TmqhOutputPacketpool(tv, tp);
+ }
}
}
break;
len - header_len, IPPROTO_IPV6);
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, IPPROTO_IPV6);
- PacketEnqueue(pq,tp);
+ if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, IPPROTO_IPV6) == TM_ECODE_OK) {
+ PacketEnqueue(pq,tp);
+ } else {
+ TmqhOutputPacketpool(tv, tp);
+ }
}
}
break;
len - header_len, VLAN_OVER_GRE);
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, VLAN_OVER_GRE);
- PacketEnqueue(pq,tp);
+ if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, VLAN_OVER_GRE) == TM_ECODE_OK) {
+ PacketEnqueue(pq,tp);
+ } else {
+ TmqhOutputPacketpool(tv, tp);
+ }
}
}
break;
}
default:
- return;
+ return TM_ECODE_OK;
}
-
+ return TM_ECODE_OK;
}
/** DecodeICMPV4
* \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);
if (len < ICMPV4_HEADER_LEN) {
ENGINE_SET_EVENT(p,ICMPV4_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->icmpv4h = (ICMPV4Hdr *)pkt;
}
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
*
* \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)
{
int full_hdr = 0;
if (len < ICMPV6_HEADER_LEN) {
SCLogDebug("ICMPV6_PKT_TOO_SMALL");
ENGINE_SET_EVENT(p, ICMPV6_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->icmpv6h = (ICMPV6Hdr *)pkt;
/* Flow is an integral part of us */
FlowHandlePacket(tv, p);
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#include "util-print.h"
#include "util-profiling.h"
+#include "tmqh-packetpool.h"
+
/* Generic validation
*
* [--type--][--len---]
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);
SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
SCLogDebug("decoding IPv4 packet failed");
p->ip4h = NULL;
- return;
+ return TM_ECODE_FAILED;
}
p->proto = IPV4_GET_IPPROTO(p);
Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) {
/* Got re-assembled packet, re-run through decoder. */
- DecodeIPV4(tv, dtv, rp, (void *)rp->ip4h, IPV4_GET_IPLEN(rp), pq);
- PacketEnqueue(pq, rp);
+ ret = DecodeIPV4(tv, dtv, rp, (void *)rp->ip4h, IPV4_GET_IPLEN(rp), pq);
+ if (unlikely(ret != TM_ECODE_OK)) {
+ TmqhOutputPacketpool(tv, rp);
+ } else {
+ PacketEnqueue(pq, rp);
+ }
}
p->flags |= PKT_IS_FRAGMENT;
- return;
+ return TM_ECODE_OK;
}
/* do hdr test, process hdr rules */
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4);
/* 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));
- /* add the tp to the packet queue. */
- PacketEnqueue(pq,tp);
+ if (unlikely(ret != TM_ECODE_OK)) {
+ TmqhOutputPacketpool(tv, tp);
+ } else {
+ /* add the tp to the packet queue. */
+ PacketEnqueue(pq,tp);
+ }
}
}
break;
break;
}
- return;
+ return TM_ECODE_OK;
}
/* UNITTESTS */
#include "util-profiling.h"
#include "host.h"
+#include "tmqh-packetpool.h"
+
#define IPV6_EXTHDRS ip6eh.ip6_exthdrs
#define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt
if (pq != NULL) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IP);
if (tp != NULL) {
+ int ret;
+
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, IPPROTO_IP);
- PacketEnqueue(pq,tp);
- SCPerfCounterIncr(dtv->counter_ipv4inipv6, tv->sc_perf_pca);
+ ret = DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, IPPROTO_IP);
+ if (unlikely(ret != TM_ECODE_OK)) {
+ TmqhOutputPacketpool(tv, tp);
+ } else {
+ /* add the tp to the packet queue. */
+ PacketEnqueue(pq,tp);
+ SCPerfCounterIncr(dtv->counter_ipv4inipv6, tv->sc_perf_pca);
+ }
return;
}
}
}
/**
- * \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)) {
ENGINE_SET_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
if (IP_GET_RAW_VER(pkt) == 6) {
if (unlikely(pq != NULL)) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6);
if (unlikely(tp != NULL)) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
- DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
- GET_PKT_LEN(tp), pq, IPPROTO_IPV6);
- PacketEnqueue(pq,tp);
- SCPerfCounterIncr(dtv->counter_ipv6inipv6, tv->sc_perf_pca);
- return;
+ if (DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
+ GET_PKT_LEN(tp), pq, IPPROTO_IPV6) == TM_ECODE_OK) {
+ PacketEnqueue(pq,tp);
+ SCPerfCounterIncr(dtv->counter_ipv6inipv6, tv->sc_perf_pca);
+ } else {
+ TmqhOutputPacketpool(tv, tp);
+ }
}
}
} else {
ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER);
}
- return;
+ return TM_ECODE_OK;
}
static void
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;
ret = DecodeIPV6Packet (tv, dtv, p, pkt, len);
if (unlikely(ret < 0)) {
p->ip6h = NULL;
- return;
+ return TM_ECODE_FAILED;
}
#ifdef DEBUG
case IPPROTO_TCP:
IPV6_SET_L4PROTO (p, IPPROTO_TCP);
DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
+ return TM_ECODE_OK;
case IPPROTO_UDP:
IPV6_SET_L4PROTO (p, IPPROTO_UDP);
DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
- break;
+ return TM_ECODE_OK;
case IPPROTO_ICMPV6:
IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6);
DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
+ return TM_ECODE_OK;
case IPPROTO_SCTP:
IPV6_SET_L4PROTO (p, IPPROTO_SCTP);
DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
+ return TM_ECODE_OK;
case IPPROTO_IPIP:
IPV6_SET_L4PROTO(p, IPPROTO_IPIP);
DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
+ return TM_ECODE_OK;
case IPPROTO_IPV6:
DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
- return;
+ return TM_ECODE_OK;
case IPPROTO_FRAGMENT:
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
if (IPV6_EXTHDR_ISSET_FH(p)) {
Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) {
- DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq);
- PacketEnqueue(pq, rp);
-
- /* Not really a tunnel packet, but we're piggybacking that
- * functionality for now. */
- SET_TUNNEL_PKT(p);
+ ret = DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq);
+ if (unlikely(ret != TM_ECODE_OK)) {
+ TmqhOutputPacketpool(tv, rp);
+ } else {
+ /* add the tp to the packet queue. */
+ PacketEnqueue(pq,rp);
+ /* Not really a tunnel packet, but we're piggybacking that
+ * functionality for now. */
+ SET_TUNNEL_PKT(p);
+ }
}
}
IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p));
}
#endif
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#include "util-unittest.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);
if (unlikely(len < PPP_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPP_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->ppph = (PPPHdr *)pkt;
if (unlikely(p->ppph == NULL))
- return;
+ return TM_ECODE_FAILED;
SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "",
p, pkt, ntohs(p->ppph->protocol), len);
case PPP_VJ_UCOMP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
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)) {
- 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;
case PPP_IP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
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);
- break;
+ return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
/* PPP IPv6 was not tested */
case PPP_IPV6:
if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
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);
- break;
+ return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
case PPP_VJ_COMP:
case PPP_IPX:
case PPP_LQM:
case PPP_CHAP:
ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO);
- break;
+ return TM_ECODE_OK;
default:
SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
ENGINE_SET_EVENT(p,PPP_WRONG_TYPE);
- return;
+ return TM_ECODE_OK;
}
- return;
}
/* TESTS BELOW */
/**
* \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);
if (len < PPPOE_DISCOVERY_HEADER_MIN_LEN) {
ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->pppoedh = (PPPOEDiscoveryHdr *)pkt;
if (p->pppoedh == NULL)
- return;
+ return TM_ECODE_FAILED;
/* parse the PPPOE code */
switch (p->pppoedh->pppoe_code)
default:
SCLogDebug("unknown PPPOE code: 0x%0"PRIX8"", p->pppoedh->pppoe_code);
ENGINE_SET_EVENT(p,PPPOE_WRONG_CODE);
- return;
+ return TM_ECODE_OK;
}
/* parse any tags we have in the packet */
if (pppoe_length > packet_length) {
SCLogDebug("malformed PPPOE 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)
pppoedt = pppoedt + (4 + tag_length);
}
- return;
+ return TM_ECODE_OK;
}
/**
* \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);
if (len < PPPOE_SESSION_HEADER_LEN) {
ENGINE_SET_EVENT(p, PPPOE_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
p->pppoesh = (PPPOESessionHdr *)pkt;
if (p->pppoesh == NULL)
- return;
+ return TM_ECODE_FAILED;
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));
if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) {
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) {
case PPP_IP:
if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) {
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 );
case PPP_IPV6:
if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN)) {
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 );
default:
SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
ENGINE_SET_EVENT(p,PPP_WRONG_TYPE);
- return;
+ return TM_ECODE_OK;
}
}
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#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);
/* If it is ipv4 or ipv6 it should at least be the size of ipv4 */
if (unlikely(len < IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,IPV4_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
if (IP_GET_RAW_VER(pkt) == 4) {
SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt));
ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV);
}
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
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);
if (unlikely(DecodeSCTPPacket(tv, p,pkt,len) < 0)) {
p->sctph = NULL;
- return;
+ return TM_ECODE_FAILED;
}
#ifdef DEBUG
/* Flow is an integral part of us */
FlowHandlePacket(tv, p);
- return;
+ return TM_ECODE_OK;
}
/**
* @}
#include "decode-events.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);
if (unlikely(len < SLL_HEADER_LEN)) {
ENGINE_SET_EVENT(p,SLL_PKT_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
SllHdr *sllh = (SllHdr *)pkt;
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 type %04x not supported", p,
pkt, ntohs(sllh->sll_protocol));
}
+
+ return TM_ECODE_OK;
}
/**
* @}
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);
if (unlikely(DecodeTCPPacket(tv, p,pkt,len) < 0)) {
SCLogDebug("invalid TCP packet");
p->tcph = NULL;
- return;
+ return TM_ECODE_FAILED;
}
#ifdef DEBUG
/* Flow is an integral part of us */
FlowHandlePacket(tv, p);
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#include "decode-ipv6.h"
#include "util-debug.h"
+#include "tmqh-packetpool.h"
+
#define TEREDO_ORIG_INDICATION_LENGTH 8
/**
* \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)
{
uint8_t *start = pkt;
+ int ret;
/* Is this packet to short to contain an IPv6 packet ? */
if (len < IPV6_HEADER_LEN)
- return 0;
+ return TM_ECODE_FAILED;
/* Teredo encapsulate IPv6 in UDP and can add some custom message
* part before the IPv6 packet. In our case, we just want to get
if (len >= TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN)
start += TEREDO_ORIG_INDICATION_LENGTH;
else
- return 0;
+ return TM_ECODE_FAILED;
break;
/* authentication: negotiation not real tunnel */
case 0x1:
- return 0;
+ return TM_ECODE_FAILED;
/* this case is not possible in Teredo: not that protocol */
default:
- return 0;
+ return TM_ECODE_FAILED;
}
}
if (tp != NULL) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_TEREDO);
/* 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);
- /* add the tp to the packet queue. */
- PacketEnqueue(pq,tp);
- SCPerfCounterIncr(dtv->counter_teredo, tv->sc_perf_pca);
- return 1;
+ if (unlikely(ret != TM_ECODE_OK)) {
+ TmqhOutputPacketpool(tv, tp);
+ return TM_ECODE_FAILED;
+ } 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;
}
/**
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);
if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) {
p->udph = NULL;
- return;
+ return TM_ECODE_FAILED;
}
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);
- 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
* layer */
FlowHandlePacket(tv, p);
- return;
+ return TM_ECODE_OK;
}
/* Flow is an integral part of us */
AppLayerHandleUdp(&dtv->udp_dp_ctx, p->flow, p);
}
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
* \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;
if(len < VLAN_HEADER_LEN) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_SMALL);
- return;
+ return TM_ECODE_FAILED;
}
if (p->vlan_idx >= 2) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
- return;
+ return TM_ECODE_FAILED;
}
p->vlanh[p->vlan_idx] = (VLANHdr *)pkt;
if(p->vlanh[p->vlan_idx] == NULL)
- return;
+ return TM_ECODE_FAILED;
proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]);
case ETHERNET_TYPE_VLAN:
if (p->vlan_idx >= 2) {
ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS);
- return;
+ return TM_ECODE_OK;
} else {
DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN,
len - VLAN_HEADER_LEN, pq);
default:
SCLogDebug("unknown VLAN type: %" PRIx32 "", proto);
ENGINE_SET_EVENT(p,VLAN_UNKNOWN_TYPE);
- return;
+ return TM_ECODE_OK;
}
- return;
+ return TM_ECODE_OK;
}
#ifdef UNITTESTS
#include "util-profiling.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)
{
switch (proto) {
case PPP_OVER_GRE:
- DecodePPP(tv, dtv, p, pkt, len, pq);
- return;
+ return DecodePPP(tv, dtv, p, pkt, len, pq);
case IPPROTO_IP:
- DecodeIPV4(tv, dtv, p, pkt, len, pq);
- return;
+ return DecodeIPV4(tv, dtv, p, pkt, len, pq);
case IPPROTO_IPV6:
- DecodeIPV6(tv, dtv, p, pkt, len, pq);
- return;
+ return DecodeIPV6(tv, dtv, p, pkt, len, pq);
case VLAN_OVER_GRE:
- DecodeVLAN(tv, dtv, p, pkt, len, pq);
- return;
+ return DecodeVLAN(tv, dtv, p, pkt, len, pq);
default:
SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto);
break;
}
+ return TM_ECODE_OK;
}
/**
DecodeThreadVars *DecodeThreadVarsAlloc();
/* decoder functions */
-void DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, uint8_t);
-void DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+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 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 *);
+int DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
void AddressDebugPrint(Address *);
typedef struct PcapFileGlobalVars_ {
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;
struct bpf_program filter;
uint64_t cnt; /** packet counter */