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-udp.h"
36 #include "decode-teredo.h"
37 #include "decode-vxlan.h"
38 #include "decode-events.h"
39 #include "util-unittest.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  p->udph = (UDPHdr *)pkt;
52 
53  if (unlikely(len < UDP_GET_LEN(p))) {
55  return -1;
56  }
57 
58  if (unlikely(len != UDP_GET_LEN(p))) {
60  return -1;
61  }
62 
63  SET_UDP_SRC_PORT(p,&p->sp);
64  SET_UDP_DST_PORT(p,&p->dp);
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)) {
81  return TM_ECODE_FAILED;
82  }
83 
84  SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "",
86 
87  if (DecodeTeredoEnabledForPort(p->sp, p->dp) &&
89  /* Here we have a Teredo packet and don't need to handle app
90  * layer */
91  FlowSetupPacket(p);
92  return TM_ECODE_OK;
93  }
94 
95  /* Handle VXLAN if configured */
96  if (DecodeVXLANEnabledForPort(p->sp, p->dp) &&
98  /* Here we have a VXLAN packet and don't need to handle app
99  * layer */
100  FlowSetupPacket(p);
101  return TM_ECODE_OK;
102  }
103 
104  FlowSetupPacket(p);
105 
106  return TM_ECODE_OK;
107 }
108 
109 #ifdef UNITTESTS
110 static int UDPV4CalculateValidChecksumtest01(void)
111 {
112  uint16_t csum = 0;
113 
114  uint8_t raw_ipshdr[] = {
115  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
116 
117  uint8_t raw_udp[] = {
118  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
119  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
120  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
121  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
122  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
123  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
124  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
125  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
126  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
127  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
128  0x67, 0x6c, 0x65, 0xc0, 0x26};
129 
130  csum = *( ((uint16_t *)raw_udp) + 3);
131 
132  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
133  (uint16_t *)raw_udp, sizeof(raw_udp), csum) != 0);
134  PASS;
135 }
136 
137 static int UDPV4CalculateInvalidChecksumtest02(void)
138 {
139  uint16_t csum = 0;
140 
141  uint8_t raw_ipshdr[] = {
142  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
143 
144  uint8_t raw_udp[] = {
145  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
146  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
147  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
148  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
149  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
150  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
151  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
152  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
153  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
154  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
155  0x67, 0x6c, 0x65, 0xc0, 0x27};
156 
157  csum = *( ((uint16_t *)raw_udp) + 3);
158 
159  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
160  (uint16_t *)raw_udp, sizeof(raw_udp), csum) == 0);
161  PASS;
162 }
163 
164 static int UDPV6CalculateValidChecksumtest03(void)
165 {
166  uint16_t csum = 0;
167 
168  static uint8_t raw_ipv6[] = {
169  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
170  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
171  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
172  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
173  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
174  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
175  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
176  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
177  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
178  0x09, 0x00};
179 
180  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
181 
182  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
183  (uint16_t *)(raw_ipv6 + 54), 20, csum) != 0);
184  PASS;
185 }
186 
187 static int UDPV6CalculateInvalidChecksumtest04(void)
188 {
189  uint16_t csum = 0;
190 
191  static uint8_t raw_ipv6[] = {
192  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
193  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
194  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
195  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
196  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
197  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
198  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
199  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
200  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
201  0x09, 0x01};
202 
203  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
204 
205  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
206  (uint16_t *)(raw_ipv6 + 54), 20, csum) == 0);
207  PASS;
208 }
209 #endif /* UNITTESTS */
210 
212 {
213 #ifdef UNITTESTS
214  UtRegisterTest("UDPV4CalculateValidChecksumtest01",
215  UDPV4CalculateValidChecksumtest01);
216  UtRegisterTest("UDPV4CalculateInvalidChecksumtest02",
217  UDPV4CalculateInvalidChecksumtest02);
218  UtRegisterTest("UDPV6CalculateValidChecksumtest03",
219  UDPV6CalculateValidChecksumtest03);
220  UtRegisterTest("UDPV6CalculateInvalidChecksumtest04",
221  UDPV6CalculateInvalidChecksumtest04);
222 #endif /* UNITTESTS */
223 }
224 /**
225  * @}
226  */
Packet_::proto
uint8_t proto
Definition: decode.h:433
DecodeUDPV4RegisterTests
void DecodeUDPV4RegisterTests(void)
Definition: decode-udp.c:211
len
uint8_t len
Definition: app-layer-dnp3.h:2
decode-vxlan.h
UDP_GET_SRC_PORT
#define UDP_GET_SRC_PORT(p)
Definition: decode-udp.h:36
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
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:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Packet_::payload
uint8_t * payload
Definition: decode.h:543
decode-udp.h
DecodeVXLANEnabledForPort
bool DecodeVXLANEnabledForPort(const uint16_t sp, const uint16_t dp)
Definition: decode-vxlan.c:50
SET_UDP_DST_PORT
#define SET_UDP_DST_PORT(pkt, prt)
Definition: decode.h:199
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:544
util-unittest.h
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:78
UDP_HLEN_INVALID
@ UDP_HLEN_INVALID
Definition: decode-events.h:105
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DecodeTeredoEnabledForPort
bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp)
Definition: decode-teredo.c:50
SET_UDP_SRC_PORT
#define SET_UDP_SRC_PORT(pkt, prt)
Definition: decode.h:196
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
Packet_::sp
Port sp
Definition: decode.h:418
UDP_HLEN_TOO_SMALL
@ UDP_HLEN_TOO_SMALL
Definition: decode-events.h:104
Packet_
Definition: decode.h:411
decode-teredo.h
DecodeVXLAN
int DecodeVXLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-vxlan.c:119
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
UDP_GET_DST_PORT
#define UDP_GET_DST_PORT(p)
Definition: decode-udp.h:37
UDP_GET_LEN
#define UDP_GET_LEN(p)
Definition: decode-udp.h:35
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
suricata-common.h
DecodeThreadVars_::counter_udp
uint16_t counter_udp
Definition: decode.h:642
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:625
Packet_::udph
UDPHdr * udph
Definition: decode.h:527
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:989
CLEAR_UDP_PACKET
#define CLEAR_UDP_PACKET(p)
Definition: decode-udp.h:49
UDP_PKT_TOO_SMALL
@ UDP_PKT_TOO_SMALL
Definition: decode-events.h:103
likely
#define likely(expr)
Definition: util-optimize.h:32
flow.h
Packet_::dp
Port dp
Definition: decode.h:426
FlowSetupPacket
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to incidate workers should do a flow look...
Definition: flow-hash.c:408
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:122
app-layer.h