decode/icmpv4: move icmpv4h into L4 packet data

To reduce Packet size.

Ticket: #6938.
pull/10971/head
Victor Julien 2 years ago committed by Victor Julien
parent b959d1dba8
commit 852ff83d70

@ -69,62 +69,62 @@ static int DecodePartialIPV4(Packet* p, uint8_t* partial_packet, uint16_t len)
}
/** We need to fill icmpv4vars */
p->icmpv4vars.emb_ipv4h = icmp4_ip4h;
p->l4.vars.icmpv4.emb_ipv4h = icmp4_ip4h;
switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) {
case IPPROTO_TCP:
if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) {
TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = SCNtohs(emb_tcph->th_sport);
p->icmpv4vars.emb_dport = SCNtohs(emb_tcph->th_dport);
p->icmpv4vars.emb_ports_set = true;
p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;
p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_tcph->th_sport);
p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_tcph->th_dport);
p->l4.vars.icmpv4.emb_ports_set = true;
p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_TCP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport,
p->icmpv4vars.emb_dport);
"%" PRIu16 " dport %" PRIu16 "",
p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport);
} else if (len >= IPV4_HEADER_LEN + 4) {
/* only access th_sport and th_dport */
TCPHdr *emb_tcph = (TCPHdr *)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = SCNtohs(emb_tcph->th_sport);
p->icmpv4vars.emb_dport = SCNtohs(emb_tcph->th_dport);
p->icmpv4vars.emb_ports_set = true;
p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP;
p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_tcph->th_sport);
p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_tcph->th_dport);
p->l4.vars.icmpv4.emb_ports_set = true;
p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_TCP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport,
p->icmpv4vars.emb_dport);
"%" PRIu16 " dport %" PRIu16 "",
p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport);
} else {
SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP "
"header Didn't fit in the packet!");
p->icmpv4vars.emb_sport = 0;
p->icmpv4vars.emb_dport = 0;
p->l4.vars.icmpv4.emb_sport = 0;
p->l4.vars.icmpv4.emb_dport = 0;
}
break;
case IPPROTO_UDP:
if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) {
UDPHdr *emb_udph = (UDPHdr *)(partial_packet + IPV4_HEADER_LEN);
p->icmpv4vars.emb_sport = SCNtohs(emb_udph->uh_sport);
p->icmpv4vars.emb_dport = SCNtohs(emb_udph->uh_dport);
p->icmpv4vars.emb_ports_set = true;
p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP;
p->l4.vars.icmpv4.emb_sport = SCNtohs(emb_udph->uh_sport);
p->l4.vars.icmpv4.emb_dport = SCNtohs(emb_udph->uh_dport);
p->l4.vars.icmpv4.emb_ports_set = true;
p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_UDP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: "
"%"PRIu16" dport %"PRIu16"", p->icmpv4vars.emb_sport,
p->icmpv4vars.emb_dport);
"%" PRIu16 " dport %" PRIu16 "",
p->l4.vars.icmpv4.emb_sport, p->l4.vars.icmpv4.emb_dport);
} else {
SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP "
"header Didn't fit in the packet!");
p->icmpv4vars.emb_sport = 0;
p->icmpv4vars.emb_dport = 0;
p->l4.vars.icmpv4.emb_sport = 0;
p->l4.vars.icmpv4.emb_dport = 0;
}
break;
case IPPROTO_ICMP:
if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN) {
p->icmpv4vars.emb_sport = 0;
p->icmpv4vars.emb_dport = 0;
p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP;
p->l4.vars.icmpv4.emb_sport = 0;
p->l4.vars.icmpv4.emb_dport = 0;
p->l4.vars.icmpv4.emb_ip4_proto = IPPROTO_ICMP;
SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header");
}
@ -147,34 +147,33 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
return TM_ECODE_FAILED;
}
p->icmpv4h = (ICMPV4Hdr *)pkt;
ICMPV4Hdr *icmpv4h = PacketSetICMPv4(p, pkt);
SCLogDebug("ICMPV4 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv4h->type, p->icmpv4h->code);
SCLogDebug("ICMPV4 TYPE %" PRIu32 " CODE %" PRIu32 "", icmpv4h->type, icmpv4h->code);
p->proto = IPPROTO_ICMP;
p->icmp_s.type = p->icmpv4h->type;
p->icmp_s.code = p->icmpv4h->code;
const uint8_t type = p->icmp_s.type = icmpv4h->type;
const uint8_t code = p->icmp_s.code = icmpv4h->code;
int ctype = ICMPv4GetCounterpart(p->icmp_s.type);
int ctype = ICMPv4GetCounterpart(type);
if (ctype != -1) {
p->icmp_d.type = (uint8_t)ctype;
}
ICMPV4ExtHdr* icmp4eh = (ICMPV4ExtHdr*) p->icmpv4h;
p->icmpv4vars.hlen = ICMPV4_HEADER_LEN;
ICMPV4ExtHdr *icmp4eh = (ICMPV4ExtHdr *)icmpv4h;
p->l4.vars.icmpv4.hlen = ICMPV4_HEADER_LEN;
switch (p->icmpv4h->type)
{
switch (type) {
case ICMP_ECHOREPLY:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
case ICMP_DEST_UNREACH:
if (p->icmpv4h->code > NR_ICMP_UNREACH) {
if (code > NR_ICMP_UNREACH) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
/* parse IP header plus 64 bytes */
@ -189,7 +188,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
break;
case ICMP_SOURCE_QUENCH:
if (p->icmpv4h->code!=0) {
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
// parse IP header plus 64 bytes
@ -204,7 +203,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
break;
case ICMP_REDIRECT:
if (p->icmpv4h->code>ICMP_REDIR_HOSTTOS) {
if (code > ICMP_REDIR_HOSTTOS) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
// parse IP header plus 64 bytes
@ -219,15 +218,15 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
break;
case ICMP_ECHO:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
case ICMP_TIME_EXCEEDED:
if (p->icmpv4h->code>ICMP_EXC_FRAGTIME) {
if (code > ICMP_EXC_FRAGTIME) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
// parse IP header plus 64 bytes
@ -242,7 +241,7 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
break;
case ICMP_PARAMETERPROB:
if (p->icmpv4h->code!=0) {
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
} else {
// parse IP header plus 64 bytes
@ -257,45 +256,45 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
break;
case ICMP_TIMESTAMP:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
if (len < (sizeof(ICMPV4Timestamp) + ICMPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT);
} else {
p->icmpv4vars.hlen += sizeof(ICMPV4Timestamp);
p->l4.vars.icmpv4.hlen += sizeof(ICMPV4Timestamp);
}
break;
case ICMP_TIMESTAMPREPLY:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
if (len < (sizeof(ICMPV4Timestamp) + ICMPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT);
} else {
p->icmpv4vars.hlen += sizeof(ICMPV4Timestamp);
p->l4.vars.icmpv4.hlen += sizeof(ICMPV4Timestamp);
}
break;
case ICMP_INFO_REQUEST:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
case ICMP_INFO_REPLY:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
@ -308,34 +307,33 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t
if (len < (advert_len + ICMPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p, ICMPV4_IPV4_TRUNC_PKT);
} else {
p->icmpv4vars.hlen += advert_len;
p->l4.vars.icmpv4.hlen += advert_len;
}
} break;
case ICMP_ADDRESS:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
case ICMP_ADDRESSREPLY:
p->icmpv4vars.id=icmp4eh->id;
p->icmpv4vars.seq=icmp4eh->seq;
if (p->icmpv4h->code!=0) {
p->l4.vars.icmpv4.id = icmp4eh->id;
p->l4.vars.icmpv4.seq = icmp4eh->seq;
if (code != 0) {
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
}
break;
default:
ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_TYPE);
ENGINE_SET_EVENT(p, ICMPV4_UNKNOWN_TYPE);
}
p->payload = (uint8_t *)pkt + p->icmpv4vars.hlen;
DEBUG_VALIDATE_BUG_ON(len - p->icmpv4vars.hlen > UINT16_MAX);
p->payload_len = (uint16_t)(len - p->icmpv4vars.hlen);
p->payload = (uint8_t *)pkt + p->l4.vars.icmpv4.hlen;
DEBUG_VALIDATE_BUG_ON(len - p->l4.vars.icmpv4.hlen > UINT16_MAX);
p->payload_len = (uint16_t)(len - p->l4.vars.icmpv4.hlen);
FlowSetupPacket(p);
return TM_ECODE_OK;
@ -374,11 +372,9 @@ static int DecodeICMPV4test01(void)
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab };
Packet *p = PacketGetFromAlloc();
if (unlikely(p == NULL))
return 0;
FAIL_IF_NULL(p);
ThreadVars tv;
DecodeThreadVars dtv;
int ret = 0;
IPV4Hdr ip4h;
memset(&ip4h, 0, sizeof(IPV4Hdr));
@ -398,16 +394,17 @@ static int DecodeICMPV4test01(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL!=p->icmpv4h) {
if (p->icmpv4h->type==8 && p->icmpv4h->code==0) {
ret = 1;
}
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
FAIL_IF_NOT(icmpv4h->type == 8);
FAIL_IF_NOT(icmpv4h->code == 0);
FlowShutdown();
SCFree(p);
return ret;
PASS;
}
/** DecodeICMPV4test02
@ -425,11 +422,9 @@ static int DecodeICMPV4test02(void)
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
Packet *p = PacketGetFromAlloc();
if (unlikely(p == NULL))
return 0;
FAIL_IF_NULL(p);
ThreadVars tv;
DecodeThreadVars dtv;
int ret = 0;
IPV4Hdr ip4h;
memset(&ip4h, 0, sizeof(IPV4Hdr));
@ -448,16 +443,17 @@ static int DecodeICMPV4test02(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL!=p->icmpv4h) {
if (p->icmpv4h->type==0 && p->icmpv4h->code==0) {
ret = 1;
}
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
FAIL_IF_NOT(icmpv4h->type == 0);
FAIL_IF_NOT(icmpv4h->code == 0);
FlowShutdown();
SCFree(p);
return ret;
PASS;
}
/** DecodeICMPV4test03
@ -473,11 +469,9 @@ static int DecodeICMPV4test03(void)
0xd1, 0x55, 0xe3, 0x93, 0x8b, 0x12, 0x82, 0xaa,
0x00, 0x28, 0x7c, 0xdd };
Packet *p = PacketGetFromAlloc();
if (unlikely(p == NULL))
return 0;
FAIL_IF_NULL(p);
ThreadVars tv;
DecodeThreadVars dtv;
int ret = 0;
IPV4Hdr ip4h;
memset(&ip4h, 0, sizeof(IPV4Hdr));
@ -496,26 +490,18 @@ static int DecodeICMPV4test03(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL == p->icmpv4h) {
printf("NULL == p->icmpv4h: ");
goto end;
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
/* check it's type 11 code 0 */
if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) {
printf("p->icmpv4h->type %u, p->icmpv4h->code %u: ",
p->icmpv4h->type, p->icmpv4h->code);
goto end;
}
FAIL_IF_NOT(icmpv4h->type == 11);
FAIL_IF_NOT(icmpv4h->code == 0);
/* check it's source port 35602 to port 33450 */
if (p->icmpv4vars.emb_sport != 35602 ||
p->icmpv4vars.emb_dport != 33450) {
printf("p->icmpv4vars.emb_sport %u, p->icmpv4vars.emb_dport %u: ",
p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport);
goto end;
}
FAIL_IF(p->l4.vars.icmpv4.emb_sport != 35602);
FAIL_IF(p->l4.vars.icmpv4.emb_dport != 33450);
/* check the src,dst IPs contained inside */
uint32_t src_ip = IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p));
@ -525,17 +511,12 @@ static int DecodeICMPV4test03(void)
PrintInet(AF_INET, &dst_ip, d, sizeof(d));
/* ICMPv4 embedding IPV4 192.168.1.13->209.85.227.147 pass */
if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "209.85.227.147") == 0) {
ret = 1;
}
else {
printf("s %s, d %s: ", s, d);
}
FAIL_IF_NOT(strcmp(s, "192.168.1.13") == 0);
FAIL_IF_NOT(strcmp(d, "209.85.227.147") == 0);
end:
FlowShutdown();
SCFree(p);
return ret;
PASS;
}
/** DecodeICMPV4test04
@ -576,19 +557,17 @@ static int DecodeICMPV4test04(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL == p->icmpv4h) {
goto end;
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
/* check the type,code pair is correct - type 3, code 10 */
if (p->icmpv4h->type != 3 || p->icmpv4h->code != 10) {
goto end;
}
FAIL_IF_NOT(icmpv4h->type == 3);
FAIL_IF_NOT(icmpv4h->code == 10);
/* check it's src port 45322 to dst port 50 */
if (p->icmpv4vars.emb_sport != 45322 ||
p->icmpv4vars.emb_dport != 50) {
if (p->l4.vars.icmpv4.emb_sport != 45322 || p->l4.vars.icmpv4.emb_dport != 50) {
goto end;
}
@ -646,19 +625,17 @@ static int DecodeICMPV4test05(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL == p->icmpv4h) {
goto end;
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
/* check the type,code pair is correct - type 11, code 0 */
if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) {
goto end;
}
FAIL_IF_NOT(icmpv4h->type == 11);
FAIL_IF_NOT(icmpv4h->code == 0);
/* check it's src port 1048 to dst port 80 */
if (p->icmpv4vars.emb_sport != 1048 ||
p->icmpv4vars.emb_dport != 80) {
if (p->l4.vars.icmpv4.emb_sport != 1048 || p->l4.vars.icmpv4.emb_dport != 80) {
goto end;
}
@ -773,11 +750,9 @@ static int DecodeICMPV4test08(void)
0x08, 0x00, 0x78, 0x47, 0xfc, 0x55, 0x00, 0x00
};
Packet *p = PacketGetFromAlloc();
if (unlikely(p == NULL))
return 0;
FAIL_IF_NULL(p);
ThreadVars tv;
DecodeThreadVars dtv;
int ret = 0;
IPV4Hdr ip4h;
memset(&ip4h, 0, sizeof(IPV4Hdr));
@ -796,16 +771,17 @@ static int DecodeICMPV4test08(void)
UTHSetIPV4Hdr(p, &ip4h);
DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
FAIL_IF_NOT(PacketIsICMPv4(p));
if (NULL!=p->icmpv4h) {
if (p->icmpv4h->type==8 && p->icmpv4h->code==0) {
ret = 1;
}
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
FAIL_IF_NULL(icmpv4h);
FAIL_IF_NOT(icmpv4h->type == 8);
FAIL_IF_NOT(icmpv4h->code == 0);
FlowShutdown();
SCFree(p);
return ret;
PASS;
}
#endif /* UNITTESTS */

@ -234,18 +234,18 @@ typedef struct ICMPV4Timestamp_ {
/* If message is informational */
/** macro for icmpv4 "id" access */
#define ICMPV4_GET_ID(p) ((p)->icmpv4vars.id)
#define ICMPV4_GET_ID(p) ((p)->l4.vars.icmpv4.id)
/** macro for icmpv4 "seq" access */
#define ICMPV4_GET_SEQ(p) ((p)->icmpv4vars.seq)
#define ICMPV4_GET_SEQ(p) ((p)->l4.vars.icmpv4.seq)
/* If message is Error */
/** macro for icmpv4 embedded "protocol" access */
#define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip4_proto
#define ICMPV4_GET_EMB_PROTO(p) (p)->l4.vars.icmpv4.emb_ip4_proto
/** macro for icmpv4 embedded "ipv4h" header access */
#define ICMPV4_GET_EMB_IPV4(p) (p)->icmpv4vars.emb_ipv4h
#define ICMPV4_GET_EMB_IPV4(p) (p)->l4.vars.icmpv4.emb_ipv4h
/** macro for icmpv4 header length */
#define ICMPV4_GET_HLEN_ICMPV4H(p) (p)->icmpv4vars.hlen
#define ICMPV4_GET_HLEN_ICMPV4H(p) (p)->l4.vars.icmpv4.hlen
/** macro for checking if a ICMP DEST UNREACH packet is valid for use
* in other parts of the engine, such as the flow engine.
@ -253,9 +253,9 @@ typedef struct ICMPV4Timestamp_ {
* \warning use only _after_ the decoder has processed the packet
*/
#define ICMPV4_DEST_UNREACH_IS_VALID(p) \
((!((p)->flags & PKT_IS_INVALID)) && ((p)->icmpv4h != NULL) && \
(ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH) && (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \
(p)->icmpv4vars.emb_ports_set)
((!((p)->flags & PKT_IS_INVALID)) && PacketIsICMPv4((p)) && \
((p)->icmp_s.type == ICMP_DEST_UNREACH) && (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \
(p)->l4.vars.icmpv4.emb_ports_set)
/**
* marco for checking if a ICMP packet is an error message or an
@ -266,11 +266,9 @@ typedef struct ICMPV4Timestamp_ {
* stage so we can to a bit check instead of the more expensive
* check below.
*/
#define ICMPV4_IS_ERROR_MSG(p) (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH || \
ICMPV4_GET_TYPE((p)) == ICMP_SOURCE_QUENCH || \
ICMPV4_GET_TYPE((p)) == ICMP_REDIRECT || \
ICMPV4_GET_TYPE((p)) == ICMP_TIME_EXCEEDED || \
ICMPV4_GET_TYPE((p)) == ICMP_PARAMETERPROB)
#define ICMPV4_IS_ERROR_MSG(type) \
((type) == ICMP_DEST_UNREACH || (type) == ICMP_SOURCE_QUENCH || (type) == ICMP_REDIRECT || \
(type) == ICMP_TIME_EXCEEDED || (type) == ICMP_PARAMETERPROB)
void DecodeICMPV4RegisterTests(void);

@ -428,6 +428,7 @@ struct PacketL3 {
enum PacketL4Types {
PACKET_L4_UNKNOWN = 0,
PACKET_L4_ICMPV4,
PACKET_L4_ICMPV6,
PACKET_L4_SCTP,
PACKET_L4_GRE,
@ -439,12 +440,14 @@ struct PacketL4 {
bool csum_set;
uint16_t csum;
union L4Hdrs {
ICMPV4Hdr *icmpv4h;
ICMPV6Hdr *icmpv6h;
SCTPHdr *sctph;
GREHdr *greh;
ESPHdr *esph;
} hdrs;
union L4Vars {
ICMPV4Vars icmpv4;
ICMPV6Vars icmpv6;
} vars;
};
@ -575,14 +578,11 @@ typedef struct Packet_
/* Can only be one of TCP, UDP, ICMP at any given time */
union {
TCPVars tcpvars;
ICMPV4Vars icmpv4vars;
} l4vars;
#define tcpvars l4vars.tcpvars
#define icmpv4vars l4vars.icmpv4vars
#define tcpvars l4vars.tcpvars
TCPHdr *tcph;
UDPHdr *udph;
ICMPV4Hdr *icmpv4h;
PPPOESessionHdr *pppoesh;
PPPOEDiscoveryHdr *pppoedh;
@ -770,9 +770,23 @@ static inline bool PacketIsUDP(const Packet *p)
return PKT_IS_UDP(p);
}
static inline ICMPV4Hdr *PacketSetICMPv4(Packet *p, const uint8_t *buf)
{
DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_UNKNOWN);
p->l4.type = PACKET_L4_ICMPV4;
p->l4.hdrs.icmpv4h = (ICMPV4Hdr *)buf;
return p->l4.hdrs.icmpv4h;
}
static inline const ICMPV4Hdr *PacketGetICMPv4(const Packet *p)
{
DEBUG_VALIDATE_BUG_ON(p->l4.type != PACKET_L4_ICMPV4);
return p->l4.hdrs.icmpv4h;
}
static inline bool PacketIsICMPv4(const Packet *p)
{
return PKT_IS_ICMPV4(p);
return p->l4.type == PACKET_L4_ICMPV4;
}
static inline ICMPV6Hdr *PacketSetICMPv6(Packet *p, const uint8_t *buf)

@ -693,15 +693,16 @@ static int DetectICMPV4CsumMatch(DetectEngineThreadCtx *det_ctx,
return cd->valid;
}
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
if (!p->l4.csum_set) {
const IPV4Hdr *ip4h = PacketGetIPv4(p);
p->l4.csum = ICMPV4CalculateChecksum(
(uint16_t *)p->icmpv4h, IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h));
(uint16_t *)icmpv4h, IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h));
p->l4.csum_set = true;
}
if (p->l4.csum == p->icmpv4h->checksum && cd->valid == 1)
if (p->l4.csum == icmpv4h->checksum && cd->valid == 1)
return 1;
else if (p->l4.csum != p->icmpv4h->checksum && cd->valid == 0)
else if (p->l4.csum != icmpv4h->checksum && cd->valid == 0)
return 1;
else
return 0;

@ -1051,9 +1051,10 @@ static int SigGroupHeadTest06(void)
Packet *p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_ICMP, "192.168.1.1", "1.2.3.4");
FAIL_IF_NULL(p);
FAIL_IF_NOT(PacketIsICMPv4(p));
p->icmpv4h->type = 5;
p->icmpv4h->code = 1;
p->l4.hdrs.icmpv4h->type = 5;
p->l4.hdrs.icmpv4h->code = 1;
/* originally ip's were
p.src.addr_data32[0] = 0xe08102d3;

@ -80,7 +80,7 @@ static inline bool GetIcmpId(Packet *p, uint16_t *id)
uint16_t pid;
if (PacketIsICMPv4(p)) {
switch (ICMPV4_GET_TYPE(p)){
switch (p->icmp_s.type) {
case ICMP_ECHOREPLY:
case ICMP_ECHO:
case ICMP_TIMESTAMP:
@ -407,7 +407,7 @@ static int DetectIcmpIdMatchTest01 (void)
memset(&th_v, 0, sizeof(ThreadVars));
p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP);
p->icmpv4vars.id = htons(21781);
p->l4.vars.icmpv4.id = htons(21781);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {

@ -80,7 +80,7 @@ static inline bool GetIcmpSeq(Packet *p, uint16_t *seq)
return false;
if (PacketIsICMPv4(p)) {
switch (ICMPV4_GET_TYPE(p)){
switch (p->icmp_s.type) {
case ICMP_ECHOREPLY:
case ICMP_ECHO:
case ICMP_TIMESTAMP:

@ -101,16 +101,17 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
const ICMPV4Hdr *icmpv4h = PacketGetICMPv4(p);
uint16_t hlen = ICMPV4_GET_HLEN_ICMPV4H(p);
if (((uint8_t *)p->icmpv4h + (ptrdiff_t)hlen) >
if (((uint8_t *)icmpv4h + (ptrdiff_t)hlen) >
((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p))) {
SCLogDebug("data out of range: %p > %p", ((uint8_t *)p->icmpv4h + (ptrdiff_t)hlen),
SCLogDebug("data out of range: %p > %p", ((uint8_t *)icmpv4h + (ptrdiff_t)hlen),
((uint8_t *)GET_PKT_DATA(p) + (ptrdiff_t)GET_PKT_LEN(p)));
SCReturnPtr(NULL, "InspectionBuffer");
}
const uint32_t data_len = hlen;
const uint8_t *data = (const uint8_t *)p->icmpv4h;
const uint8_t *data = (const uint8_t *)icmpv4h;
InspectionBufferSetup(det_ctx, list_id, buffer, data, data_len);
InspectionBufferApplyTransforms(buffer, transforms);

@ -92,7 +92,7 @@ static int DetectICodeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
uint8_t picode;
if (PacketIsICMPv4(p)) {
picode = ICMPV4_GET_CODE(p);
picode = p->icmp_s.code;
} else if (PacketIsICMPv6(p)) {
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
picode = ICMPV6_GET_CODE(icmpv6h);
@ -158,7 +158,7 @@ static void PrefilterPacketICodeMatch(DetectEngineThreadCtx *det_ctx,
uint8_t picode;
if (PacketIsICMPv4(p)) {
picode = ICMPV4_GET_CODE(p);
picode = p->icmp_s.code;
} else if (PacketIsICMPv6(p)) {
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
picode = ICMPV6_GET_CODE(icmpv6h);
@ -335,17 +335,16 @@ static int DetectICodeParseTest09(void)
*/
static int DetectICodeMatchTest01(void)
{
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP);
p->icmpv4h->code = 10;
Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP);
FAIL_IF_NULL(p);
FAIL_IF_NOT(PacketIsICMPv4(p));
p->icmp_s.code = p->l4.hdrs.icmpv4h->code = 10;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);

@ -89,7 +89,7 @@ static int DetectITypeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
uint8_t pitype;
if (PacketIsICMPv4(p)) {
pitype = ICMPV4_GET_TYPE(p);
pitype = p->icmp_s.type;
} else if (PacketIsICMPv6(p)) {
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
pitype = ICMPV6_GET_TYPE(icmpv6h);
@ -174,7 +174,7 @@ static void PrefilterPacketITypeMatch(DetectEngineThreadCtx *det_ctx,
uint8_t pitype;
if (PacketIsICMPv4(p)) {
pitype = ICMPV4_GET_TYPE(p);
pitype = p->icmp_s.type;
} else if (PacketIsICMPv6(p)) {
const ICMPV6Hdr *icmpv6h = PacketGetICMPv6(p);
pitype = ICMPV6_GET_TYPE(icmpv6h);

@ -226,9 +226,9 @@ static inline uint32_t FlowGetHash(const Packet *p)
fhk.addrs[1-ai] = psrc;
fhk.addrs[ai] = pdst;
const int pi = (p->icmpv4vars.emb_sport > p->icmpv4vars.emb_dport);
fhk.ports[1-pi] = p->icmpv4vars.emb_sport;
fhk.ports[pi] = p->icmpv4vars.emb_dport;
const int pi = (p->l4.vars.icmpv4.emb_sport > p->l4.vars.icmpv4.emb_dport);
fhk.ports[1 - pi] = p->l4.vars.icmpv4.emb_sport;
fhk.ports[pi] = p->l4.vars.icmpv4.emb_dport;
fhk.proto = ICMPV4_GET_EMB_PROTO(p);
fhk.recur = p->recursion_level;
@ -470,7 +470,7 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p)
* response to the clients traffic */
if ((f->src.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p))) &&
(f->dst.addr_data32[0] == IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p))) &&
f->sp == p->icmpv4vars.emb_sport && f->dp == p->icmpv4vars.emb_dport &&
f->sp == p->l4.vars.icmpv4.emb_sport && f->dp == p->l4.vars.icmpv4.emb_dport &&
f->proto == ICMPV4_GET_EMB_PROTO(p) && f->recursion_level == p->recursion_level &&
CmpVlanIds(f->vlan_id, p->vlan_id) &&
(f->livedev == p->livedev || g_livedev_mask == 0)) {
@ -480,7 +480,7 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p)
* a packet from the server. */
} else if ((f->dst.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p))) &&
(f->src.addr_data32[0] == IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p))) &&
f->dp == p->icmpv4vars.emb_sport && f->sp == p->icmpv4vars.emb_dport &&
f->dp == p->l4.vars.icmpv4.emb_sport && f->sp == p->l4.vars.icmpv4.emb_dport &&
f->proto == ICMPV4_GET_EMB_PROTO(p) &&
f->recursion_level == p->recursion_level && CmpVlanIds(f->vlan_id, p->vlan_id) &&
(f->livedev == p->livedev || g_livedev_mask == 0)) {
@ -562,7 +562,7 @@ static inline int FlowCreateCheck(const Packet *p, const bool emerg)
}
if (PacketIsICMPv4(p)) {
if (ICMPV4_IS_ERROR_MSG(p)) {
if (ICMPV4_IS_ERROR_MSG(p->icmp_s.type)) {
return 0;
}
}

@ -329,7 +329,7 @@ int FlowGetPacketDirection(const Flow *f, const Packet *p)
static inline int FlowUpdateSeenFlag(const Packet *p)
{
if (PacketIsICMPv4(p)) {
if (ICMPV4_IS_ERROR_MSG(p)) {
if (ICMPV4_IS_ERROR_MSG(p->icmp_s.type)) {
return 0;
}
}

@ -839,9 +839,9 @@ JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir,
/* icmp */
switch (p->proto) {
case IPPROTO_ICMP:
if (p->icmpv4h) {
jb_set_uint(js, "icmp_type", p->icmpv4h->type);
jb_set_uint(js, "icmp_code", p->icmpv4h->code);
if (PacketIsICMPv4(p)) {
jb_set_uint(js, "icmp_type", p->icmp_s.type);
jb_set_uint(js, "icmp_code", p->icmp_s.code);
}
break;
case IPPROTO_ICMPV6:

@ -121,9 +121,6 @@ void PacketReinit(Packet *p)
if (p->udph != NULL) {
CLEAR_UDP_PACKET(p);
}
if (p->icmpv4h != NULL) {
CLEAR_ICMPV4_PACKET(p);
}
p->pppoesh = NULL;
p->pppoedh = NULL;
p->payload = NULL;

@ -2825,7 +2825,7 @@ static int SigTest34ICMPV4Keyword(void)
IPV4Hdr *ip4h = PacketSetIPV4(p1, valid_raw_ipv4);
ip4h->ip_verhl = 69;
p1->icmpv4h = (ICMPV4Hdr *)(valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
(void)PacketSetICMPv4(p1, valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
p1->src.family = AF_INET;
p1->dst.family = AF_INET;
p1->payload = buf;
@ -2834,7 +2834,7 @@ static int SigTest34ICMPV4Keyword(void)
ip4h = PacketSetIPV4(p2, invalid_raw_ipv4);
ip4h->ip_verhl = 69;
p2->icmpv4h = (ICMPV4Hdr *)(invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
(void)PacketSetICMPv4(p2, invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
p2->src.family = AF_INET;
p2->dst.family = AF_INET;
p2->payload = buf;
@ -2941,7 +2941,7 @@ static int SigTest35NegativeICMPV4Keyword(void)
IPV4Hdr *ip4h = PacketSetIPV4(p1, valid_raw_ipv4);
ip4h->ip_verhl = 69;
p1->icmpv4h = (ICMPV4Hdr *)(valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
(void)PacketSetICMPv4(p1, valid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
p1->src.family = AF_INET;
p1->dst.family = AF_INET;
p1->payload = buf;
@ -2950,7 +2950,7 @@ static int SigTest35NegativeICMPV4Keyword(void)
ip4h = PacketSetIPV4(p2, invalid_raw_ipv4);
ip4h->ip_verhl = 69;
p2->icmpv4h = (ICMPV4Hdr *)(invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
(void)PacketSetICMPv4(p2, invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(ip4h));
p2->src.family = AF_INET;
p2->dst.family = AF_INET;
p2->payload = buf;

@ -310,13 +310,14 @@ Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len,
p->tcph->th_dport = htons(dport);
hdr_offset += sizeof(TCPHdr);
break;
case IPPROTO_ICMP:
p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr));
if (p->icmpv4h == NULL)
case IPPROTO_ICMP: {
ICMPV4Hdr *icmpv4h = PacketSetICMPv4(p, (GET_PKT_DATA(p) + sizeof(IPV4Hdr)));
if (icmpv4h == NULL)
goto error;
hdr_offset += sizeof(ICMPV4Hdr);
break;
}
default:
break;
/* TODO: Add more protocols */

@ -77,7 +77,7 @@
} else if ((p)->proto == IPPROTO_UDP) { \
BUG_ON((p)->udph == NULL); \
} else if ((p)->proto == IPPROTO_ICMP) { \
BUG_ON((p)->icmpv4h == NULL); \
BUG_ON(PacketGetICMPv4((p)) == NULL); \
} else if ((p)->proto == IPPROTO_SCTP) { \
BUG_ON(PacketGetSCTP((p)) == NULL); \
} else if ((p)->proto == IPPROTO_ICMPV6) { \

Loading…
Cancel
Save