/** * \test HOP header decode */ static int DecodeIPV6HopTest01 (void) { uint8_t raw_pkt1[] = { 0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0xff, /* 0xff is a nonsene opt */ 0x02,0x00,0x00,0x00,0x00, 0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; Packet *p1 = PacketGetFromAlloc(); FAIL_IF(unlikely(p1 == NULL)); ThreadVars tv; DecodeThreadVars dtv; PacketQueue pq; FlowInitConfig(FLOW_QUIET); memset(&pq, 0, sizeof(PacketQueue)); memset(&tv, 0, sizeof(ThreadVars)); memset(&dtv, 0, sizeof(DecodeThreadVars)); PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); FAIL_IF (!(ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT))); PACKET_RECYCLE(p1); SCFree(p1); FlowShutdown(); PASS; }
int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq) { StatsIncr(tv, dtv->counter_raw); /* If it is ipv4 or ipv6 it should at least be the size of ipv4 */ if (unlikely(len < IPV4_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, IPV4_PKT_TOO_SMALL); return TM_ECODE_FAILED; } if (IP_GET_RAW_VER(pkt) == 4) { if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) { return TM_ECODE_FAILED; } SCLogDebug("IPV4 Packet"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if (IP_GET_RAW_VER(pkt) == 6) { if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) { return TM_ECODE_FAILED; } SCLogDebug("IPV6 Packet"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt)); ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV); } return TM_ECODE_OK; }
/** * \brief Decode a packet coming from NFQ */ TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); DecodeThreadVars *dtv = (DecodeThreadVars *)data; /* XXX HACK: flow timeout can call us for injected pseudo packets * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ if (PKT_IS_PSEUDOPKT(p)) return TM_ECODE_OK; DecodeUpdatePacketCounters(tv, dtv, p); if (IPV4_GET_RAW_VER(ip4h) == 4) { SCLogDebug("IPv4 packet"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if(IPV6_GET_RAW_VER(ip6h) == 6) { SCLogDebug("IPv6 packet"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { SCLogDebug("packet unsupported by NFQ, first byte: %02x", *GET_PKT_DATA(p)); } PacketDecodeFinalize(tv, dtv, p); return TM_ECODE_OK; }
/** * \brief Decode a packet coming from NFQ */ TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); DecodeThreadVars *dtv = (DecodeThreadVars *)data; SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); #if 0 SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca, (GET_PKT_LEN(p) * 8)/1000000.0); #endif if (IPV4_GET_RAW_VER(ip4h) == 4) { SCLogDebug("IPv4 packet"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if(IPV6_GET_RAW_VER(ip6h) == 6) { SCLogDebug("IPv6 packet"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { SCLogDebug("packet unsupported by NFQ, first byte: %02x", *GET_PKT_DATA(p)); } return TM_ECODE_OK; }
/** * \brief This function passes off to link type decoders. * \todo Unit tests are needed for this module. * * DecodeIPFW reads packets from the PacketQueue and passes * them off to the proper link type decoder. * * \param tv pointer to ThreadVars * \param p pointer to the current packet * \param data pointer that gets cast into IPFWThreadVars for ptv * \param pq pointer to the PacketQueue */ TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); DecodeThreadVars *dtv = (DecodeThreadVars *)data; SCEnter(); /* update counters */ SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); /* Process IP packets */ if (IPV4_GET_RAW_VER(ip4h) == 4) { SCLogDebug("DecodeIPFW ip4 processing"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if(IPV6_GET_RAW_VER(ip6h) == 6) { SCLogDebug("DecodeIPFW ip6 processing"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { /* We don't support anything besides IP packets for now, bridged packets? */ SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p)); SCReturnInt(TM_ECODE_FAILED); } SCReturnInt(TM_ECODE_OK); }
/** * \brief This function passes off to link type decoders. * \todo Unit tests are needed for this module. * * DecodeIPFW reads packets from the PacketQueue and passes * them off to the proper link type decoder. * * \param tv pointer to ThreadVars * \param p pointer to the current packet * \param data pointer that gets cast into IPFWThreadVars for ptv * \param pq pointer to the PacketQueue */ TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); DecodeThreadVars *dtv = (DecodeThreadVars *)data; SCEnter(); /* XXX HACK: flow timeout can call us for injected pseudo packets * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ if (p->flags & PKT_PSEUDO_STREAM_END) return TM_ECODE_OK; /* update counters */ DecodeUpdatePacketCounters(tv, dtv, p); /* Process IP packets */ if (IPV4_GET_RAW_VER(ip4h) == 4) { SCLogDebug("DecodeIPFW ip4 processing"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if(IPV6_GET_RAW_VER(ip6h) == 6) { SCLogDebug("DecodeIPFW ip6 processing"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { /* We don't support anything besides IP packets for now, bridged packets? */ SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p)); SCReturnInt(TM_ECODE_FAILED); } PacketDecodeFinalize(tv, dtv, p); SCReturnInt(TM_ECODE_OK); }
void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { SCPerfCounterIncr(dtv->counter_sll, tv->sc_perf_pca); if (len < SLL_HEADER_LEN) { DECODER_SET_EVENT(p,SLL_PKT_TOO_SMALL); return; } SllHdr *sllh = (SllHdr *)pkt; if (sllh == NULL) return; SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol)); switch (ntohs(sllh->sll_protocol)) { case ETHERNET_TYPE_IP: DecodeIPV4(tv, dtv, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: DecodeIPV6(tv, dtv, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: DecodeVLAN(tv, dtv, p, pkt + SLL_HEADER_LEN, len - SLL_HEADER_LEN, pq); break; default: SCLogDebug("p %p pkt %p sll type %04x not supported", p, pkt, ntohs(sllh->sll_protocol)); } }
/** \test icmpv6 message type: parameter problem, invalid packet * \brief set the event ICMPV6_IPV6_UNKNOWN_VER properly when the embedded packet has an unknown version * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6ParamProbTest02(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf, 0x38, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (p->icmpv6h == NULL) { SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); retval = 0; goto end; } if (ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0) { SCLogDebug("ICMPv6 Not processed at all"); retval = 0; goto end; } if (!DECODER_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER)) { SCLogDebug("ICMPv6 Error: Unknown embedded ipv6 version event not set"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { StatsIncr(tv, dtv->counter_eth); if (unlikely(len < ETHERNET_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, ETHERNET_PKT_TOO_SMALL); return TM_ECODE_FAILED; } p->ethh = (EthernetHdr *)pkt; if (unlikely(p->ethh == NULL)) return TM_ECODE_FAILED; SCLogDebug("p %p pkt %p ether type %04x", p, pkt, ntohs(p->ethh->eth_type)); switch (ntohs(p->ethh->eth_type)) { case ETHERNET_TYPE_IP: //printf("DecodeEthernet ip4\n"); DecodeIPV4(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: //printf("DecodeEthernet ip6\n"); DecodeIPV6(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_SESS: //printf("DecodeEthernet PPPOE Session\n"); DecodePPPOESession(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_DISC: //printf("DecodeEthernet PPPOE Discovery\n"); DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: case ETHERNET_TYPE_8021QINQ: DecodeVLAN(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; case ETHERNET_TYPE_MPLS_UNICAST: case ETHERNET_TYPE_MPLS_MULTICAST: DecodeMPLS(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, pq); break; default: SCLogDebug("p %p pkt %p ether type %04x not supported", p, pkt, ntohs(p->ethh->eth_type)); } return TM_ECODE_OK; }
/** * \test routing header decode */ static int DecodeIPV6RouteTest01 (void) { uint8_t raw_pkt1[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40, 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0xfa, 0x87, 0x00, 0x00, }; Packet *p1 = SCMalloc(SIZE_OF_PACKET); if (p1 == NULL) return 0; ThreadVars tv; DecodeThreadVars dtv; int result = 0; PacketQueue pq; FlowInitConfig(FLOW_QUIET); memset(&pq, 0, sizeof(PacketQueue)); memset(&tv, 0, sizeof(ThreadVars)); memset(p1, 0, SIZE_OF_PACKET); p1->pkt = (uint8_t *)(p1 + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); PACKET_INITIALIZE(p1); PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); if (!(IPV6_EXTHDR_ISSET_RH(p1))) { printf("ipv6 routing header not detected: "); goto end; } if (p1->ip6eh.ip6_exthdrs[0].len != 8) { printf("ipv6 routing length incorrect: "); goto end; } result = 1; end: PACKET_CLEANUP(p1); SCFree(p1); FlowShutdown(); return result; }
/** \test icmpv6 message type: packet too big, invalid packet * \brief Set the event ICMPV6_UNKNOWN_CODE if code is invalid for this type * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6PktTooBigTest02(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x10, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00, 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (p->icmpv6h == NULL) { SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); retval = 0; goto end; } if (!DECODER_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { SCLogDebug("ICMPv6 Error: Unknown code event not set"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
/**\test icmpv6 message type: echo reply, valid packet * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6EchoRepTest01(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (p->icmpv6h == NULL) { SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); retval = 0; goto end; } SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 || ICMPV6_GET_ID(p) != 61477 || ICMPV6_GET_SEQ(p) != 29987) { SCLogDebug("ICMPv6 Echo reply decode failed"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
/**\test icmpv6 packet decoding and setting up of payload_len and payload buufer * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6PayloadTest01(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (p->payload == NULL) { printf("payload == NULL, expected non-NULL: "); goto end; } if (p->payload_len != 37) { printf("payload_len %"PRIu16", expected 37: ", p->payload_len); goto end; } retval = 1; end: SCFree(p); return retval; }
/** * \test HOP header decode */ static int DecodeIPV6HopTest01 (void) { uint8_t raw_pkt1[] = { 0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00, 0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0x05,0x02,0x00,0x00,0x00,0x00, 0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; Packet *p1 = PacketGetFromAlloc(); if (unlikely(p1 == NULL)) return 0; ThreadVars tv; DecodeThreadVars dtv; int result = 0; PacketQueue pq; FlowInitConfig(FLOW_QUIET); memset(&pq, 0, sizeof(PacketQueue)); memset(&tv, 0, sizeof(ThreadVars)); memset(&dtv, 0, sizeof(DecodeThreadVars)); PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); if (!(IPV6_EXTHDR_ISSET_HH(p1))) { printf("ipv6 routing header not detected: "); goto end; } if (p1->ip6eh.ip6_exthdrs[0].len != 8) { printf("ipv6 routing length incorrect: "); goto end; } if (ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)) { printf("engine event IPV6_HOPOPTS_UNKNOWN_OPT set: "); goto end; } result = 1; end: PACKET_RECYCLE(p1); SCFree(p1); FlowShutdown(); return result; }
void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq, uint8_t proto) { switch (proto) { case PPP_OVER_GRE: return DecodePPP(tv, dtv, p, pkt, len, pq); case IPPROTO_IP: return DecodeIPV4(tv, dtv, p, pkt, len, pq); case IPPROTO_IPV6: return DecodeIPV6(tv, dtv, p, pkt, len, pq); case VLAN_OVER_GRE: return DecodeVLAN(tv, dtv, p, pkt, len, pq); default: SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto); break; } }
/**\test icmpv6 message type: destination unreach, invalid packet * \brief The embedded packet header (ipv6) is truncated * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6DestUnreachTest02(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (!DECODER_ISSET_EVENT(p, ICMPV6_IPV6_TRUNC_PKT)) { SCLogDebug("ICMPv6 Error: embedded ipv6 truncated packet event not set"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
/** * \internal * \brief this function is used to decode IEEE802.1q packets * * \param tv pointer to the thread vars * \param dtv pointer code thread vars * \param p pointer to the packet struct * \param pkt pointer to the raw packet * \param len packet len * \param pq pointer to the packet queue * */ void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca); if(len < VLAN_HEADER_LEN) { DECODER_SET_EVENT(p,VLAN_HEADER_TOO_SMALL); return; } p->vlanh = (VLANHdr *)pkt; if(p->vlanh == NULL) return; SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "", p, pkt, GET_VLAN_PROTO(p->vlanh), GET_VLAN_PRIORITY(p->vlanh), GET_VLAN_CFI(p->vlanh), GET_VLAN_ID(p->vlanh), len); switch (GET_VLAN_PROTO(p->vlanh)) { case ETHERNET_TYPE_IP: DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_SESS: DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_DISC: DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; default: SCLogDebug("unknown VLAN type: %" PRIx32 "",GET_VLAN_PROTO(p->vlanh)); DECODER_SET_EVENT(p,VLAN_UNKNOWN_TYPE); return; } return; }
/** \test icmpv6 message type: time exceed, invalid packet * \brief set the event ICMPV6_PKT_TOO_SMALL properly * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6TimeExceedTest02(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x10, 0x5c }; /* The icmpv6 header is broken in the checksum (so we dont have a complete header) */ Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (!DECODER_ISSET_EVENT(p, ICMPV6_PKT_TOO_SMALL)) { SCLogDebug("ICMPv6 Error: event packet too small not set"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
/**\test icmpv6 message type: echo request, invalid packet * \brief unknown code * \retval retval 0 = Error ; 1 = ok */ static int ICMPV6EchoReqTest02(void) { int retval = 0; static uint8_t raw_ipv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); FlowInitConfig(FLOW_QUIET); DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); FlowShutdown(); if (!DECODER_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { SCLogDebug("ICMPv6 Error: Unknown code event not set"); retval = 0; goto end; } retval = 1; end: SCFree(p); return retval; }
int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq, enum DecodeTunnelProto proto) { switch (proto) { case DECODE_TUNNEL_PPP: return DecodePPP(tv, dtv, p, pkt, len, pq); case DECODE_TUNNEL_IPV4: return DecodeIPV4(tv, dtv, p, pkt, len, pq); case DECODE_TUNNEL_IPV6: return DecodeIPV6(tv, dtv, p, pkt, len, pq); case DECODE_TUNNEL_VLAN: return DecodeVLAN(tv, dtv, p, pkt, len, pq); case DECODE_TUNNEL_ETHERNET: return DecodeEthernet(tv, dtv, p, pkt, len, pq); case DECODE_TUNNEL_ERSPAN: return DecodeERSPAN(tv, dtv, p, pkt, len, pq); default: SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto); break; } return TM_ECODE_OK; }
void 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 (len < IPV4_HEADER_LEN) { ENGINE_SET_EVENT(p,IPV4_PKT_TOO_SMALL); return; } if (IP_GET_RAW_VER(pkt) == 4) { SCLogDebug("IPV4 Packet"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if (IP_GET_RAW_VER(pkt) == 6) { SCLogDebug("IPV6 Packet"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt)); ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV); } return; }
/** * \test routing header decode */ static int DecodeIPV6RouteTest01 (void) { uint8_t raw_pkt1[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40, 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0xfa, 0x87, 0x00, 0x00, }; Packet *p1 = PacketGetFromAlloc(); FAIL_IF(unlikely(p1 == NULL)); ThreadVars tv; DecodeThreadVars dtv; PacketQueue pq; FlowInitConfig(FLOW_QUIET); memset(&pq, 0, sizeof(PacketQueue)); memset(&tv, 0, sizeof(ThreadVars)); memset(&dtv, 0, sizeof(DecodeThreadVars)); PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); FAIL_IF (!(IPV6_EXTHDR_ISSET_RH(p1))); FAIL_IF (p1->ip6eh.rh_type != 0); PACKET_RECYCLE(p1); SCFree(p1); FlowShutdown(); PASS; }
/** * \brief Decode a packet coming from NFQ */ TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); DecodeThreadVars *dtv = (DecodeThreadVars *)data; /* XXX HACK: flow timeout can call us for injected pseudo packets * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ if (p->flags & PKT_PSEUDO_STREAM_END) return TM_ECODE_OK; SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); #if 0 SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca, (GET_PKT_LEN(p) * 8)/1000000.0); #endif if (IPV4_GET_RAW_VER(ip4h) == 4) { SCLogDebug("IPv4 packet"); DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else if(IPV6_GET_RAW_VER(ip6h) == 6) { SCLogDebug("IPv6 packet"); DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); } else { SCLogDebug("packet unsupported by NFQ, first byte: %02x", *GET_PKT_DATA(p)); } PacketDecodeFinalize(tv, dtv, p); return TM_ECODE_OK; }
/** * \internal * \brief this function is used to decode IEEE802.1q packets * * \param tv pointer to the thread vars * \param dtv pointer code thread vars * \param p pointer to the packet struct * \param pkt pointer to the raw packet * \param len packet len * \param pq pointer to the packet queue * */ int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { uint32_t proto; SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca); if(len < VLAN_HEADER_LEN) { ENGINE_SET_INVALID_EVENT(p, VLAN_HEADER_TOO_SMALL); return TM_ECODE_FAILED; } if (p->vlan_idx >= 2) { ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); return TM_ECODE_FAILED; } p->vlanh[p->vlan_idx] = (VLANHdr *)pkt; if(p->vlanh[p->vlan_idx] == NULL) return TM_ECODE_FAILED; proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]); SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "", p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]), GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len); /* only store the id for flow hashing if it's not disabled. */ if (dtv->vlan_disabled == 0) p->vlan_id[p->vlan_idx] = (uint16_t)GET_VLAN_ID(p->vlanh[p->vlan_idx]); p->vlan_idx++; switch (proto) { case ETHERNET_TYPE_IP: DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_SESS: DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_DISC: DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: if (p->vlan_idx >= 2) { ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); return TM_ECODE_OK; } else { DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); } break; default: SCLogDebug("unknown VLAN type: %" PRIx32 "", proto); ENGINE_SET_INVALID_EVENT(p, VLAN_UNKNOWN_TYPE); return TM_ECODE_OK; } return TM_ECODE_OK; }
/** * \test fragment decoding */ static int DecodeIPV6FragTest01 (void) { uint8_t raw_frag1[] = { 0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01, 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7, 0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13, 0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44, 0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a, 0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39, 0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33, 0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75, 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, }; uint8_t raw_frag2[] = { 0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01, 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, }; Packet *p1 = SCMalloc(SIZE_OF_PACKET); if (p1 == NULL) return 0; Packet *p2 = SCMalloc(SIZE_OF_PACKET); if (p2 == NULL) { SCFree(p1); return 0; } ThreadVars tv; DecodeThreadVars dtv; int result = 0; PacketQueue pq; FlowInitConfig(FLOW_QUIET); memset(&pq, 0, sizeof(PacketQueue)); memset(&tv, 0, sizeof(ThreadVars)); memset(p1, 0, SIZE_OF_PACKET); p1->pkt = (uint8_t *)(p1 + 1); memset(p2, 0, SIZE_OF_PACKET); p2->pkt = (uint8_t *)(p2 + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); PACKET_INITIALIZE(p1); PACKET_INITIALIZE(p2); PacketCopyData(p1, raw_frag1, sizeof(raw_frag1)); PacketCopyData(p2, raw_frag2, sizeof(raw_frag2)); DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); if (!(IPV6_EXTHDR_ISSET_FH(p1))) { printf("ipv6 frag header not detected: "); goto end; } DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2), &pq); if (!(IPV6_EXTHDR_ISSET_FH(p2))) { printf("ipv6 frag header not detected: "); goto end; } if (pq.len != 1) { printf("no reassembled packet: "); goto end; } result = 1; end: PACKET_CLEANUP(p1); PACKET_CLEANUP(p2); SCFree(p1); SCFree(p2); FlowShutdown(); return result; }
void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { int ret; SCPerfCounterIncr(dtv->counter_ipv6, tv->sc_perf_pca); /* do the actual decoding */ ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); if (ret < 0) { p->ip6h = NULL; return; } #ifdef DEBUG if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ /* debug print */ char s[46], d[46]; PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d)); SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d, IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p), IPV6_GET_HLIM(p)); } #endif /* DEBUG */ /* now process the Ext headers and/or the L4 Layer */ switch(IPV6_GET_NH(p)) { case IPPROTO_TCP: IPV6_SET_L4PROTO (p, IPPROTO_TCP); return DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_UDP: IPV6_SET_L4PROTO (p, IPPROTO_UDP); return DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; case IPPROTO_ICMPV6: IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6); return DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_SCTP: IPV6_SET_L4PROTO (p, IPPROTO_SCTP); return DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_IPIP: IPV6_SET_L4PROTO(p, IPPROTO_IPIP); return DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_IPV6: return DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); case IPPROTO_FRAGMENT: case IPPROTO_HOPOPTS: case IPPROTO_ROUTING: case IPPROTO_NONE: case IPPROTO_DSTOPTS: case IPPROTO_AH: case IPPROTO_ESP: DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); break; default: p->proto = IPV6_GET_NH(p); break; } /* Pass to defragger if a fragment. */ if (IPV6_EXTHDR_ISSET_FH(p)) { Packet *rp = Defrag(tv, dtv, NULL, 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); } } #ifdef DEBUG if (IPV6_EXTHDR_ISSET_FH(p)) { SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "", (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p), IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p)); } if (IPV6_EXTHDR_ISSET_RH(p)) { SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "", IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p), IPV6_EXTHDR_GET_RH_TYPE(p)); } if (IPV6_EXTHDR_ISSET_HH(p)) { SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p)); } if (IPV6_EXTHDR_ISSET_DH1(p)) { SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p)); } if (IPV6_EXTHDR_ISSET_DH2(p)) { SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p)); } #endif return; }
int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { uint32_t shim; int label; int event = 0; StatsIncr(tv, dtv->counter_mpls); do { if (len < MPLS_HEADER_LEN) { ENGINE_SET_INVALID_EVENT(p, MPLS_HEADER_TOO_SMALL); return TM_ECODE_FAILED; } shim = *(uint32_t *)pkt; pkt += MPLS_HEADER_LEN; len -= MPLS_HEADER_LEN; } while (MPLS_BOTTOM(shim) == 0); label = MPLS_LABEL(shim); if (label == MPLS_LABEL_IPV4) { return DecodeIPV4(tv, dtv, p, pkt, len, pq); } else if (label == MPLS_LABEL_ROUTER_ALERT) { /* Not valid at the bottom of the stack. */ event = MPLS_BAD_LABEL_ROUTER_ALERT; } else if (label == MPLS_LABEL_IPV6) { return DecodeIPV6(tv, dtv, p, pkt, len, pq); } else if (label == MPLS_LABEL_NULL) { /* Shouldn't appear on the wire. */ event = MPLS_BAD_LABEL_IMPLICIT_NULL; } else if (label < MPLS_MAX_RESERVED_LABEL) { event = MPLS_BAD_LABEL_RESERVED; } if (event) { goto end; } /* Best guess at inner packet. */ switch (pkt[0] >> 4) { case MPLS_PROTO_IPV4: DecodeIPV4(tv, dtv, p, pkt, len, pq); break; case MPLS_PROTO_IPV6: DecodeIPV6(tv, dtv, p, pkt, len, pq); break; case MPLS_PROTO_ETHERNET_PW: DecodeEthernet(tv, dtv, p, pkt + MPLS_PW_LEN, len - MPLS_PW_LEN, pq); break; default: ENGINE_SET_INVALID_EVENT(p, MPLS_UNKNOWN_PAYLOAD_TYPE); return TM_ECODE_OK; } end: if (event) { ENGINE_SET_EVENT(p, event); } return TM_ECODE_OK; }
/** * \test DetectDsizeIcmpv6Test01 is a test for checking the working of * dsize keyword by creating 2 rules and matching a crafted packet * against them. Only the first one shall trigger. */ int DetectDsizeIcmpv6Test01 (void) { int result = 0; static uint8_t raw_icmpv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); memset(&th_v, 0, sizeof(ThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET6; p->dst.family = AF_INET6; p->ip6h = &ip6h; DecodeIPV6(&tv, &dtv, p, raw_icmpv6, sizeof(raw_icmpv6), NULL); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(msg:\"ICMP Large ICMP Packet\"; dsize:>8; sid:1; rev:4;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx, "alert icmp any any -> any any " "(msg:\"ICMP Large ICMP Packet\"; dsize:>800; sid:2; rev:4;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1) == 0) { printf("sid 1 did not alert, but should have: "); goto cleanup; } else if (PacketAlertCheck(p, 2)) { printf("sid 2 alerted, but should not have: "); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); FlowShutdown(); end: SCFree(p); return result; }
/** * \brief Main decoding function for PPPOE Session packets */ 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_INVALID_EVENT(p, PPPOE_PKT_TOO_SMALL); return TM_ECODE_FAILED; } p->pppoesh = (PPPOESessionHdr *)pkt; if (p->pppoesh == NULL) 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)); /* can't use DecodePPP() here because we only get a single 2-byte word to indicate protocol instead of the full PPP header */ if (ntohs(p->pppoesh->pppoe_length) > 0) { /* decode contained PPP packet */ switch (ntohs(p->pppoesh->protocol)) { case PPP_VJ_COMP: case PPP_IPX: case PPP_OSI: case PPP_NS: case PPP_DECNET: case PPP_APPLE: case PPP_BRPDU: case PPP_STII: case PPP_VINES: case PPP_HELLO: case PPP_LUXCOM: case PPP_SNS: case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: case PPP_IPCP: case PPP_OSICP: case PPP_NSCP: case PPP_DECNETCP: case PPP_APPLECP: case PPP_IPXCP: case PPP_STIICP: case PPP_VINESCP: case PPP_IPV6CP: case PPP_MPLSCP: case PPP_LCP: case PPP_PAP: case PPP_LQM: case PPP_CHAP: ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO); break; case PPP_VJ_UCOMP: if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, PPPVJU_PKT_TOO_SMALL); return TM_ECODE_OK; } if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) { DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); } break; case PPP_IP: if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, PPPIPV4_PKT_TOO_SMALL); return TM_ECODE_OK; } DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); break; /* PPP IPv6 was not tested */ case PPP_IPV6: if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN)) { ENGINE_SET_INVALID_EVENT(p, PPPIPV6_PKT_TOO_SMALL); return TM_ECODE_OK; } DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); break; default: SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol)); ENGINE_SET_INVALID_EVENT(p, PPP_WRONG_TYPE); return TM_ECODE_OK; } } return TM_ECODE_OK; }
int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq) { uint32_t shim; int label; int event = 0; StatsIncr(tv, dtv->counter_mpls); do { if (len < MPLS_HEADER_LEN) { ENGINE_SET_INVALID_EVENT(p, MPLS_HEADER_TOO_SMALL); return TM_ECODE_FAILED; } memcpy(&shim, pkt, sizeof(shim)); pkt += MPLS_HEADER_LEN; len -= MPLS_HEADER_LEN; } while (MPLS_BOTTOM(shim) == 0); label = MPLS_LABEL(shim); if (label == MPLS_LABEL_IPV4) { if (len > USHRT_MAX) { return TM_ECODE_FAILED; } return DecodeIPV4(tv, dtv, p, pkt, len, pq); } else if (label == MPLS_LABEL_ROUTER_ALERT) { /* Not valid at the bottom of the stack. */ event = MPLS_BAD_LABEL_ROUTER_ALERT; } else if (label == MPLS_LABEL_IPV6) { if (len > USHRT_MAX) { return TM_ECODE_FAILED; } return DecodeIPV6(tv, dtv, p, pkt, len, pq); } else if (label == MPLS_LABEL_NULL) { /* Shouldn't appear on the wire. */ event = MPLS_BAD_LABEL_IMPLICIT_NULL; } else if (label < MPLS_MAX_RESERVED_LABEL) { event = MPLS_BAD_LABEL_RESERVED; } if (event) { goto end; } // Make sure we still have enough data. While we only need 1 byte to test // for IPv4 and IPv4, we need for to check for ethernet. if (len < MPLS_PW_LEN) { ENGINE_SET_INVALID_EVENT(p, MPLS_PKT_TOO_SMALL); return TM_ECODE_FAILED; } /* Best guess at inner packet. */ switch (pkt[0] >> 4) { case MPLS_PROTO_IPV4: if (len > USHRT_MAX) { return TM_ECODE_FAILED; } DecodeIPV4(tv, dtv, p, pkt, len, pq); break; case MPLS_PROTO_IPV6: if (len > USHRT_MAX) { return TM_ECODE_FAILED; } DecodeIPV6(tv, dtv, p, pkt, len, pq); break; case MPLS_PROTO_ETHERNET_PW: DecodeEthernet(tv, dtv, p, pkt + MPLS_PW_LEN, len - MPLS_PW_LEN, pq); break; default: ENGINE_SET_INVALID_EVENT(p, MPLS_UNKNOWN_PAYLOAD_TYPE); return TM_ECODE_OK; } end: if (event) { ENGINE_SET_EVENT(p, event); } return TM_ECODE_OK; }