From: Sascha Steinbiss Date: Thu, 22 Sep 2022 13:10:47 +0000 (+0200) Subject: decode-ipv4: implement extended security option X-Git-Tag: suricata-7.0.0-beta1~154 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb790121bb2805190c033953ffd4e9dfa09b565b;p=thirdparty%2Fsuricata.git decode-ipv4: implement extended security option IP option 0x85 (extended security) is mentioned in the documentation for the ipopts keyword but was not implemented. --- diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index e472ca281b..71c41d5a96 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -66,6 +66,7 @@ static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o) break; /* See: RFC 1108 */ case IPV4_OPT_SEC: + case IPV4_OPT_ESEC: if (o->len != IPV4_OPT_SEC_LEN) { ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); return -1; @@ -290,6 +291,7 @@ typedef struct IPV4Options_ { IPV4Opt o_ts; IPV4Opt o_sec; IPV4Opt o_lsrr; + IPV4Opt o_esec; IPV4Opt o_cipso; IPV4Opt o_sid; IPV4Opt o_ssrr; @@ -415,6 +417,15 @@ static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Op p->ip4vars.opts_set |= IPV4_OPT_FLAG_LSRR; } break; + case IPV4_OPT_ESEC: + if (opts->o_esec.type != 0) { + ENGINE_SET_EVENT(p, IPV4_OPT_DUPLICATE); + /* Warn - we can keep going */ + } else if (IPV4OptValidateGeneric(p, &opt) == 0) { + opts->o_esec = opt; + p->ip4vars.opts_set |= IPV4_OPT_FLAG_ESEC; + } + break; case IPV4_OPT_CIPSO: if (opts->o_cipso.type != 0) { ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); @@ -912,6 +923,40 @@ static int DecodeIPV4OptionsSECTest02(void) PASS; } +/** \test IPV4 with ESEC option. */ +static int DecodeIPV4OptionsESECTest01(void) +{ + uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + Packet *p = PacketGetFromAlloc(); + FAIL_IF(unlikely(p == NULL)); + + IPV4Options opts; + memset(&opts, 0x00, sizeof(opts)); + DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts); + FAIL_IF(p->flags & PKT_IS_INVALID); + FAIL_IF(opts.o_esec.type != IPV4_OPT_ESEC); + SCFree(p); + PASS; +} + +/** \test IPV4 with ESEC option (invalid length). */ +static int DecodeIPV4OptionsESECTest02(void) +{ + uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + Packet *p = PacketGetFromAlloc(); + FAIL_IF(unlikely(p == NULL)); + + IPV4Options opts; + memset(&opts, 0x00, sizeof(opts)); + DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts); + FAIL_IF((p->flags & PKT_IS_INVALID) == 0); + FAIL_IF(opts.o_esec.type != 0); + SCFree(p); + PASS; +} + /** \test IPV4 with LSRR option. */ static int DecodeIPV4OptionsLSRRTest01(void) { @@ -1665,6 +1710,8 @@ void DecodeIPV4RegisterTests(void) UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04); UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01); UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02); + UtRegisterTest("DecodeIPV4OptionsESECTest01", DecodeIPV4OptionsESECTest01); + UtRegisterTest("DecodeIPV4OptionsESECTest02", DecodeIPV4OptionsESECTest02); UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01); UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02); UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03); diff --git a/src/decode-ipv4.h b/src/decode-ipv4.h index 0da5ab5b8e..3b20eb8fc7 100644 --- a/src/decode-ipv4.h +++ b/src/decode-ipv4.h @@ -37,6 +37,7 @@ #define IPV4_OPT_TS 0x44 /**< Option: Timestamp */ #define IPV4_OPT_SEC 0x82 /**< Option: Security */ #define IPV4_OPT_LSRR 0x83 /**< Option: Loose Source Route */ +#define IPV4_OPT_ESEC 0x85 /**< Option: Extended Security */ #define IPV4_OPT_CIPSO 0x86 /**< Option: Commercial IP Security */ #define IPV4_OPT_SID 0x88 /**< Option: Stream Identifier */ #define IPV4_OPT_SSRR 0x89 /**< Option: Strict Source Route */ @@ -165,6 +166,7 @@ enum IPV4OptionFlags { IPV4_OPT_FLAG_SEC, IPV4_OPT_FLAG_CIPSO, IPV4_OPT_FLAG_RTRALT, + IPV4_OPT_FLAG_ESEC, }; /* helper structure with parsed ipv4 info */ diff --git a/src/detect-ipopts.c b/src/detect-ipopts.c index dac1d24e15..944e1b16d2 100644 --- a/src/detect-ipopts.c +++ b/src/detect-ipopts.c @@ -76,15 +76,46 @@ struct DetectIpOpts_ { const char *ipopt_name; /**< ip option name */ uint16_t code; /**< ip option flag value */ } ipopts[] = { - { "rr", IPV4_OPT_FLAG_RR, }, - { "lsrr", IPV4_OPT_FLAG_LSRR, }, - { "eol", IPV4_OPT_FLAG_EOL, }, - { "nop", IPV4_OPT_FLAG_NOP, }, - { "ts", IPV4_OPT_FLAG_TS, }, - { "sec", IPV4_OPT_FLAG_SEC, }, - { "ssrr", IPV4_OPT_FLAG_SSRR, }, - { "satid", IPV4_OPT_FLAG_SID, }, - { "any", 0xffff, }, + { + "rr", + IPV4_OPT_FLAG_RR, + }, + { + "lsrr", + IPV4_OPT_FLAG_LSRR, + }, + { + "eol", + IPV4_OPT_FLAG_EOL, + }, + { + "nop", + IPV4_OPT_FLAG_NOP, + }, + { + "ts", + IPV4_OPT_FLAG_TS, + }, + { + "sec", + IPV4_OPT_FLAG_SEC, + }, + { + "esec", + IPV4_OPT_FLAG_ESEC, + }, + { + "ssrr", + IPV4_OPT_FLAG_SSRR, + }, + { + "satid", + IPV4_OPT_FLAG_SID, + }, + { + "any", + 0xffff, + }, { NULL, 0 }, };