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, PacketQueue *pq)
45 {
46  StatsIncr(tv, dtv->counter_ppp);
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:
63  if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
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, pq);
75  } else
76  return TM_ECODE_FAILED;
77  break;
78 
79  case PPP_IP:
80  if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
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, pq);
90 
91  /* PPP IPv6 was not tested */
92  case PPP_IPV6:
93  if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
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, pq);
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;
157  DecodeThreadVars dtv;
158 
159  memset(&tv, 0, sizeof(ThreadVars));
160  memset(&dtv, 0, sizeof(DecodeThreadVars));
161 
162  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
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;
190  DecodeThreadVars dtv;
191 
192  memset(&tv, 0, sizeof(ThreadVars));
193  memset(&dtv, 0, sizeof(DecodeThreadVars));
194 
195  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL);
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;
225  DecodeThreadVars dtv;
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), NULL);
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;
283  DecodeThreadVars dtv;
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), NULL);
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  */
#define PPP_VJ_UCOMP
Definition: decode-ppp.h:30
#define PPP_NSCP
Definition: decode-ppp.h:50
int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len, PacketQueue *pq)
Definition: decode-ppp.c:43
#define PPP_HELLO
Definition: decode-ppp.h:43
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:992
#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:1007
#define PPP_OSICP
Definition: decode-ppp.h:49
#define PPP_SNS
Definition: decode-ppp.h:45
#define unlikely(expr)
Definition: util-optimize.h:35
void DecodePPPRegisterTests(void)
Definition: decode-ppp.c:311
#define FLOW_QUIET
Definition: flow.h:38
#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
#define PPP_VINESCP
Definition: decode-ppp.h:55
#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:532
#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:632
#define PPP_MPLSCP
Definition: decode-ppp.h:57
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:168
#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
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv6.c:585
#define IPV6_HEADER_LEN
Definition: decode-ipv6.h:27
uint16_t counter_ppp
Definition: decode.h:657
#define SCFree(a)
Definition: util-mem.h:322
#define SCNtohs(x)
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:532
#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:670
#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:1000
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:141
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:515