suricata
decode-ppp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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 Breno Silva Pinto <breno.silva@gmail.com>
29  *
30  * Decode PPP
31  */
32 
33 #include "suricata-common.h"
34 #include "decode.h"
35 #include "decode-ppp.h"
36 #include "decode-events.h"
37 
38 #include "flow.h"
39 
40 #include "util-unittest.h"
41 #include "util-debug.h"
42 
43 int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
44 {
45  StatsIncr(tv, dtv->counter_ppp);
46 
47  if (unlikely(len < PPP_HEADER_LEN)) {
49  return TM_ECODE_FAILED;
50  }
51 
52  p->ppph = (PPPHdr *)pkt;
53  if (unlikely(p->ppph == NULL))
54  return TM_ECODE_FAILED;
55 
56  SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRIu32 "",
57  p, pkt, SCNtohs(p->ppph->protocol), len);
58 
59  switch (SCNtohs(p->ppph->protocol))
60  {
61  case PPP_VJ_UCOMP:
62  if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
64  p->ppph = NULL;
65  return TM_ECODE_FAILED;
66  }
67 
68  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
69  return TM_ECODE_FAILED;
70  }
71 
72  if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
73  return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
74  } else
75  return TM_ECODE_FAILED;
76  break;
77 
78  case PPP_IP:
79  if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
81  p->ppph = NULL;
82  return TM_ECODE_FAILED;
83  }
84  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
85  return TM_ECODE_FAILED;
86  }
87 
88  return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
89 
90  /* PPP IPv6 was not tested */
91  case PPP_IPV6:
92  if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
94  p->ppph = NULL;
95  return TM_ECODE_FAILED;
96  }
97  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
98  return TM_ECODE_FAILED;
99  }
100 
101  return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
102 
103  case PPP_VJ_COMP:
104  case PPP_IPX:
105  case PPP_OSI:
106  case PPP_NS:
107  case PPP_DECNET:
108  case PPP_APPLE:
109  case PPP_BRPDU:
110  case PPP_STII:
111  case PPP_VINES:
112  case PPP_HELLO:
113  case PPP_LUXCOM:
114  case PPP_SNS:
115  case PPP_MPLS_UCAST:
116  case PPP_MPLS_MCAST:
117  case PPP_IPCP:
118  case PPP_OSICP:
119  case PPP_NSCP:
120  case PPP_DECNETCP:
121  case PPP_APPLECP:
122  case PPP_IPXCP:
123  case PPP_STIICP:
124  case PPP_VINESCP:
125  case PPP_IPV6CP:
126  case PPP_MPLSCP:
127  case PPP_LCP:
128  case PPP_PAP:
129  case PPP_LQM:
130  case PPP_CHAP:
132  return TM_ECODE_OK;
133 
134  default:
135  SCLogDebug("unknown PPP protocol: %" PRIx32 "",SCNtohs(p->ppph->protocol));
137  return TM_ECODE_OK;
138  }
139 
140 }
141 
142 /* TESTS BELOW */
143 #ifdef UNITTESTS
144 
145 /* DecodePPPtest01
146  * Decode malformed ip layer PPP packet
147  * Expected test value: 1
148  */
149 static int DecodePPPtest01 (void)
150 {
151  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00 };
152  Packet *p = PacketGetFromAlloc();
153  if (unlikely(p == NULL))
154  return 0;
155  ThreadVars tv;
156  DecodeThreadVars dtv;
157 
158  memset(&tv, 0, sizeof(ThreadVars));
159  memset(&dtv, 0, sizeof(DecodeThreadVars));
160 
161  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
162 
163  /* Function my returns here with expected value */
164 
166  SCFree(p);
167  return 1;
168  }
169 
170  SCFree(p);
171  return 0;
172 }
173 
174 /* DecodePPPtest02
175  * Decode malformed ppp layer packet
176  * Expected test value: 1
177  */
178 static int DecodePPPtest02 (void)
179 {
180  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0xff, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
181  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
182  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
183  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
184  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
185  Packet *p = PacketGetFromAlloc();
186  if (unlikely(p == NULL))
187  return 0;
188  ThreadVars tv;
189  DecodeThreadVars dtv;
190 
191  memset(&tv, 0, sizeof(ThreadVars));
192  memset(&dtv, 0, sizeof(DecodeThreadVars));
193 
194  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
195 
196  /* Function must returns here */
197 
199  SCFree(p);
200  return 1;
201  }
202 
203  SCFree(p);
204  return 0;
205 }
206 
207 /** DecodePPPtest03
208  * \brief Decode good PPP packet, additionally the IPv4 packet inside is
209  * 4 bytes short.
210  * \retval 0 Test failed
211  * \retval 1 Test succeeded
212  */
213 static int DecodePPPtest03 (void)
214 {
215  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
216  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
217  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
218  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
219  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
220  Packet *p = PacketGetFromAlloc();
221  if (unlikely(p == NULL))
222  return 0;
223  ThreadVars tv;
224  DecodeThreadVars dtv;
225 
226  memset(&tv, 0, sizeof(ThreadVars));
227  memset(&dtv, 0, sizeof(DecodeThreadVars));
228 
230 
231  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
232 
233  FlowShutdown();
234 
235  if(p->ppph == NULL) {
236  SCFree(p);
237  return 0;
238  }
239 
241  SCFree(p);
242  return 0;
243  }
244 
246  SCFree(p);
247  return 0;
248  }
249 
251  SCFree(p);
252  return 0;
253  }
254 
256  SCFree(p);
257  return 0;
258  }
259  /* Function must return here */
260 
261  SCFree(p);
262  return 1;
263 }
264 
265 
266 /* DecodePPPtest04
267  * Check if ppp header is null
268  * Expected test value: 1
269  */
270 
271 static int DecodePPPtest04 (void)
272 {
273  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
274  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
275  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
276  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
277  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
278  Packet *p = PacketGetFromAlloc();
279  if (unlikely(p == NULL))
280  return 0;
281  ThreadVars tv;
282  DecodeThreadVars dtv;
283 
284  memset(&tv, 0, sizeof(ThreadVars));
285  memset(&dtv, 0, sizeof(DecodeThreadVars));
286 
288 
289  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
290 
291  FlowShutdown();
292 
293  if(p->ppph == NULL) {
294  SCFree(p);
295  return 0;
296  }
297 
299  SCFree(p);
300  return 0;
301  }
302 
303  /* Function must returns here */
304 
305  SCFree(p);
306  return 1;
307 }
308 #endif /* UNITTESTS */
309 
311 {
312 #ifdef UNITTESTS
313  UtRegisterTest("DecodePPPtest01", DecodePPPtest01);
314  UtRegisterTest("DecodePPPtest02", DecodePPPtest02);
315  UtRegisterTest("DecodePPPtest03", DecodePPPtest03);
316  UtRegisterTest("DecodePPPtest04", DecodePPPtest04);
317 #endif /* UNITTESTS */
318 }
319 
320 /**
321  * @}
322  */
#define PPP_VJ_UCOMP
Definition: decode-ppp.h:30
#define PPP_NSCP
Definition: decode-ppp.h:50
#define PPP_HELLO
Definition: decode-ppp.h:43
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1000
#define SCLogDebug(...)
Definition: util-debug.h:335
#define PPP_PAP
Definition: decode-ppp.h:59
#define PPP_OSI
Definition: decode-ppp.h:36
#define ENGINE_ISSET_EVENT(p, e)
Definition: decode.h:1015
#define PPP_OSICP
Definition: decode-ppp.h:49
int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode-ppp.c:43
#define PPP_SNS
Definition: decode-ppp.h:45
#define unlikely(expr)
Definition: util-optimize.h:35
void DecodePPPRegisterTests(void)
Definition: decode-ppp.c:310
#define FLOW_QUIET
Definition: flow.h:37
#define PPP_IP
Definition: decode-ppp.h:28
#define PPP_VINES
Definition: decode-ppp.h:42
#define IPV4_GET_RAW_VER(ip4h)
Definition: decode-ipv4.h:94
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:533
#define PPP_VINESCP
Definition: decode-ppp.h:55
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv6.c:584
#define PPP_STIICP
Definition: decode-ppp.h:54
#define PPP_IPX
Definition: decode-ppp.h:35
#define PPP_BRPDU
Definition: decode-ppp.h:40
PPPHdr * ppph
Definition: decode.h:535
#define PPP_LUXCOM
Definition: decode-ppp.h:44
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:642
#define PPP_MPLSCP
Definition: decode-ppp.h:57
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:163
#define PPP_IPCP
Definition: decode-ppp.h:48
#define PPP_VJ_COMP
Definition: decode-ppp.h:34
#define PPP_IPV6
Definition: decode-ppp.h:29
#define IPV6_HEADER_LEN
Definition: decode-ipv6.h:27
uint16_t counter_ppp
Definition: decode.h:669
#define SCFree(a)
Definition: util-mem.h:236
#define SCNtohs(x)
#define PPP_DECNETCP
Definition: decode-ppp.h:51
#define PPP_NS
Definition: decode-ppp.h:37
#define PPP_MPLS_UCAST
Definition: decode-ppp.h:46
#define PPP_STII
Definition: decode-ppp.h:41
#define PPP_DECNET
Definition: decode-ppp.h:38
#define PPP_CHAP
Definition: decode-ppp.h:61
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:599
#define PPP_APPLE
Definition: decode-ppp.h:39
#define PPP_IPV6CP
Definition: decode-ppp.h:56
#define PPP_APPLECP
Definition: decode-ppp.h:52
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define PPP_IPXCP
Definition: decode-ppp.h:53
#define PPP_MPLS_MCAST
Definition: decode-ppp.h:47
#define likely(expr)
Definition: util-optimize.h:32
#define IPV4_HEADER_LEN
Definition: decode-ipv4.h:28
#define PPP_LQM
Definition: decode-ppp.h:60
#define PPP_HEADER_LEN
Definition: decode-ppp.h:71
#define PPP_LCP
Definition: decode-ppp.h:58
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1008
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:140
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:444