/**
* Decode/Validate IPv4 Options.
*/
-static void DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Options *opts)
+static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Options *opts)
{
uint16_t plen = len;
/* Option length is too big for packet */
if (unlikely(*(pkt+1) > plen)) {
ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
- return;
+ return -1;
}
IPV4Opt opt = {*pkt, *(pkt+1), plen > 2 ? (pkt + 2) : NULL };
* Also check for invalid lengths 0 and 1. */
if (unlikely(opt.len > plen || opt.len < 2)) {
ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
- return;
+ return -1;
}
/* we are parsing the most commonly used opts to prevent
* us from having to walk the opts list for these all the
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateTimestamp(p, &opt)) {
- return;
+ return 0;
}
opts->o_ts = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_TS;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateRoute(p, &opt) != 0) {
- return;
+ return 0;
}
opts->o_rr = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_RR;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateGeneric(p, &opt)) {
- return;
+ return 0;
}
opts->o_qs = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_QS;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateGeneric(p, &opt)) {
- return;
+ return 0;
}
opts->o_sec = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_SEC;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateRoute(p, &opt) != 0) {
- return;
+ return 0;
}
opts->o_lsrr = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_LSRR;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateCIPSO(p, &opt) != 0) {
- return;
+ return 0;
}
opts->o_cipso = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_CIPSO;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateGeneric(p, &opt)) {
- return;
+ return 0;
}
opts->o_sid = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_SID;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateRoute(p, &opt) != 0) {
- return;
+ return 0;
}
opts->o_ssrr = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_SSRR;
/* Warn - we can keep going */
break;
} else if (IPV4OptValidateGeneric(p, &opt)) {
- return;
+ return 0;
}
opts->o_rtralt = opt;
p->ip4vars.opts_set |= IPV4_OPT_FLAG_RTRALT;
}
}
+ return 0;
}
static int DecodeIPV4Packet(Packet *p, const uint8_t *pkt, uint16_t len)
if (ip_opt_len > 0) {
IPV4Options opts;
memset(&opts, 0x00, sizeof(opts));
- DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts);
+ if (DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts) < 0) {
+ return -1;
+ }
}
return 0;
IPV4Options opts;
memset(&opts, 0x00, sizeof(opts));
- DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
+ FAIL_IF(DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts) != -1);
FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
FAIL_IF(opts.o_rr.type != 0);
SCFree(p);