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