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