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