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-unittest.h"
42 #include "util-debug.h"
43 
44 int DecodeETag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
45 {
46  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
47 
49 
50  if (len < ETAG_HEADER_LEN) {
52  return TM_ECODE_FAILED;
53  }
54 
55  if (!PacketIncreaseCheckLayers(p)) {
56  return TM_ECODE_FAILED;
57  }
58 
59  const ETagHdr *etag_hdr = (const ETagHdr *)pkt;
60 
61  uint16_t proto = SCNtohs(etag_hdr->protocol);
62 
63  if (DecodeNetworkLayer(tv, dtv, proto, p, pkt + ETAG_HEADER_LEN, len - ETAG_HEADER_LEN) ==
64  false) {
66  return TM_ECODE_FAILED;
67  }
68 
69  return TM_ECODE_OK;
70 }
71 
72 #ifdef UNITTESTS
73 #include "util-unittest-helper.h"
74 #include "packet.h"
75 
76 /**
77  * \test DecodeETagTest01 test if etag header is too small.
78  */
79 static int DecodeETagTest01(void)
80 {
81  uint8_t raw_etag[] = { 0x00, 0x20, 0x08 };
83  FAIL_IF_NULL(p);
84 
85  ThreadVars tv = { 0 };
86  DecodeThreadVars dtv = { 0 };
87 
88  FAIL_IF(TM_ECODE_OK == DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
89 
91 
92  PacketFree(p);
93  PASS;
94 }
95 
96 /**
97  * \test DecodeETagTest02 test if etag header has unknown type.
98  */
99 static int DecodeETagTest02(void)
100 {
101  uint8_t raw_etag[] = { 0x10, 0x00, 0x00, 0xd8, 0x00, 0x00, 0xFF, 0x00, 0x45, 0x00, 0x00, 0x34,
102  0x3B, 0x09, 0x40, 0x00, 0x7F, 0x06, 0x2E, 0x3A, 0xC0, 0xA8, 0x01, 0x2C, 0xC0, 0xA8, 0x10,
103  0x04, 0x00, 0x19, 0x29, 0x2B, 0x3E, 0xE9, 0x31, 0x81, 0x20, 0x04, 0x4B, 0x9A, 0x80, 0x10,
104  0x3E, 0xB8, 0x8E, 0x3C, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0A, 0x5F, 0x3E, 0xE4, 0xAA, 0x63,
105  0x0E, 0x6B, 0x03, 0x07, 0x69 };
106 
107  Packet *p = PacketGetFromAlloc();
108  FAIL_IF_NULL(p);
109 
110  ThreadVars tv = { 0 };
111  DecodeThreadVars dtv = { 0 };
112 
113  FAIL_IF_NOT(TM_ECODE_OK != DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
114 
116 
117  PacketFree(p);
118  PASS;
119 }
120 
121 /**
122  * \test DecodeETagTest03 test a good etag header.
123  */
124 static int DecodeETagTest03(void)
125 {
126  uint8_t raw_etag[] = { 0x10, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34,
127  0x3B, 0x09, 0x40, 0x00, 0x7F, 0x06, 0x2E, 0x3A, 0xC0, 0xA8, 0x01, 0x2C, 0xC0, 0xA8, 0x10,
128  0x04, 0x00, 0x19, 0x29, 0x2B, 0x3E, 0xE9, 0x31, 0x81, 0x20, 0x04, 0x4B, 0x9A, 0x80, 0x10,
129  0x3E, 0xB8, 0x8E, 0x3C, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0A, 0x5F, 0x3E, 0xE4, 0xAA, 0x63,
130  0x0E, 0x6B, 0x03, 0x07, 0x69 };
131 
132  Packet *p = PacketGetFromAlloc();
133  FAIL_IF_NULL(p);
134 
135  ThreadVars tv = { 0 };
136  DecodeThreadVars dtv = { 0 };
137 
139 
140  FAIL_IF(TM_ECODE_OK != DecodeETag(&tv, &dtv, p, raw_etag, sizeof(raw_etag)));
141 
142  PacketRecycle(p);
143  FlowShutdown();
144  PacketFree(p);
145  PASS;
146 }
147 
148 #endif /* UNITTESTS */
149 
151 {
152 #ifdef UNITTESTS
153  UtRegisterTest("DecodeETagTest01", DecodeETagTest01);
154  UtRegisterTest("DecodeETagTest02", DecodeETagTest02);
155  UtRegisterTest("DecodeETagTest03", DecodeETagTest03);
156 #endif
157 }
158 
159 /**
160  * @}
161  */
DecodeETagRegisterTests
void DecodeETagRegisterTests(void)
Definition: decode-etag.c:150
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
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ENGINE_ISSET_EVENT
#define ENGINE_ISSET_EVENT(p, e)
Definition: decode.h:1201
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:151
proto
uint8_t proto
Definition: decode-template.h:0
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
util-unittest.h
ETAG_UNKNOWN_TYPE
@ ETAG_UNKNOWN_TYPE
Definition: decode-events.h:164
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:547
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:44
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:219
Packet_
Definition: decode.h:501
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
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:431
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:691
packet.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
DecodeThreadVars_::counter_etag
uint16_t counter_etag
Definition: decode.h:1006
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:258
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:963
decode-etag.h
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1196
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
ETAG_HEADER_TOO_SMALL
@ ETAG_HEADER_TOO_SMALL
Definition: decode-events.h:163
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102