suricata
decode-udp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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;
67  p->payload_len = len - UDP_HEADER_LEN;
68 
69  p->proto = IPPROTO_UDP;
70 
71  return 0;
72 }
73 
75  const uint8_t *pkt, uint16_t len, PacketQueue *pq)
76 {
77  StatsIncr(tv, dtv->counter_udp);
78 
79  if (unlikely(DecodeUDPPacket(tv, p, pkt,len) < 0)) {
80  p->udph = NULL;
81  return TM_ECODE_FAILED;
82  }
83 
84  SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "",
86 
87  if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) {
88  /* Here we have a Teredo packet and don't need to handle app
89  * layer */
90  FlowSetupPacket(p);
91  return TM_ECODE_OK;
92  }
93 
94  /* Handle VXLAN if configured */
95  if (DecodeVXLANEnabledForPort(p->sp, p->dp) &&
96  unlikely(DecodeVXLAN(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) {
97  /* Here we have a VXLAN packet and don't need to handle app
98  * layer */
99  FlowSetupPacket(p);
100  return TM_ECODE_OK;
101  }
102 
103  FlowSetupPacket(p);
104 
105  return TM_ECODE_OK;
106 }
107 
108 #ifdef UNITTESTS
109 static int UDPV4CalculateValidChecksumtest01(void)
110 {
111  uint16_t csum = 0;
112 
113  uint8_t raw_ipshdr[] = {
114  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
115 
116  uint8_t raw_udp[] = {
117  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
118  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
119  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
120  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
121  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
122  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
123  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
124  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
125  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
126  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
127  0x67, 0x6c, 0x65, 0xc0, 0x26};
128 
129  csum = *( ((uint16_t *)raw_udp) + 3);
130 
131  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
132  (uint16_t *)raw_udp, sizeof(raw_udp), csum) != 0);
133  PASS;
134 }
135 
136 static int UDPV4CalculateInvalidChecksumtest02(void)
137 {
138  uint16_t csum = 0;
139 
140  uint8_t raw_ipshdr[] = {
141  0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3};
142 
143  uint8_t raw_udp[] = {
144  0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0,
145  0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
146  0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67,
147  0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f,
148  0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69,
149  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63,
150  0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0,
151  0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b,
152  0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65,
153  0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
154  0x67, 0x6c, 0x65, 0xc0, 0x27};
155 
156  csum = *( ((uint16_t *)raw_udp) + 3);
157 
158  FAIL_IF(UDPV4Checksum((uint16_t *) raw_ipshdr,
159  (uint16_t *)raw_udp, sizeof(raw_udp), csum) == 0);
160  PASS;
161 }
162 
163 static int UDPV6CalculateValidChecksumtest03(void)
164 {
165  uint16_t csum = 0;
166 
167  static uint8_t raw_ipv6[] = {
168  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
169  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
170  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
171  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
172  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
173  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
174  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
175  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
176  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
177  0x09, 0x00};
178 
179  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
180 
181  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
182  (uint16_t *)(raw_ipv6 + 54), 20, csum) != 0);
183  PASS;
184 }
185 
186 static int UDPV6CalculateInvalidChecksumtest04(void)
187 {
188  uint16_t csum = 0;
189 
190  static uint8_t raw_ipv6[] = {
191  0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00,
192  0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00,
193  0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe,
194  0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
195  0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
196  0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
197  0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
198  0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02,
199  0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0,
200  0x09, 0x01};
201 
202  csum = *( ((uint16_t *)(raw_ipv6 + 60)));
203 
204  FAIL_IF(UDPV6Checksum((uint16_t *)(raw_ipv6 + 14 + 8),
205  (uint16_t *)(raw_ipv6 + 54), 20, csum) == 0);
206  PASS;
207 }
208 #endif /* UNITTESTS */
209 
211 {
212 #ifdef UNITTESTS
213  UtRegisterTest("UDPV4CalculateValidChecksumtest01",
214  UDPV4CalculateValidChecksumtest01);
215  UtRegisterTest("UDPV4CalculateInvalidChecksumtest02",
216  UDPV4CalculateInvalidChecksumtest02);
217  UtRegisterTest("UDPV6CalculateValidChecksumtest03",
218  UDPV6CalculateValidChecksumtest03);
219  UtRegisterTest("UDPV6CalculateInvalidChecksumtest04",
220  UDPV6CalculateInvalidChecksumtest04);
221 #endif /* UNITTESTS */
222 }
223 /**
224  * @}
225  */
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:407
UDPHdr * udph
Definition: decode.h:524
#define SCLogDebug(...)
Definition: util-debug.h:335
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
void DecodeUDPV4RegisterTests(void)
Definition: decode-udp.c:210
Port sp
Definition: decode.h:415
#define UDP_GET_SRC_PORT(p)
Definition: decode-udp.h:36
Port dp
Definition: decode.h:423
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
#define SET_UDP_DST_PORT(pkt, prt)
Definition: decode.h:196
int DecodeVXLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode-vxlan.c:119
uint8_t proto
Definition: decode.h:430
int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Function to decode Teredo packets.
Definition: decode-teredo.c:63
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
#define SET_UDP_SRC_PORT(pkt, prt)
Definition: decode.h:193
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:168
#define UDP_GET_LEN(p)
Definition: decode-udp.h:35
bool DecodeVXLANEnabledForPort(const uint16_t sp, const uint16_t dp)
Definition: decode-vxlan.c:50
#define UDP_GET_DST_PORT(p)
Definition: decode-udp.h:37
uint16_t counter_udp
Definition: decode.h:649
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-udp.c:74
uint16_t payload_len
Definition: decode.h:541
uint8_t * payload
Definition: decode.h:540
#define UDP_HEADER_LEN
Definition: decode-udp.h:27
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1000