suricata
decode-ppp.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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-validate.h"
41 #include "util-unittest.h"
42 #include "util-debug.h"
43 
45  const uint8_t *pkt, uint32_t len)
46 {
47  DEBUG_VALIDATE_BUG_ON(pkt == NULL);
48 
50 
51  if (unlikely(len < PPP_HEADER_LEN)) {
53  return TM_ECODE_FAILED;
54  }
55  if (!PacketIncreaseCheckLayers(p)) {
56  return TM_ECODE_FAILED;
57  }
58 
59  p->ppph = (PPPHdr *)pkt;
60 
61  SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRIu32 "",
62  p, pkt, SCNtohs(p->ppph->protocol), len);
63 
64  switch (SCNtohs(p->ppph->protocol))
65  {
66  case PPP_VJ_UCOMP:
69  p->ppph = NULL;
70  return TM_ECODE_FAILED;
71  }
72 
73  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
74  return TM_ECODE_FAILED;
75  }
76 
77  if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
78  return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN);
79  } else
80  return TM_ECODE_FAILED;
81  break;
82 
83  case PPP_IP:
86  p->ppph = NULL;
87  return TM_ECODE_FAILED;
88  }
89  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
90  return TM_ECODE_FAILED;
91  }
92 
93  return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN);
94 
95  /* PPP IPv6 was not tested */
96  case PPP_IPV6:
99  p->ppph = NULL;
100  return TM_ECODE_FAILED;
101  }
102  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
103  return TM_ECODE_FAILED;
104  }
105 
106  return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN);
107 
108  case PPP_VJ_COMP:
109  case PPP_IPX:
110  case PPP_OSI:
111  case PPP_NS:
112  case PPP_DECNET:
113  case PPP_APPLE:
114  case PPP_BRPDU:
115  case PPP_STII:
116  case PPP_VINES:
117  case PPP_HELLO:
118  case PPP_LUXCOM:
119  case PPP_SNS:
120  case PPP_MPLS_UCAST:
121  case PPP_MPLS_MCAST:
122  case PPP_IPCP:
123  case PPP_OSICP:
124  case PPP_NSCP:
125  case PPP_DECNETCP:
126  case PPP_APPLECP:
127  case PPP_IPXCP:
128  case PPP_STIICP:
129  case PPP_VINESCP:
130  case PPP_IPV6CP:
131  case PPP_MPLSCP:
132  case PPP_LCP:
133  case PPP_PAP:
134  case PPP_LQM:
135  case PPP_CHAP:
137  return TM_ECODE_OK;
138 
139  default:
140  SCLogDebug("unknown PPP protocol: %" PRIx32 "",SCNtohs(p->ppph->protocol));
142  return TM_ECODE_OK;
143  }
144 
145 }
146 
147 /* TESTS BELOW */
148 #ifdef UNITTESTS
149 
150 /* DecodePPPtest01
151  * Decode malformed ip layer PPP packet
152  * Expected test value: 1
153  */
154 static int DecodePPPtest01 (void)
155 {
156  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00 };
157  Packet *p = PacketGetFromAlloc();
158  if (unlikely(p == NULL))
159  return 0;
160  ThreadVars tv;
162 
163  memset(&tv, 0, sizeof(ThreadVars));
164  memset(&dtv, 0, sizeof(DecodeThreadVars));
165 
166  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
167 
168  /* Function my returns here with expected value */
169 
171  SCFree(p);
172  return 1;
173  }
174 
175  SCFree(p);
176  return 0;
177 }
178 
179 /* DecodePPPtest02
180  * Decode malformed ppp layer packet
181  * Expected test value: 1
182  */
183 static int DecodePPPtest02 (void)
184 {
185  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0xff, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
186  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
187  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
188  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
189  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
190  Packet *p = PacketGetFromAlloc();
191  if (unlikely(p == NULL))
192  return 0;
193  ThreadVars tv;
195 
196  memset(&tv, 0, sizeof(ThreadVars));
197  memset(&dtv, 0, sizeof(DecodeThreadVars));
198 
199  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
200 
201  /* Function must returns here */
202 
204  SCFree(p);
205  return 1;
206  }
207 
208  SCFree(p);
209  return 0;
210 }
211 
212 /** DecodePPPtest03
213  * \brief Decode good PPP packet, additionally the IPv4 packet inside is
214  * 4 bytes short.
215  * \retval 0 Test failed
216  * \retval 1 Test succeeded
217  */
218 static int DecodePPPtest03 (void)
219 {
220  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
221  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
222  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
223  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
224  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
225  Packet *p = PacketGetFromAlloc();
226  if (unlikely(p == NULL))
227  return 0;
228  ThreadVars tv;
230 
231  memset(&tv, 0, sizeof(ThreadVars));
232  memset(&dtv, 0, sizeof(DecodeThreadVars));
233 
235 
236  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
237 
238  FlowShutdown();
239 
240  if(p->ppph == NULL) {
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 
261  SCFree(p);
262  return 0;
263  }
264  /* Function must return here */
265 
266  SCFree(p);
267  return 1;
268 }
269 
270 
271 /* DecodePPPtest04
272  * Check if ppp header is null
273  * Expected test value: 1
274  */
275 
276 static int DecodePPPtest04 (void)
277 {
278  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
279  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
280  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
281  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
282  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
283  Packet *p = PacketGetFromAlloc();
284  if (unlikely(p == NULL))
285  return 0;
286  ThreadVars tv;
288 
289  memset(&tv, 0, sizeof(ThreadVars));
290  memset(&dtv, 0, sizeof(DecodeThreadVars));
291 
293 
294  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
295 
296  FlowShutdown();
297 
298  if(p->ppph == NULL) {
299  SCFree(p);
300  return 0;
301  }
302 
304  SCFree(p);
305  return 0;
306  }
307 
308  /* Function must returns here */
309 
310  SCFree(p);
311  return 1;
312 }
313 #endif /* UNITTESTS */
314 
316 {
317 #ifdef UNITTESTS
318  UtRegisterTest("DecodePPPtest01", DecodePPPtest01);
319  UtRegisterTest("DecodePPPtest02", DecodePPPtest02);
320  UtRegisterTest("DecodePPPtest03", DecodePPPtest03);
321  UtRegisterTest("DecodePPPtest04", DecodePPPtest04);
322 #endif /* UNITTESTS */
323 }
324 
325 /**
326  * @}
327  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1036
PPP_MPLS_MCAST
#define PPP_MPLS_MCAST
Definition: decode-ppp.h:47
PPP_UNSUP_PROTO
@ PPP_UNSUP_PROTO
Definition: decode-events.h:119
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:44
PPPVJU_PKT_TOO_SMALL
@ PPPVJU_PKT_TOO_SMALL
Definition: decode-events.h:115
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:1051
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
PPP_WRONG_TYPE
@ PPP_WRONG_TYPE
Definition: decode-events.h:118
PPP_NSCP
#define PPP_NSCP
Definition: decode-ppp.h:50
DecodePPPRegisterTests
void DecodePPPRegisterTests(void)
Definition: decode-ppp.c:315
PPP_VINES
#define PPP_VINES
Definition: decode-ppp.h:42
PPP_IP
#define PPP_IP
Definition: decode-ppp.h:28
PPP_PKT_TOO_SMALL
@ PPP_PKT_TOO_SMALL
Definition: decode-events.h:114
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
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
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:523
PPPIPV4_PKT_TOO_SMALL
@ PPPIPV4_PKT_TOO_SMALL
Definition: decode-events.h:116
decode.h
util-debug.h
PPP_STIICP
#define PPP_STIICP
Definition: decode-ppp.h:54
PPPIPV6_PKT_TOO_SMALL
@ PPPIPV6_PKT_TOO_SMALL
Definition: decode-events.h:117
PPP_IPX
#define PPP_IPX
Definition: decode-ppp.h:35
DecodeThreadVars_::counter_ppp
uint16_t counter_ppp
Definition: decode.h:666
decode-ppp.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PPP_IPCP
#define PPP_IPCP
Definition: decode-ppp.h:48
PPP_VJ_COMP
#define PPP_VJ_COMP
Definition: decode-ppp.h:34
IPV4_TRUNC_PKT
@ IPV4_TRUNC_PKT
Definition: decode-events.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:414
DecodeIPV6
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv6.c:570
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:543
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:651
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
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:151
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:638
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:1044
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
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
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
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