suricata
decode-udp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  *
30  * Decode UDP
31  */
32 
33 #include "suricata-common.h"
34 #include "decode.h"
35 #include "decode-geneve.h"
36 #include "decode-udp.h"
37 #include "decode-teredo.h"
38 #include "decode-vxlan.h"
39 #include "decode-events.h"
40 #include "util-debug.h"
41 #include "flow.h"
42 #include "app-layer.h"
43 
44 static int DecodeUDPPacket(ThreadVars *t, Packet *p, const uint8_t *pkt, uint16_t len)
45 {
46  if (unlikely(len < UDP_HEADER_LEN)) {
48  return -1;
49  }
50 
51  const UDPHdr *udph = PacketSetUDP(p, pkt);
52 
53  if (unlikely(len < UDP_GET_RAW_LEN(udph))) {
55  return -1;
56  }
57 
60  return -1;
61  }
62 
63  p->sp = UDP_GET_RAW_SRC_PORT(udph);
64  p->dp = UDP_GET_RAW_DST_PORT(udph);
65 
66  p->payload = (uint8_t *)pkt + UDP_HEADER_LEN;
68 
69  p->proto = IPPROTO_UDP;
70 
71  return 0;
72 }
73 
75  const uint8_t *pkt, uint16_t len)
76 {
78 
79  if (unlikely(DecodeUDPPacket(tv, p, pkt,len) < 0)) {
80  PacketClearL4(p);
81  return TM_ECODE_FAILED;
82  }
83 
84  SCLogDebug("UDP sp: %u -> dp: %u - HLEN: %" PRIu32 " LEN: %" PRIu32 "", p->sp, p->dp,
86 
89  /* Here we have a Teredo packet and don't need to handle app
90  * layer */
92  return TM_ECODE_OK;
93  }
94 
95  /* Handle Geneve if configured */
98  /* Here we have a Geneve packet and don't need to handle app
99  * layer */
101  return TM_ECODE_OK;
102  }
103 
104  /* Handle VXLAN if configured */
107  /* Here we have a VXLAN packet and don't need to handle app
108  * layer */
110  return TM_ECODE_OK;
111  }
112 
114 
115  return TM_ECODE_OK;
116 }
117 
118 #ifdef UNITTESTS
119 static int UDPV4CalculateValidChecksumtest01(void)
120 {
121  uint16_t csum = 0;
122 
123  uint8_t raw_ipshdr[] = {
124  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
125 
126  uint8_t raw_udp[] = {
127  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
128  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
129  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
130  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
131  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
132  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
133  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
134  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
135  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
136  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
137  0x67, 0x6c, 0x65, 0xc0, 0x26};
138 
139  csum = *( ((uint16_t *)raw_udp) + 3);
140 
141  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
142  (uint16_t *)raw_udp, sizeof(raw_udp), csum) != 0);
143  PASS;
144 }
145 
146 static int UDPV4CalculateInvalidChecksumtest02(void)
147 {
148  uint16_t csum = 0;
149 
150  uint8_t raw_ipshdr[] = {
151  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
152 
153  uint8_t raw_udp[] = {
154  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
155  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
156  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
157  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
158  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
159  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
160  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
161  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
162  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
163  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
164  0x67, 0x6c, 0x65, 0xc0, 0x27};
165 
166  csum = *( ((uint16_t *)raw_udp) + 3);
167 
168  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
169  (uint16_t *)raw_udp, sizeof(raw_udp), csum) == 0);
170  PASS;
171 }
172 
173 static int UDPV6CalculateValidChecksumtest03(void)
174 {
175  uint16_t csum = 0;
176 
177  static uint8_t raw_ipv6[] = {
178  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
179  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
180  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
181  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
182  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
183  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
184  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
185  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
186  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
187  0x09, 0x00};
188 
189  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
190 
191  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
192  (uint16_t *)(raw_ipv6 + 54), 20, csum) != 0);
193  PASS;
194 }
195 
196 static int UDPV6CalculateInvalidChecksumtest04(void)
197 {
198  uint16_t csum = 0;
199 
200  static uint8_t raw_ipv6[] = {
201  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
202  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
203  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
204  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
205  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
206  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
207  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
208  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
209  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
210  0x09, 0x01};
211 
212  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
213 
214  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
215  (uint16_t *)(raw_ipv6 + 54), 20, csum) == 0);
216  PASS;
217 }
218 #endif /* UNITTESTS */
219 
221 {
222 #ifdef UNITTESTS
223  UtRegisterTest("UDPV4CalculateValidChecksumtest01",
224  UDPV4CalculateValidChecksumtest01);
225  UtRegisterTest("UDPV4CalculateInvalidChecksumtest02",
226  UDPV4CalculateInvalidChecksumtest02);
227  UtRegisterTest("UDPV6CalculateValidChecksumtest03",
228  UDPV6CalculateValidChecksumtest03);
229  UtRegisterTest("UDPV6CalculateInvalidChecksumtest04",
230  UDPV6CalculateInvalidChecksumtest04);
231 #endif /* UNITTESTS */
232 }
233 /**
234  * @}
235  */
UDP_GET_RAW_DST_PORT
#define UDP_GET_RAW_DST_PORT(udph)
Definition: decode-udp.h:32
Packet_::proto
uint8_t proto
Definition: decode.h:538
DecodeUDPV4RegisterTests
void DecodeUDPV4RegisterTests(void)
Definition: decode-udp.c:220
len
uint8_t len
Definition: app-layer-dnp3.h:2
decode-vxlan.h
DecodeUDP
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-udp.c:74
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
UDP_HLEN_TOO_SMALL
@ UDP_HLEN_TOO_SMALL
Definition: decode-events.h:108
Packet_::payload
uint8_t * payload
Definition: decode.h:620
decode-udp.h
UDP_PKT_TOO_SMALL
@ UDP_PKT_TOO_SMALL
Definition: decode-events.h:107
p
Packet * p
Definition: fuzz_dataset.c:30
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:621
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
DecodeGeneveEnabledForPort
bool DecodeGeneveEnabledForPort(const uint16_t sp, const uint16_t dp)
Definition: decode-geneve.c:90
decode.h
DecodeGeneve
int DecodeGeneve(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-geneve.c:184
util-debug.h
UDP_GET_RAW_LEN
#define UDP_GET_RAW_LEN(udph)
Definition: decode-udp.h:30
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
UDP_GET_RAW_SRC_PORT
#define UDP_GET_RAW_SRC_PORT(udph)
Definition: decode-udp.h:31
DecodeThreadVars_::counter_udp
StatsCounterId counter_udp
Definition: decode.h:1018
DecodeTeredoEnabledForPort
bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp)
Definition: decode-teredo.c:57
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
Packet_::sp
Port sp
Definition: decode.h:523
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:163
Packet_
Definition: decode.h:516
decode-teredo.h
DecodeVXLAN
int DecodeVXLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-vxlan.c:143
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
suricata-common.h
DecodeVXLANEnabledForPort
bool DecodeVXLANEnabledForPort(const uint16_t dp)
Definition: decode-vxlan.c:67
UDPHdr_
Definition: decode-udp.h:42
decode-geneve.h
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:995
UDP_LEN_INVALID
@ UDP_LEN_INVALID
Definition: decode-events.h:110
UDP_HEADER_LEN
#define UDP_HEADER_LEN
Definition: decode-udp.h:27
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1239
likely
#define likely(expr)
Definition: util-optimize.h:32
flow.h
Packet_::dp
Port dp
Definition: decode.h:531
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:120
FlowSetupPacket
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to indicate workers should do a flow look...
Definition: flow-hash.c:531
DecodeTeredo
int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Function to decode Teredo packets.
Definition: decode-teredo.c:127
app-layer.h