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