@ -97,47 +97,44 @@ void DecodeIPV6FragHeader(Packet *p, const uint8_t *pkt,
uint16_t frag_offset = ( * ( pkt + 2 ) < < 8 | * ( pkt + 3 ) ) & 0xFFF8 ;
int frag_morefrags = ( * ( pkt + 2 ) < < 8 | * ( pkt + 3 ) ) & 0x0001 ;
p - > ip6eh. fh_offset = frag_offset ;
p - > ip6eh. fh_more_frags_set = frag_morefrags ? true : false ;
p - > ip6eh. fh_nh = * pkt ;
p - > l3. vars . ip6. eh. fh_offset = frag_offset ;
p - > l3. vars . ip6. eh. fh_more_frags_set = frag_morefrags ? true : false ;
p - > l3. vars . ip6. eh. fh_nh = * pkt ;
uint32_t fh_id ;
memcpy ( & fh_id , pkt + 4 , 4 ) ;
p - > ip6eh. fh_id = SCNtohl ( fh_id ) ;
p - > l3. vars . ip6. eh. fh_id = SCNtohl ( fh_id ) ;
SCLogDebug ( " IPV6 FH: offset %u, mf %s, nh %u, id %u/%x " ,
p - > ip6eh . fh_offset ,
p - > ip6eh . fh_more_frags_set ? " true " : " false " ,
p - > ip6eh . fh_nh ,
p - > ip6eh . fh_id , p - > ip6eh . fh_id ) ;
SCLogDebug ( " IPV6 FH: offset %u, mf %s, nh %u, id %u/%x " , p - > l3 . vars . ip6 . eh . fh_offset ,
p - > l3 . vars . ip6 . eh . fh_more_frags_set ? " true " : " false " , p - > l3 . vars . ip6 . eh . fh_nh ,
p - > l3 . vars . ip6 . eh . fh_id , p - > l3 . vars . ip6 . eh . fh_id ) ;
// store header offset, data offset
uint16_t frag_hdr_offset = ( uint16_t ) ( pkt - GET_PKT_DATA ( p ) ) ;
uint16_t data_offset = ( uint16_t ) ( frag_hdr_offset + hdrextlen ) ;
uint16_t data_len = plen - hdrextlen ;
p - > ip6eh. fh_header_offset = frag_hdr_offset ;
p - > ip6eh. fh_data_offset = data_offset ;
p - > ip6eh. fh_data_len = data_len ;
p - > l3. vars . ip6. eh. fh_header_offset = frag_hdr_offset ;
p - > l3. vars . ip6. eh. fh_data_offset = data_offset ;
p - > l3. vars . ip6. eh. fh_data_len = data_len ;
/* if we have a prev hdr, store the type and offset of it */
if ( prev_hdrextlen ) {
p - > ip6eh. fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen ;
p - > l3. vars . ip6. eh. fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen ;
}
SCLogDebug ( " IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u " ,
p - > ip6eh. fh_header_offset , p - > ip6eh. fh_data_offset ,
p - > ip6eh. fh_data_len ) ;
p - > l3. vars . ip6. eh. fh_header_offset , p - > l3. vars . ip6. eh. fh_data_offset ,
p - > l3. vars . ip6. eh. fh_data_len ) ;
}
static void
DecodeIPV6ExtHdrs ( ThreadVars * tv , DecodeThreadVars * dtv , Packet * p ,
static void DecodeIPV6ExtHdrs ( ThreadVars * tv , DecodeThreadVars * dtv , Packet * p , const IPV6Hdr * ip6h ,
const uint8_t * pkt , uint16_t len )
{
SCEnter ( ) ;
const uint8_t * orig_pkt = pkt ;
uint8_t nh = IPV6_GET_ NH( p) ; /* careful, 0 is actually a real type */
uint8_t nh = IPV6_GET_ RAW_ NH( i p6h ) ; /* careful, 0 is actually a real type */
uint16_t hdrextlen = 0 ;
uint16_t plen = len ;
char dstopts = 0 ;
@ -213,7 +210,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
if ( ip6rh_type = = 0 ) {
ENGINE_SET_EVENT ( p , IPV6_EXTHDR_RH_TYPE_0 ) ;
}
p - > ip6eh. rh_type = ip6rh_type ;
p - > l3. vars . ip6. eh. rh_type = ip6rh_type ;
nh = * pkt ;
pkt + = hdrextlen ;
@ -404,7 +401,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
* a defragmented packet without the frag header */
if ( exthdr_fh_done = = 0 ) {
DEBUG_VALIDATE_BUG_ON ( pkt - orig_pkt > UINT16_MAX ) ;
p - > ip6eh. fh_offset = ( uint16_t ) ( pkt - orig_pkt ) ;
p - > l3. vars . ip6. eh. fh_offset = ( uint16_t ) ( pkt - orig_pkt ) ;
exthdr_fh_done = 1 ;
}
@ -439,7 +436,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
* parse this packet further right away , no defrag will be
* needed . It is a useless FH then though , so we do set an
* decoder event . */
if ( p - > ip6eh. fh_more_frags_set = = 0 & & p - > ip6eh. fh_offset = = 0 ) {
if ( p - > l3. vars . ip6. eh. fh_more_frags_set = = 0 & & p - > l3. vars . ip6. eh. fh_offset = = 0 ) {
ENGINE_SET_EVENT ( p , IPV6_EXTHDR_USELESS_FH ) ;
nh = * pkt ;
@ -447,7 +444,7 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
plen - = hdrextlen ;
break ;
}
if ( p - > ip6eh. fh_more_frags_set ! = 0 & & plen % 8 ! = 0 ) {
if ( p - > l3. vars . ip6. eh. fh_more_frags_set ! = 0 & & plen % 8 ! = 0 ) {
// cf https://datatracker.ietf.org/doc/html/rfc2460#section-4.5
// each, except possibly the last ("rightmost") one,
// being an integer multiple of 8 octets long.
@ -535,30 +532,30 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
SCReturn ;
}
static int DecodeIPV6Packet ( ThreadVars * tv , DecodeThreadVars * dtv , Packet * p , const uint8_t * pkt , uint16_t len )
static const IPV6Hdr * DecodeIPV6Packet (
ThreadVars * tv , DecodeThreadVars * dtv , Packet * p , const uint8_t * pkt , uint16_t len )
{
if ( unlikely ( len < IPV6_HEADER_LEN ) ) {
return - 1 ;
return NULL ;
}
if ( unlikely ( IP_GET_RAW_VER ( pkt ) ! = 6 ) ) {
SCLogDebug ( " wrong ip version %d " , IP_GET_RAW_VER ( pkt ) ) ;
ENGINE_SET_INVALID_EVENT ( p , IPV6_WRONG_IP_VER ) ;
return - 1 ;
return NULL ;
}
p - > ip6h = ( IPV6Hdr * ) pkt ;
const IPV6Hdr * ip6h = PacketSetIPV6 ( p , pkt ) ;
if ( unlikely ( len < ( IPV6_HEADER_LEN + IPV6_GET_PLEN ( p ) ) ) )
{
if ( unlikely ( len < ( IPV6_HEADER_LEN + IPV6_GET_RAW_PLEN ( ip6h ) ) ) ) {
ENGINE_SET_INVALID_EVENT ( p , IPV6_TRUNC_PKT ) ;
return - 1 ;
return NULL ;
}
SET_IPV6_SRC_ADDR ( p, & p - > src ) ;
SET_IPV6_DST_ADDR ( p, & p - > dst ) ;
SET_IPV6_SRC_ADDR ( i p6h , & p - > src ) ;
SET_IPV6_DST_ADDR ( i p6h , & p - > dst ) ;
return 0 ;
return ip6h ;
}
int DecodeIPV6 ( ThreadVars * tv , DecodeThreadVars * dtv , Packet * p , const uint8_t * pkt , uint16_t len )
@ -569,12 +566,12 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *
return TM_ECODE_FAILED ;
}
/* do the actual decoding */
int ret = DecodeIPV6Packet ( tv , dtv , p , pkt , len ) ;
if ( unlikely ( ret < 0 ) ) {
CLEAR_IPV6_PACKET ( p ) ;
const IPV6Hdr * ip6h = DecodeIPV6Packet ( tv , dtv , p , pkt , len ) ;
if ( unlikely ( ip6h = = NULL ) ) {
PacketClearL3 ( p ) ;
return TM_ECODE_FAILED ;
}
p - > proto = IPV6_GET_ NH( p) ;
p - > proto = IPV6_GET_ RAW_ NH( i p6h ) ;
# ifdef DEBUG
if ( SCLogDebugEnabled ( ) ) { /* only convert the addresses if debug is really enabled */
@ -582,17 +579,17 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *
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 ) ) ;
SCLogDebug ( " IPV6 %s->%s - CLASS: % " PRIu32 " FLOW: % " PRIu32 " NH: % " PRIu32
" PLEN: % " PRIu32 " HLIM: % " PRIu32 " " ,
s , d , IPV6_GET_RAW_CLASS ( ip6h ) , IPV6_GET_RAW_FLOW ( ip6h ) , IPV6_GET_RAW_NH ( ip6h ) ,
IPV6_GET_RAW_PLEN ( ip6h ) , IPV6_GET_RAW_HLIM ( ip6h ) ) ;
}
# endif /* DEBUG */
const uint8_t * data = pkt + IPV6_HEADER_LEN ;
const uint16_t data_len = IPV6_GET_ PLEN( p) ;
const uint16_t data_len = IPV6_GET_ RAW_ PLEN( i p6h ) ;
/* now process the Ext headers and/or the L4 Layer */
switch ( IPV6_GET_ NH( p) ) {
switch ( IPV6_GET_ RAW_ NH( i p6h ) ) {
case IPPROTO_TCP :
IPV6_SET_L4PROTO ( p , IPPROTO_TCP ) ;
DecodeTCP ( tv , dtv , p , data , data_len ) ;
@ -630,14 +627,14 @@ int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *
case IPPROTO_MH :
case IPPROTO_HIP :
case IPPROTO_SHIM6 :
DecodeIPV6ExtHdrs ( tv , dtv , p , data, data_len ) ;
DecodeIPV6ExtHdrs ( tv , dtv , p , ip6h, data, data_len ) ;
break ;
case IPPROTO_ICMP :
ENGINE_SET_EVENT ( p , IPV6_WITH_ICMPV4 ) ;
break ;
default :
ENGINE_SET_EVENT ( p , IPV6_UNKNOWN_NEXT_HEADER ) ;
IPV6_SET_L4PROTO ( p , IPV6_GET_ NH( p) ) ;
IPV6_SET_L4PROTO ( p , IPV6_GET_ RAW_ NH( i p6h ) ) ;
break ;
}
p - > proto = IPV6_GET_L4PROTO ( p ) ;
@ -855,7 +852,7 @@ static int DecodeIPV6RouteTest01 (void)
DecodeIPV6 ( & tv , & dtv , p1 , GET_PKT_DATA ( p1 ) , GET_PKT_LEN ( p1 ) ) ;
FAIL_IF ( ! ( IPV6_EXTHDR_ISSET_RH ( p1 ) ) ) ;
FAIL_IF ( p1 - > ip6eh. rh_type ! = 0 ) ;
FAIL_IF ( p1 - > l3. vars . ip6. eh. rh_type ! = 0 ) ;
PacketRecycle ( p1 ) ;
SCFree ( p1 ) ;
FlowShutdown ( ) ;