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(
79  tv, dtv, p, pkt + PPP_HEADER_LEN, (uint16_t)(len - PPP_HEADER_LEN));
80  } else
81  return TM_ECODE_FAILED;
82  break;
83 
84  case PPP_IP:
87  p->ppph = NULL;
88  return TM_ECODE_FAILED;
89  }
90  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
91  return TM_ECODE_FAILED;
92  }
93 
94  return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, (uint16_t)(len - PPP_HEADER_LEN));
95 
96  /* PPP IPv6 was not tested */
97  case PPP_IPV6:
100  p->ppph = NULL;
101  return TM_ECODE_FAILED;
102  }
103  if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
104  return TM_ECODE_FAILED;
105  }
106 
107  return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, (uint16_t)(len - PPP_HEADER_LEN));
108 
109  case PPP_VJ_COMP:
110  case PPP_IPX:
111  case PPP_OSI:
112  case PPP_NS:
113  case PPP_DECNET:
114  case PPP_APPLE:
115  case PPP_BRPDU:
116  case PPP_STII:
117  case PPP_VINES:
118  case PPP_HELLO:
119  case PPP_LUXCOM:
120  case PPP_SNS:
121  case PPP_MPLS_UCAST:
122  case PPP_MPLS_MCAST:
123  case PPP_IPCP:
124  case PPP_OSICP:
125  case PPP_NSCP:
126  case PPP_DECNETCP:
127  case PPP_APPLECP:
128  case PPP_IPXCP:
129  case PPP_STIICP:
130  case PPP_VINESCP:
131  case PPP_IPV6CP:
132  case PPP_MPLSCP:
133  case PPP_LCP:
134  case PPP_PAP:
135  case PPP_LQM:
136  case PPP_CHAP:
138  return TM_ECODE_OK;
139 
140  default:
141  SCLogDebug("unknown PPP protocol: %" PRIx32 "",SCNtohs(p->ppph->protocol));
143  return TM_ECODE_OK;
144  }
145 
146 }
147 
148 /* TESTS BELOW */
149 #ifdef UNITTESTS
150 
151 /* DecodePPPtest01
152  * Decode malformed ip layer PPP packet
153  * Expected test value: 1
154  */
155 static int DecodePPPtest01 (void)
156 {
157  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00 };
158  Packet *p = PacketGetFromAlloc();
159  if (unlikely(p == NULL))
160  return 0;
161  ThreadVars tv;
163 
164  memset(&tv, 0, sizeof(ThreadVars));
165  memset(&dtv, 0, sizeof(DecodeThreadVars));
166 
167  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
168 
169  /* Function my returns here with expected value */
170 
172  SCFree(p);
173  return 1;
174  }
175 
176  SCFree(p);
177  return 0;
178 }
179 
180 /* DecodePPPtest02
181  * Decode malformed ppp layer packet
182  * Expected test value: 1
183  */
184 static int DecodePPPtest02 (void)
185 {
186  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0xff, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
187  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
188  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
189  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
190  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
191  Packet *p = PacketGetFromAlloc();
192  if (unlikely(p == NULL))
193  return 0;
194  ThreadVars tv;
196 
197  memset(&tv, 0, sizeof(ThreadVars));
198  memset(&dtv, 0, sizeof(DecodeThreadVars));
199 
200  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
201 
202  /* Function must returns here */
203 
205  SCFree(p);
206  return 1;
207  }
208 
209  SCFree(p);
210  return 0;
211 }
212 
213 /** DecodePPPtest03
214  * \brief Decode good PPP packet, additionally the IPv4 packet inside is
215  * 4 bytes short.
216  * \retval 0 Test failed
217  * \retval 1 Test succeeded
218  */
219 static int DecodePPPtest03 (void)
220 {
221  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
222  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
223  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
224  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
225  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
226  Packet *p = PacketGetFromAlloc();
227  if (unlikely(p == NULL))
228  return 0;
229  ThreadVars tv;
231 
232  memset(&tv, 0, sizeof(ThreadVars));
233  memset(&dtv, 0, sizeof(DecodeThreadVars));
234 
236 
237  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
238 
239  FlowShutdown();
240 
241  if(p->ppph == NULL) {
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 
262  SCFree(p);
263  return 0;
264  }
265  /* Function must return here */
266 
267  SCFree(p);
268  return 1;
269 }
270 
271 
272 /* DecodePPPtest04
273  * Check if ppp header is null
274  * Expected test value: 1
275  */
276 
277 static int DecodePPPtest04 (void)
278 {
279  uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d,
280  0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01,
281  0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00,
282  0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00,
283  0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 };
284  Packet *p = PacketGetFromAlloc();
285  if (unlikely(p == NULL))
286  return 0;
287  ThreadVars tv;
289 
290  memset(&tv, 0, sizeof(ThreadVars));
291  memset(&dtv, 0, sizeof(DecodeThreadVars));
292 
294 
295  DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp));
296 
297  FlowShutdown();
298 
299  if(p->ppph == NULL) {
300  SCFree(p);
301  return 0;
302  }
303 
305  SCFree(p);
306  return 0;
307  }
308 
309  /* Function must returns here */
310 
311  SCFree(p);
312  return 1;
313 }
314 #endif /* UNITTESTS */
315 
317 {
318 #ifdef UNITTESTS
319  UtRegisterTest("DecodePPPtest01", DecodePPPtest01);
320  UtRegisterTest("DecodePPPtest02", DecodePPPtest02);
321  UtRegisterTest("DecodePPPtest03", DecodePPPtest03);
322  UtRegisterTest("DecodePPPtest04", DecodePPPtest04);
323 #endif /* UNITTESTS */
324 }
325 
326 /**
327  * @}
328  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:880
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:167
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
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:895
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
PPP_NSCP
#define PPP_NSCP
Definition: decode-ppp.h:50
DecodePPPRegisterTests
void DecodePPPRegisterTests(void)
Definition: decode-ppp.c:316
PPP_VINES
#define PPP_VINES
Definition: decode-ppp.h:42
PPP_WRONG_TYPE
@ PPP_WRONG_TYPE
Definition: decode-events.h:118
PPP_IP
#define PPP_IP
Definition: decode-ppp.h:28
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:83
PPP_BRPDU
#define PPP_BRPDU
Definition: decode-ppp.h:40
util-unittest.h
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:82
PPP_LUXCOM
#define PPP_LUXCOM
Definition: decode-ppp.h:44
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
decode.h
util-debug.h
PPPIPV4_PKT_TOO_SMALL
@ PPPIPV4_PKT_TOO_SMALL
Definition: decode-events.h:116
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:687
decode-ppp.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
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
PPPVJU_PKT_TOO_SMALL
@ PPPVJU_PKT_TOO_SMALL
Definition: decode-events.h:115
PPP_UNSUP_PROTO
@ PPP_UNSUP_PROTO
Definition: decode-events.h:119
PPP_MPLSCP
#define PPP_MPLSCP
Definition: decode-ppp.h:57
Packet_
Definition: decode.h:425
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:95
PPP_DECNETCP
#define PPP_DECNETCP
Definition: decode-ppp.h:51
PPPIPV6_PKT_TOO_SMALL
@ PPPIPV6_PKT_TOO_SMALL
Definition: decode-events.h:117
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
IPV4Hdr_
Definition: decode-ipv4.h:72
Packet_::ppph
PPPHdr * ppph
Definition: decode.h:559
PPP_APPLE
#define PPP_APPLE
Definition: decode-ppp.h:39
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:403
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:690
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:32
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:173
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:659
PPP_STII
#define PPP_STII
Definition: decode-ppp.h:41
IPV4_TRUNC_PKT
@ IPV4_TRUNC_PKT
Definition: decode-events.h:34
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:888
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:40
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
PPP_PKT_TOO_SMALL
@ PPP_PKT_TOO_SMALL
Definition: decode-events.h:114
DecodeIPV4
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv4.c:520
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