suricata
decode-etag.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup decode
20  *
21  * @{
22  */
23 
24 /**
25  * \file
26  *
27  * \author Fupeng Zhao <fupeng.zhao@foxmail.com>
28  *
29  * Decode 802.1BR E-Tag headers
30  *
31  * This implementation is based on the following specification doc:
32  * https://www.scribd.com/document/262742673/802-1BR-2012-pdf
33  */
34 
35 #include "suricata-common.h"
36 #include "decode-etag.h"
37 #include "decode.h"
38 #include "decode-events.h"
39 
40 #include "util-validate.h"
41 #include "util-debug.h"
42 
43 int DecodeETag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
44 {
45  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
46 
48 
49  if (len < ETAG_HEADER_LEN) {
51  return TM_ECODE_FAILED;
52  }
53 
54  if (!PacketIncreaseCheckLayers(p)) {
55  return TM_ECODE_FAILED;
56  }
57 
58  const ETagHdr *etag_hdr = (const ETagHdr *)pkt;
59 
60  uint16_t proto = SCNtohs(etag_hdr->protocol);
61 
62  if (DecodeNetworkLayer(tv, dtv, proto, p, pkt + ETAG_HEADER_LEN, len - ETAG_HEADER_LEN) ==
63  false) {
65  return TM_ECODE_FAILED;
66  }
67 
68  return TM_ECODE_OK;
69 }
70 
71 #ifdef UNITTESTS
72 #include "util-unittest-helper.h"
73 #include "packet.h"
74 
75 /**
76  * \test DecodeETagTest01 test if etag header is too small.
77  */
78 static int DecodeETagTest01(void)
79 {
80  uint8_t raw_etag[] = { 0x00, 0x20, 0x08 };
82  FAIL_IF_NULL(p);
83 
84  ThreadVars tv = { 0 };
85  DecodeThreadVars dtv = { 0 };
86 
87  FAIL_IF(TM_ECODE_OK == DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
88 
90 
91  PacketFree(p);
92  PASS;
93 }
94 
95 /**
96  * \test DecodeETagTest02 test if etag header has unknown type.
97  */
98 static int DecodeETagTest02(void)
99 {
100  uint8_t raw_etag[] = { 0x10, 0x00, 0x00, 0xd8, 0x00, 0x00, 0xFF, 0x00, 0x45, 0x00, 0x00, 0x34,
101  0x3B, 0x09, 0x40, 0x00, 0x7F, 0x06, 0x2E, 0x3A, 0xC0, 0xA8, 0x01, 0x2C, 0xC0, 0xA8, 0x10,
102  0x04, 0x00, 0x19, 0x29, 0x2B, 0x3E, 0xE9, 0x31, 0x81, 0x20, 0x04, 0x4B, 0x9A, 0x80, 0x10,
103  0x3E, 0xB8, 0x8E, 0x3C, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0A, 0x5F, 0x3E, 0xE4, 0xAA, 0x63,
104  0x0E, 0x6B, 0x03, 0x07, 0x69 };
105 
107  FAIL_IF_NULL(p);
108 
109  ThreadVars tv = { 0 };
110  DecodeThreadVars dtv = { 0 };
111 
112  FAIL_IF_NOT(TM_ECODE_OK != DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
113 
115 
116  PacketFree(p);
117  PASS;
118 }
119 
120 /**
121  * \test DecodeETagTest03 test a good etag header.
122  */
123 static int DecodeETagTest03(void)
124 {
125  uint8_t raw_etag[] = { 0x10, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
126  0x3B, 0x09, 0x40, 0x00, 0x7F, 0x06, 0x2E, 0x3A, 0xC0, 0xA8, 0x01, 0x2C, 0xC0, 0xA8, 0x10,
127  0x04, 0x00, 0x19, 0x29, 0x2B, 0x3E, 0xE9, 0x31, 0x81, 0x20, 0x04, 0x4B, 0x9A, 0x80, 0x10,
128  0x3E, 0xB8, 0x8E, 0x3C, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0A, 0x5F, 0x3E, 0xE4, 0xAA, 0x63,
129  0x0E, 0x6B, 0x03, 0x07, 0x69 };
130 
132  FAIL_IF_NULL(p);
133 
134  ThreadVars tv = { 0 };
135  DecodeThreadVars dtv = { 0 };
136 
138 
139  FAIL_IF(TM_ECODE_OK != DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
140 
141  PacketRecycle(p);
142  FlowShutdown();
143  PacketFree(p);
144  PASS;
145 }
146 
147 #endif /* UNITTESTS */
148 
150 {
151 #ifdef UNITTESTS
152  UtRegisterTest("DecodeETagTest01", DecodeETagTest01);
153  UtRegisterTest("DecodeETagTest02", DecodeETagTest02);
154  UtRegisterTest("DecodeETagTest03", DecodeETagTest03);
155 #endif
156 }
157 
158 /**
159  * @}
160  */
DecodeETagRegisterTests
void DecodeETagRegisterTests(void)
Definition: decode-etag.c:149
len
uint8_t len
Definition: app-layer-dnp3.h:2
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
ETAG_UNKNOWN_TYPE
@ ETAG_UNKNOWN_TYPE
Definition: decode-events.h:165
ENGINE_ISSET_EVENT
#define ENGINE_ISSET_EVENT(p, e)
Definition: decode.h:1244
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:167
p
Packet * p
Definition: fuzz_dataset.c:30
proto
uint8_t proto
Definition: decode-template.h:0
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
ETAG_HEADER_LEN
#define ETAG_HEADER_LEN
Definition: decode-etag.h:37
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:574
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DecodeETag
int DecodeETag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-etag.c:43
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:163
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:221
Packet_
Definition: decode.h:516
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:35
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:436
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:718
packet.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
ETAG_HEADER_TOO_SMALL
@ ETAG_HEADER_TOO_SMALL
Definition: decode-events.h:164
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:260
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:995
DecodeThreadVars_::counter_etag
StatsCounterId counter_etag
Definition: decode.h:1044
decode-etag.h
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1239
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:120
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109