suricata
app-layer-enip.c
Go to the documentation of this file.
1 /* Copyright (C) 2015 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  * \file
20  *
21  * \author Kevin Wong <kwong@solananetworks.com>
22  *
23  * App-layer parser for ENIP protocol
24  *
25  */
26 
27 #include "suricata-common.h"
28 
29 #include "util-debug.h"
30 #include "util-byte.h"
31 #include "util-enum.h"
32 #include "util-mem.h"
33 #include "util-misc.h"
34 
35 #include "stream.h"
36 
37 #include "app-layer-protos.h"
38 #include "app-layer-parser.h"
39 #include "app-layer-enip.h"
40 #include "app-layer-enip-common.h"
41 
42 #include "app-layer-detect-proto.h"
43 
44 #include "conf.h"
45 #include "decode.h"
46 
47 #include "detect-parse.h"
48 #include "detect-engine.h"
49 #include "util-byte.h"
50 #include "util-unittest.h"
51 #include "util-unittest-helper.h"
52 #include "pkt-var.h"
53 #include "util-profiling.h"
54 
55 
57  { NULL, -1 },
58 };
59 
60 /** \brief get value for 'complete' status in ENIP
61  *
62  * For ENIP we use a simple bool.
63  */
64 static int ENIPGetAlstateProgress(void *tx, uint8_t direction)
65 {
66  return 1;
67 }
68 
69 /** \brief get value for 'complete' status in ENIP
70  *
71  * For ENIP we use a simple bool.
72  */
73 static int ENIPGetAlstateProgressCompletionStatus(uint8_t direction)
74 {
75  return 1;
76 }
77 
78 static DetectEngineState *ENIPGetTxDetectState(void *vtx)
79 {
80  ENIPTransaction *tx = (ENIPTransaction *)vtx;
81  return tx->de_state;
82 }
83 
84 static int ENIPSetTxDetectState(void *vtx, DetectEngineState *s)
85 {
86  ENIPTransaction *tx = (ENIPTransaction *)vtx;
87  tx->de_state = s;
88  return 0;
89 }
90 
91 static AppLayerTxData *ENIPGetTxData(void *vtx)
92 {
93  ENIPTransaction *tx = (ENIPTransaction *)vtx;
94  return &tx->tx_data;
95 }
96 
97 static void *ENIPGetTx(void *alstate, uint64_t tx_id)
98 {
99  ENIPState *enip = (ENIPState *) alstate;
100  ENIPTransaction *tx = NULL;
101 
102  if (enip->curr && enip->curr->tx_num == tx_id + 1)
103  return enip->curr;
104 
105  TAILQ_FOREACH(tx, &enip->tx_list, next) {
106  if (tx->tx_num != (tx_id+1))
107  continue;
108 
109  SCLogDebug("returning tx %p", tx);
110  return tx;
111  }
112 
113  return NULL;
114 }
115 
116 static uint64_t ENIPGetTxCnt(void *alstate)
117 {
118  return ((uint64_t) ((ENIPState *) alstate)->transaction_max);
119 }
120 
121 static AppLayerDecoderEvents *ENIPGetEvents(void *tx)
122 {
123  return ((ENIPTransaction *)tx)->decoder_events;
124 }
125 
126 static int ENIPStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type)
127 {
128  *event_id = SCMapEnumNameToValue(event_name, enip_decoder_event_table);
129 
130  if (*event_id == -1) {
131  SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in "
132  "enip's enum map table.", event_name);
133  /* yes this is fatal */
134  return -1;
135  }
136 
137  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
138 
139  return 0;
140 }
141 
142 static int ENIPStateGetEventInfoById(int event_id, const char **event_name,
143  AppLayerEventType *event_type)
144 {
145  *event_name = SCMapEnumValueToName(event_id, enip_decoder_event_table);
146  if (*event_name == NULL) {
147  SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%d\" not present in "
148  "enip's enum map table.", event_id);
149  /* yes this is fatal */
150  return -1;
151  }
152 
153  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
154 
155  return 0;
156 }
157 
158 /** \brief Allocate enip state
159  *
160  * return state
161  */
162 static void *ENIPStateAlloc(void *orig_state, AppProto proto_orig)
163 {
164  SCLogDebug("ENIPStateAlloc");
165  void *s = SCMalloc(sizeof(ENIPState));
166  if (unlikely(s == NULL))
167  return NULL;
168 
169  memset(s, 0, sizeof(ENIPState));
170 
171  ENIPState *enip_state = (ENIPState *) s;
172 
173  TAILQ_INIT(&enip_state->tx_list);
174  return s;
175 }
176 
177 /** \internal
178  * \brief Free a ENIP TX
179  * \param tx ENIP TX to free */
180 static void ENIPTransactionFree(ENIPTransaction *tx, ENIPState *state)
181 {
182  SCEnter();
183  SCLogDebug("ENIPTransactionFree");
184  CIPServiceEntry *svc = NULL;
185  while ((svc = TAILQ_FIRST(&tx->service_list)))
186  {
187  TAILQ_REMOVE(&tx->service_list, svc, next);
188 
189  SegmentEntry *seg = NULL;
190  while ((seg = TAILQ_FIRST(&svc->segment_list)))
191  {
192  TAILQ_REMOVE(&svc->segment_list, seg, next);
193  SCFree(seg);
194  }
195 
196  AttributeEntry *attr = NULL;
197  while ((attr = TAILQ_FIRST(&svc->attrib_list)))
198  {
199  TAILQ_REMOVE(&svc->attrib_list, attr, next);
200  SCFree(attr);
201  }
202 
203  SCFree(svc);
204  }
205 
207 
208  if (tx->de_state != NULL)
209  {
211 
212  state->tx_with_detect_state_cnt--;
213  }
214 
215  if (state->iter == tx)
216  state->iter = NULL;
217 
218  SCFree(tx);
219  SCReturn;
220 }
221 
222 /** \brief Free enip state
223  *
224  */
225 static void ENIPStateFree(void *s)
226 {
227  SCEnter();
228  SCLogDebug("ENIPStateFree");
229  if (s)
230  {
231  ENIPState *enip_state = (ENIPState *) s;
232 
233  ENIPTransaction *tx = NULL;
234  while ((tx = TAILQ_FIRST(&enip_state->tx_list)))
235  {
236  TAILQ_REMOVE(&enip_state->tx_list, tx, next);
237  ENIPTransactionFree(tx, enip_state);
238  }
239 
240  if (enip_state->buffer != NULL)
241  {
242  SCFree(enip_state->buffer);
243  }
244 
245  SCFree(s);
246  }
247  SCReturn;
248 }
249 
250 /** \internal
251  * \brief Allocate a ENIP TX
252  * \retval tx or NULL */
253 static ENIPTransaction *ENIPTransactionAlloc(ENIPState *state)
254 {
255  SCLogDebug("ENIPStateTransactionAlloc");
257  sizeof(ENIPTransaction));
258  if (unlikely(tx == NULL))
259  return NULL;
260 
261  state->curr = tx;
262  state->transaction_max++;
263 
264  memset(tx, 0x00, sizeof(ENIPTransaction));
265  TAILQ_INIT(&tx->service_list);
266 
267  tx->enip = state;
268  tx->tx_num = state->transaction_max;
269  tx->service_count = 0;
270 
271  TAILQ_INSERT_TAIL(&state->tx_list, tx, next);
272 
273  return tx;
274 }
275 
276 /**
277  * \brief enip transaction cleanup callback
278  */
279 static void ENIPStateTransactionFree(void *state, uint64_t tx_id)
280 {
281  SCEnter();
282  SCLogDebug("ENIPStateTransactionFree");
283  ENIPState *enip_state = state;
284  ENIPTransaction *tx = NULL;
285  TAILQ_FOREACH(tx, &enip_state->tx_list, next)
286  {
287 
288  if ((tx_id+1) < tx->tx_num)
289  break;
290  else if ((tx_id+1) > tx->tx_num)
291  continue;
292 
293  if (tx == enip_state->curr)
294  enip_state->curr = NULL;
295 
296  if (tx->decoder_events != NULL)
297  {
298  if (tx->decoder_events->cnt <= enip_state->events)
299  enip_state->events -= tx->decoder_events->cnt;
300  else
301  enip_state->events = 0;
302  }
303 
304  TAILQ_REMOVE(&enip_state->tx_list, tx, next);
305  ENIPTransactionFree(tx, state);
306  break;
307  }
308  SCReturn;
309 }
310 
311 /** \internal
312  *
313  * \brief This function is called to retrieve a ENIP
314  *
315  * \param state ENIP state structure for the parser
316  * \param input Input line of the command
317  * \param input_len Length of the request
318  *
319  * \retval 1 when the command is parsed, 0 otherwise
320  */
321 static AppLayerResult ENIPParse(Flow *f, void *state, AppLayerParserState *pstate,
322  const uint8_t *input, uint32_t input_len, void *local_data,
323  const uint8_t flags)
324 {
325  SCEnter();
326  ENIPState *enip = (ENIPState *) state;
327  ENIPTransaction *tx;
328 
329  if (input == NULL && AppLayerParserStateIssetFlag(pstate,
331  {
333  } else if (input == NULL && input_len != 0) {
334  // GAP
336  } else if (input == NULL || input_len == 0)
337  {
339  }
340 
341  while (input_len > 0)
342  {
343  tx = ENIPTransactionAlloc(enip);
344  if (tx == NULL)
346 
347  SCLogDebug("ENIPParse input len %d", input_len);
348  DecodeENIPPDU(input, input_len, tx);
349  uint32_t pkt_len = tx->header.length + sizeof(ENIPEncapHdr);
350  SCLogDebug("ENIPParse packet len %d", pkt_len);
351  if (pkt_len > input_len)
352  {
353  SCLogDebug("Invalid packet length");
354  break;
355  }
356 
357  input += pkt_len;
358  input_len -= pkt_len;
359  //SCLogDebug("remaining %d", input_len);
360 
361  if (input_len < sizeof(ENIPEncapHdr))
362  {
363  //SCLogDebug("Not enough data"); //not enough data for ENIP
364  break;
365  }
366  }
367 
369 }
370 
371 
372 
373 static uint16_t ENIPProbingParser(Flow *f, uint8_t direction,
374  const uint8_t *input, uint32_t input_len, uint8_t *rdir)
375 {
376  // SCLogDebug("ENIPProbingParser %d", input_len);
377  if (input_len < sizeof(ENIPEncapHdr))
378  {
379  SCLogDebug("length too small to be a ENIP header");
380  return ALPROTO_UNKNOWN;
381  }
382  uint16_t cmd;
383  uint32_t status;
384  int ret = ByteExtractUint16(&cmd, BYTE_LITTLE_ENDIAN, sizeof(uint16_t),
385  (const uint8_t *) (input));
386  if(ret < 0) {
387  return ALPROTO_FAILED;
388  }
389  //ok for all the known commands
390  switch(cmd) {
391  case NOP:
392  case LIST_SERVICES:
393  case LIST_IDENTITY:
394  case LIST_INTERFACES:
395  case REGISTER_SESSION:
396  case UNREGISTER_SESSION:
397  case SEND_RR_DATA:
398  case SEND_UNIT_DATA:
399  case INDICATE_STATUS:
400  case CANCEL:
401  ret = ByteExtractUint32(&status, BYTE_LITTLE_ENDIAN,
402  sizeof(uint32_t),
403  (const uint8_t *) (input + 8));
404  if(ret < 0) {
405  return ALPROTO_FAILED;
406  }
407  switch(status) {
408  case SUCCESS:
409  case INVALID_CMD:
410  case NO_RESOURCES:
411  case INCORRECT_DATA:
412  case INVALID_SESSION:
413  case INVALID_LENGTH:
415  case ENCAP_HEADER_ERROR:
416  return ALPROTO_ENIP;
417  }
418  }
419  return ALPROTO_FAILED;
420 }
421 
422 /**
423  * \brief Function to register the ENIP protocol parsers and other functions
424  */
426 {
427  SCEnter();
428  const char *proto_name = "enip";
429 
430  if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name))
431  {
433 
434  if (RunmodeIsUnittests())
435  {
436  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
437  0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
438 
439  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
440  0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
441 
442  } else
443  {
444  if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
445  proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
446  ENIPProbingParser, ENIPProbingParser))
447  {
448  SCLogDebug(
449  "no ENIP UDP config found enabling ENIP detection on port 44818.");
450 
451  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
453  ENIPProbingParser, NULL);
454 
455  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
457  ENIPProbingParser, NULL);
458  }
459  }
460 
461  } else
462  {
463  SCLogConfig("Protocol detection and parser disabled for %s protocol.",
464  proto_name);
465  return;
466  }
467 
468  if (AppLayerParserConfParserEnabled("udp", proto_name))
469  {
471  STREAM_TOSERVER, ENIPParse);
473  STREAM_TOCLIENT, ENIPParse);
474 
476  ENIPStateAlloc, ENIPStateFree);
477 
478  AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetEvents);
479 
481  ENIPGetTxDetectState, ENIPSetTxDetectState);
482 
483  AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTx);
484  AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxData);
485  AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxCnt);
486  AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateTransactionFree);
487 
488  AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetAlstateProgress);
489  AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_ENIP, ENIPGetAlstateProgressCompletionStatus);
490 
491  AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateGetEventInfo);
492  AppLayerParserRegisterGetEventInfoById(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateGetEventInfoById);
493 
498  } else
499  {
500  SCLogInfo(
501  "Parsed disabled for %s protocol. Protocol detection" "still on.",
502  proto_name);
503  }
504 
505 #ifdef UNITTESTS
507 #endif
508 
509  SCReturn;
510 }
511 
512 /**
513  * \brief Function to register the ENIP protocol parsers and other functions
514  */
516 {
517  SCEnter();
518  const char *proto_name = "enip";
519 
520  if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name))
521  {
523 
524  if (RunmodeIsUnittests())
525  {
526  AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
527  0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
528 
529  AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
530  0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
531 
532  } else
533  {
534  if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
535  proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
536  ENIPProbingParser, ENIPProbingParser))
537  {
538  return;
539  }
540  }
541 
542  } else
543  {
544  SCLogDebug("Protocol detection and parser disabled for %s protocol.",
545  proto_name);
546  return;
547  }
548 
549  if (AppLayerParserConfParserEnabled("tcp", proto_name))
550  {
552  STREAM_TOSERVER, ENIPParse);
554  STREAM_TOCLIENT, ENIPParse);
556  ENIPStateAlloc, ENIPStateFree);
557 
558  AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetEvents);
559 
561  ENIPGetTxDetectState, ENIPSetTxDetectState);
562 
563  AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTx);
564  AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxData);
565  AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxCnt);
566  AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPStateTransactionFree);
567 
568  AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetAlstateProgress);
569  AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_ENIP, ENIPGetAlstateProgressCompletionStatus);
570 
571  AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_ENIP, ENIPStateGetEventInfo);
572 
575 
576  /* This parser accepts gaps. */
579 
582  } else
583  {
584  SCLogConfig("Parser disabled for %s protocol. Protocol detection still on.",
585  proto_name);
586  }
587 
588 #ifdef UNITTESTS
590 #endif
591 
592  SCReturn;
593 }
594 
595 /* UNITTESTS */
596 #ifdef UNITTESTS
597 #include "app-layer-parser.h"
598 #include "detect-parse.h"
599 #include "detect-engine.h"
600 #include "flow-util.h"
601 #include "stream-tcp.h"
602 #include "util-unittest.h"
603 #include "util-unittest-helper.h"
604 
605 static uint8_t listIdentity[] = {/* List ID */ 0x63, 0x00,
606  /* Length */ 0x00, 0x00,
607  /* Session */ 0x00, 0x00, 0x00, 0x00,
608  /* Status */ 0x00, 0x00, 0x00, 0x00,
609  /* Delay*/ 0x00,
610  /* Context */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611  /* Quantity of coils */ 0x00, 0x00, 0x00, 0x00, 0x00};
612 
613 /**
614  * \brief Test if ENIP Packet matches signature
615  */
616 static int ALDecodeENIPTest(void)
617 {
619  Flow f;
620  TcpSession ssn;
621 
622  memset(&f, 0, sizeof(f));
623  memset(&ssn, 0, sizeof(ssn));
624 
625  f.protoctx = (void *)&ssn;
626  f.proto = IPPROTO_TCP;
627  f.alproto = ALPROTO_ENIP;
628 
630 
632  listIdentity, sizeof(listIdentity));
633  FAIL_IF(r != 0);
634 
635  ENIPState *enip_state = f.alstate;
636  FAIL_IF_NULL(enip_state);
637 
638  ENIPTransaction *tx = ENIPGetTx(enip_state, 0);
639  FAIL_IF_NULL(tx);
640 
641  FAIL_IF(tx->header.command != 99);
642 
645  FLOW_DESTROY(&f);
646 
647  PASS;
648 }
649 
650 #endif /* UNITTESTS */
651 
653 {
654 #ifdef UNITTESTS
655  UtRegisterTest("ALDecodeENIPTest", ALDecodeENIPTest);
656 #endif /* UNITTESTS */
657 }
util-byte.h
SEND_RR_DATA
#define SEND_RR_DATA
Definition: app-layer-enip-common.h:39
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:475
AppLayerProtoDetectPPParseConfPorts
int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, uint8_t ipproto, const char *alproto_name, AppProto alproto, uint16_t min_depth, uint16_t max_depth, ProbingParserFPtr ProbingParserTs, ProbingParserFPtr ProbingParserTc)
Definition: app-layer-detect-proto.c:1699
LIST_SERVICES
#define LIST_SERVICES
Definition: app-layer-enip-common.h:34
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SegmentEntry_
Definition: app-layer-enip-common.h:158
enip_decoder_event_table
SCEnumCharMap enip_decoder_event_table[]
Definition: app-layer-enip.c:56
AppLayerParserRegisterOptionFlags
void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto, uint32_t flags)
Definition: app-layer-parser.c:382
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:370
ByteExtractUint16
int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:164
flow-util.h
INVALID_LENGTH
#define INVALID_LENGTH
Definition: app-layer-enip-common.h:57
DetectEngineState_
Definition: detect-engine-state.h:92
stream-tcp.h
ALPROTO_ENIP
@ ALPROTO_ENIP
Definition: app-layer-protos.h:43
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ENIPState_
Per flow ENIP state container.
Definition: app-layer-enip-common.h:218
ENIPState_::events
uint16_t events
Definition: app-layer-enip-common.h:225
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SEND_UNIT_DATA
#define SEND_UNIT_DATA
Definition: app-layer-enip-common.h:40
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DecodeENIPPDU
int DecodeENIPPDU(const uint8_t *input, uint32_t input_len, ENIPTransaction *enip_data)
Decode ENIP Encapsulation Header.
Definition: app-layer-enip-common.c:185
Flow_::proto
uint8_t proto
Definition: flow.h:365
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:73
AppLayerParserConfParserEnabled
int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name)
check if a parser is enabled in the config Returns enabled always if: were running unittests
Definition: app-layer-parser.c:301
Flow_
Flow data structure.
Definition: flow.h:347
AppLayerEventType
enum AppLayerEventType_ AppLayerEventType
AppLayerParserRegisterGetEventsFunc
void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, AppLayerDecoderEvents *(*StateGetEvents)(void *))
Definition: app-layer-parser.c:436
AppLayerParserRegisterParserAcceptableDataDirection
void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction)
Definition: app-layer-parser.c:371
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:486
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
NOP
#define NOP
Definition: app-layer-enip-common.h:33
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:278
INVALID_CMD
#define INVALID_CMD
Definition: app-layer-enip-common.h:53
AppLayerDecoderEventsFreeEvents
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events)
Definition: app-layer-events.c:148
AppLayerParserRegisterDetectStateFuncs
void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, DetectEngineState *(*GetTxDetectState)(void *tx), int(*SetTxDetectState)(void *tx, DetectEngineState *))
Definition: app-layer-parser.c:562
ENIPTransaction_::tx_num
uint16_t tx_num
Definition: app-layer-enip-common.h:198
REGISTER_SESSION
#define REGISTER_SESSION
Definition: app-layer-enip-common.h:37
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:385
LIST_INTERFACES
#define LIST_INTERFACES
Definition: app-layer-enip-common.h:36
LIST_IDENTITY
#define LIST_IDENTITY
Definition: app-layer-enip-common.h:35
CANCEL
#define CANCEL
Definition: app-layer-enip-common.h:42
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:41
Flow_::protoctx
void * protoctx
Definition: flow.h:441
INCORRECT_DATA
#define INCORRECT_DATA
Definition: app-layer-enip-common.h:55
AppLayerDecoderEvents_
Data structure to store app layer decoder events.
Definition: app-layer-events.h:34
util-unittest.h
ENIPEncapHdr_::command
uint16_t command
Definition: app-layer-enip-common.h:102
APP_LAYER_EVENT_TYPE_TRANSACTION
@ APP_LAYER_EVENT_TYPE_TRANSACTION
Definition: app-layer-events.h:57
AttributeEntry_
Definition: app-layer-enip-common.h:166
util-unittest-helper.h
CIPServiceEntry_
Definition: app-layer-enip-common.h:173
INVALID_SESSION
#define INVALID_SESSION
Definition: app-layer-enip-common.h:56
AppLayerProtoDetectPPRegister
void AppLayerProtoDetectPPRegister(uint8_t ipproto, const char *portstr, AppProto alproto, uint16_t min_depth, uint16_t max_depth, uint8_t direction, ProbingParserFPtr ProbingParser1, ProbingParserFPtr ProbingParser2)
register parser at a port
Definition: app-layer-detect-proto.c:1665
app-layer-detect-proto.h
AppLayerParserStateIssetFlag
int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
Definition: app-layer-parser.c:1648
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:412
decode.h
util-debug.h
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:339
AppLayerParserState_
Definition: app-layer-parser.c:154
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
ENCAP_HEADER_ERROR
#define ENCAP_HEADER_ERROR
Definition: app-layer-enip-common.h:60
ENIPTransaction_::enip
struct ENIPState_ * enip
Definition: app-layer-enip-common.h:197
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:19
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
RegisterENIPTCPParsers
void RegisterENIPTCPParsers(void)
Function to register the ENIP protocol parsers and other functions.
Definition: app-layer-enip.c:515
ByteExtractUint32
int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:143
pkt-var.h
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void(*StateFree)(void *))
Definition: app-layer-parser.c:398
APP_LAYER_PARSER_OPT_UNIDIR_TXS
#define APP_LAYER_PARSER_OPT_UNIDIR_TXS
Definition: app-layer-parser.h:46
ENIPEncapHdr_
Definition: app-layer-enip-common.h:97
app-layer-parser.h
TRUE
#define TRUE
Definition: suricata-common.h:33
AppLayerDecoderEvents_::cnt
uint8_t cnt
Definition: app-layer-events.h:38
util-profiling.h
SCReturn
#define SCReturn
Definition: util-debug.h:302
stream.h
AppLayerParserRegisterProtocolUnittests
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
Definition: app-layer-parser.c:1746
ENIPState_::buffer
uint8_t * buffer
Definition: app-layer-enip-common.h:231
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:668
APP_LAYER_PARSER_EOF_TC
#define APP_LAYER_PARSER_EOF_TC
Definition: app-layer-parser.h:42
conf.h
ENIPTransaction_::tx_data
AppLayerTxData tx_data
Definition: app-layer-enip-common.h:213
AppLayerParserRegisterGetEventInfo
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type))
Definition: app-layer-parser.c:550
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1875
ENIPParserRegisterTests
void ENIPParserRegisterTests(void)
Definition: app-layer-enip.c:652
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:264
INDICATE_STATUS
#define INDICATE_STATUS
Definition: app-layer-enip-common.h:41
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:217
AppLayerParserRegisterParser
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
Definition: app-layer-parser.c:359
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:175
AppLayerParserRegisterGetStateProgressCompletionStatus
void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto, int(*StateGetProgressCompletionStatus)(uint8_t direction))
Definition: app-layer-parser.c:527
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:252
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:508
ENIPState_::iter
ENIPTransaction * iter
Definition: app-layer-enip-common.h:221
ENIPTransaction_
Definition: app-layer-enip-common.h:196
util-mem.h
NO_RESOURCES
#define NO_RESOURCES
Definition: app-layer-enip-common.h:54
APP_LAYER_OK
#define APP_LAYER_OK
Definition: app-layer-parser.h:60
BYTE_LITTLE_ENDIAN
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
app-layer-enip.h
SCMapEnumValueToName
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
Maps an enum value to a string name, from the supplied table.
Definition: util-enum.c:68
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:320
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
SCMapEnumNameToValue
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
Definition: util-enum.c:40
flags
uint8_t flags
Definition: decode-gre.h:0
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1203
suricata-common.h
SCEnumCharMap_
Definition: util-enum.h:27
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
RegisterENIPUDPParsers
void RegisterENIPUDPParsers(void)
Function to register the ENIP protocol parsers and other functions.
Definition: app-layer-enip.c:425
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:574
ENIPState_::curr
ENIPTransaction * curr
Definition: app-layer-enip-common.h:220
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
ENIPTransaction_::decoder_events
AppLayerDecoderEvents * decoder_events
Definition: app-layer-enip-common.h:209
APP_LAYER_PARSER_OPT_ACCEPT_GAPS
#define APP_LAYER_PARSER_OPT_ACCEPT_GAPS
Definition: app-layer-parser.h:45
ENIPTransaction_::de_state
DetectEngineState * de_state
Definition: app-layer-enip-common.h:212
UNSUPPORTED_PROT_REV
#define UNSUPPORTED_PROT_REV
Definition: app-layer-enip-common.h:58
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ENIPTransaction_::service_count
uint16_t service_count
Definition: app-layer-enip-common.h:200
ENIPEncapHdr
struct ENIPEncapHdr_ ENIPEncapHdr
Flow_::alstate
void * alstate
Definition: flow.h:476
detect-parse.h
AppLayerParserRegisterGetEventInfoById
void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfoById)(int event_id, const char **event_name, AppLayerEventType *event_type))
Definition: app-layer-parser.c:538
app-layer-enip-common.h
ENIPState_::tx_with_detect_state_cnt
uint64_t tx_with_detect_state_cnt
Definition: app-layer-enip-common.h:223
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:63
ENIPEncapHdr_::length
uint16_t length
Definition: app-layer-enip-common.h:103
app-layer-protos.h
ENIPState_::transaction_max
uint64_t transaction_max
Definition: app-layer-enip-common.h:222
AppLayerParserRegisterGetTxCnt
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
Definition: app-layer-parser.c:497
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:64
SC_ERR_INVALID_ENUM_MAP
@ SC_ERR_INVALID_ENUM_MAP
Definition: util-error.h:45
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:87
TcpSession_
Definition: stream-tcp-private.h:260
util-misc.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
ENIPTransaction_::header
ENIPEncapHdr header
Definition: app-layer-enip-common.h:202
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
util-enum.h
AppLayerProtoDetectConfProtoDetectionEnabled
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
Definition: app-layer-detect-proto.c:1938
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:130
UNREGISTER_SESSION
#define UNREGISTER_SESSION
Definition: app-layer-enip-common.h:38
SUCCESS
#define SUCCESS
Definition: app-layer-enip-common.h:52