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 static DetectEngineState *ENIPGetTxDetectState(void *vtx)
70 {
71  ENIPTransaction *tx = (ENIPTransaction *)vtx;
72  return tx->de_state;
73 }
74 
75 static int ENIPSetTxDetectState(void *vtx, DetectEngineState *s)
76 {
77  ENIPTransaction *tx = (ENIPTransaction *)vtx;
78  tx->de_state = s;
79  return 0;
80 }
81 
82 static AppLayerTxData *ENIPGetTxData(void *vtx)
83 {
84  ENIPTransaction *tx = (ENIPTransaction *)vtx;
85  return &tx->tx_data;
86 }
87 
88 static void *ENIPGetTx(void *alstate, uint64_t tx_id)
89 {
90  ENIPState *enip = (ENIPState *) alstate;
91  ENIPTransaction *tx = NULL;
92 
93  if (enip->curr && enip->curr->tx_num == tx_id + 1)
94  return enip->curr;
95 
96  TAILQ_FOREACH(tx, &enip->tx_list, next) {
97  if (tx->tx_num != (tx_id+1))
98  continue;
99 
100  SCLogDebug("returning tx %p", tx);
101  return tx;
102  }
103 
104  return NULL;
105 }
106 
107 static uint64_t ENIPGetTxCnt(void *alstate)
108 {
109  return ((uint64_t) ((ENIPState *) alstate)->transaction_max);
110 }
111 
112 static AppLayerDecoderEvents *ENIPGetEvents(void *tx)
113 {
114  return ((ENIPTransaction *)tx)->decoder_events;
115 }
116 
117 static int ENIPStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type)
118 {
119  *event_id = SCMapEnumNameToValue(event_name, enip_decoder_event_table);
120 
121  if (*event_id == -1) {
122  SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in "
123  "enip's enum map table.", event_name);
124  /* yes this is fatal */
125  return -1;
126  }
127 
128  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
129 
130  return 0;
131 }
132 
133 static int ENIPStateGetEventInfoById(int event_id, const char **event_name,
134  AppLayerEventType *event_type)
135 {
136  *event_name = SCMapEnumValueToName(event_id, enip_decoder_event_table);
137  if (*event_name == NULL) {
138  SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%d\" not present in "
139  "enip's enum map table.", event_id);
140  /* yes this is fatal */
141  return -1;
142  }
143 
144  *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
145 
146  return 0;
147 }
148 
149 /** \brief Allocate enip state
150  *
151  * return state
152  */
153 static void *ENIPStateAlloc(void *orig_state, AppProto proto_orig)
154 {
155  SCLogDebug("ENIPStateAlloc");
156  void *s = SCMalloc(sizeof(ENIPState));
157  if (unlikely(s == NULL))
158  return NULL;
159 
160  memset(s, 0, sizeof(ENIPState));
161 
162  ENIPState *enip_state = (ENIPState *) s;
163 
164  TAILQ_INIT(&enip_state->tx_list);
165  return s;
166 }
167 
168 /** \internal
169  * \brief Free a ENIP TX
170  * \param tx ENIP TX to free */
171 static void ENIPTransactionFree(ENIPTransaction *tx, ENIPState *state)
172 {
173  SCEnter();
174  SCLogDebug("ENIPTransactionFree");
175  CIPServiceEntry *svc = NULL;
176  while ((svc = TAILQ_FIRST(&tx->service_list)))
177  {
178  TAILQ_REMOVE(&tx->service_list, svc, next);
179 
180  SegmentEntry *seg = NULL;
181  while ((seg = TAILQ_FIRST(&svc->segment_list)))
182  {
183  TAILQ_REMOVE(&svc->segment_list, seg, next);
184  SCFree(seg);
185  }
186 
187  AttributeEntry *attr = NULL;
188  while ((attr = TAILQ_FIRST(&svc->attrib_list)))
189  {
190  TAILQ_REMOVE(&svc->attrib_list, attr, next);
191  SCFree(attr);
192  }
193 
194  SCFree(svc);
195  }
196 
198 
199  if (tx->de_state != NULL)
200  {
202 
203  state->tx_with_detect_state_cnt--;
204  }
205 
206  if (state->iter == tx)
207  state->iter = NULL;
208 
209  SCFree(tx);
210  SCReturn;
211 }
212 
213 /** \brief Free enip state
214  *
215  */
216 static void ENIPStateFree(void *s)
217 {
218  SCEnter();
219  SCLogDebug("ENIPStateFree");
220  if (s)
221  {
222  ENIPState *enip_state = (ENIPState *) s;
223 
224  ENIPTransaction *tx = NULL;
225  while ((tx = TAILQ_FIRST(&enip_state->tx_list)))
226  {
227  TAILQ_REMOVE(&enip_state->tx_list, tx, next);
228  ENIPTransactionFree(tx, enip_state);
229  }
230 
231  if (enip_state->buffer != NULL)
232  {
233  SCFree(enip_state->buffer);
234  }
235 
236  SCFree(s);
237  }
238  SCReturn;
239 }
240 
241 /** \internal
242  * \brief Allocate a ENIP TX
243  * \retval tx or NULL */
244 static ENIPTransaction *ENIPTransactionAlloc(ENIPState *state)
245 {
246  SCLogDebug("ENIPStateTransactionAlloc");
248  sizeof(ENIPTransaction));
249  if (unlikely(tx == NULL))
250  return NULL;
251 
252  state->curr = tx;
253  state->transaction_max++;
254 
255  memset(tx, 0x00, sizeof(ENIPTransaction));
256  TAILQ_INIT(&tx->service_list);
257 
258  tx->enip = state;
259  tx->tx_num = state->transaction_max;
260  tx->service_count = 0;
261 
262  TAILQ_INSERT_TAIL(&state->tx_list, tx, next);
263 
264  return tx;
265 }
266 
267 /**
268  * \brief enip transaction cleanup callback
269  */
270 static void ENIPStateTransactionFree(void *state, uint64_t tx_id)
271 {
272  SCEnter();
273  SCLogDebug("ENIPStateTransactionFree");
274  ENIPState *enip_state = state;
275  ENIPTransaction *tx = NULL;
276  TAILQ_FOREACH(tx, &enip_state->tx_list, next)
277  {
278 
279  if ((tx_id+1) < tx->tx_num)
280  break;
281  else if ((tx_id+1) > tx->tx_num)
282  continue;
283 
284  if (tx == enip_state->curr)
285  enip_state->curr = NULL;
286 
287  if (tx->decoder_events != NULL)
288  {
289  if (tx->decoder_events->cnt <= enip_state->events)
290  enip_state->events -= tx->decoder_events->cnt;
291  else
292  enip_state->events = 0;
293  }
294 
295  TAILQ_REMOVE(&enip_state->tx_list, tx, next);
296  ENIPTransactionFree(tx, state);
297  break;
298  }
299  SCReturn;
300 }
301 
302 /** \internal
303  *
304  * \brief This function is called to retrieve a ENIP
305  *
306  * \param state ENIP state structure for the parser
307  * \param input Input line of the command
308  * \param input_len Length of the request
309  *
310  * \retval 1 when the command is parsed, 0 otherwise
311  */
312 static AppLayerResult ENIPParse(Flow *f, void *state, AppLayerParserState *pstate,
313  const uint8_t *input, uint32_t input_len, void *local_data,
314  const uint8_t flags)
315 {
316  SCEnter();
317  ENIPState *enip = (ENIPState *) state;
318  ENIPTransaction *tx;
319 
320  if (input == NULL && AppLayerParserStateIssetFlag(pstate,
322  {
324  } else if (input == NULL && input_len != 0) {
325  // GAP
327  } else if (input == NULL || input_len == 0)
328  {
330  }
331 
332  while (input_len > 0)
333  {
334  tx = ENIPTransactionAlloc(enip);
335  if (tx == NULL)
337 
338  SCLogDebug("ENIPParse input len %d", input_len);
339  DecodeENIPPDU(input, input_len, tx);
340  uint32_t pkt_len = tx->header.length + sizeof(ENIPEncapHdr);
341  SCLogDebug("ENIPParse packet len %d", pkt_len);
342  if (pkt_len > input_len)
343  {
344  SCLogDebug("Invalid packet length");
345  break;
346  }
347 
348  input += pkt_len;
349  input_len -= pkt_len;
350  //SCLogDebug("remaining %d", input_len);
351 
352  if (input_len < sizeof(ENIPEncapHdr))
353  {
354  //SCLogDebug("Not enough data"); //not enough data for ENIP
355  break;
356  }
357  }
358 
360 }
361 
362 #define ENIP_LEN_REGISTER_SESSION 4 // protocol u16, options u16
363 
364 static uint16_t ENIPProbingParser(Flow *f, uint8_t direction,
365  const uint8_t *input, uint32_t input_len, uint8_t *rdir)
366 {
367  // SCLogDebug("ENIPProbingParser %d", input_len);
368  if (input_len < sizeof(ENIPEncapHdr))
369  {
370  SCLogDebug("length too small to be a ENIP header");
371  return ALPROTO_UNKNOWN;
372  }
373  uint16_t cmd;
374  uint16_t enip_len;
375  uint32_t status;
376  uint32_t option;
377  uint16_t nbitems;
378 
379  int ret = ByteExtractUint16(
380  &enip_len, BYTE_LITTLE_ENDIAN, sizeof(uint16_t), (const uint8_t *)(input + 2));
381  if (ret < 0) {
382  return ALPROTO_FAILED;
383  }
384  if (enip_len < sizeof(ENIPEncapHdr)) {
385  return ALPROTO_FAILED;
386  }
387  ret = ByteExtractUint32(
388  &status, BYTE_LITTLE_ENDIAN, sizeof(uint32_t), (const uint8_t *)(input + 8));
389  if (ret < 0) {
390  return ALPROTO_FAILED;
391  }
392  switch (status) {
393  case SUCCESS:
394  case INVALID_CMD:
395  case NO_RESOURCES:
396  case INCORRECT_DATA:
397  case INVALID_SESSION:
398  case INVALID_LENGTH:
400  case ENCAP_HEADER_ERROR:
401  break;
402  default:
403  return ALPROTO_FAILED;
404  }
405  ret = ByteExtractUint16(&cmd, BYTE_LITTLE_ENDIAN, sizeof(uint16_t), (const uint8_t *)(input));
406  if(ret < 0) {
407  return ALPROTO_FAILED;
408  }
409  ret = ByteExtractUint32(
410  &option, BYTE_LITTLE_ENDIAN, sizeof(uint32_t), (const uint8_t *)(input + 20));
411  if (ret < 0) {
412  return ALPROTO_FAILED;
413  }
414 
415  //ok for all the known commands
416  switch(cmd) {
417  case NOP:
418  if (option != 0) {
419  return ALPROTO_FAILED;
420  }
421  break;
422  case REGISTER_SESSION:
423  if (enip_len != ENIP_LEN_REGISTER_SESSION) {
424  return ALPROTO_FAILED;
425  }
426  break;
427  case UNREGISTER_SESSION:
428  if (enip_len != ENIP_LEN_REGISTER_SESSION && enip_len != 0) {
429  // 0 for request and 4 for response
430  return ALPROTO_FAILED;
431  }
432  break;
433  case LIST_SERVICES:
434  case LIST_IDENTITY:
435  case SEND_RR_DATA:
436  case SEND_UNIT_DATA:
437  case INDICATE_STATUS:
438  case CANCEL:
439  break;
440  case LIST_INTERFACES:
441  if (input_len < sizeof(ENIPEncapHdr) + 2) {
442  SCLogDebug("length too small to be a ENIP LIST_INTERFACES");
443  return ALPROTO_UNKNOWN;
444  }
445  ret = ByteExtractUint16(
446  &nbitems, BYTE_LITTLE_ENDIAN, sizeof(uint16_t), (const uint8_t *)(input));
447  if(ret < 0) {
448  return ALPROTO_FAILED;
449  }
450  if (enip_len < sizeof(ENIPEncapHdr) + 2 * (size_t)nbitems) {
451  return ALPROTO_FAILED;
452  }
453  break;
454  default:
455  return ALPROTO_FAILED;
456  }
457  return ALPROTO_ENIP;
458 }
459 
460 /**
461  * \brief Function to register the ENIP protocol parsers and other functions
462  */
464 {
465  SCEnter();
466  const char *proto_name = "enip";
467 
468  if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name))
469  {
471 
472  if (RunmodeIsUnittests())
473  {
474  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
475  0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
476 
477  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
478  0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
479 
480  } else
481  {
482  if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
483  proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
484  ENIPProbingParser, ENIPProbingParser))
485  {
486  SCLogDebug(
487  "no ENIP UDP config found enabling ENIP detection on port 44818.");
488 
489  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
491  ENIPProbingParser, NULL);
492 
493  AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
495  ENIPProbingParser, NULL);
496  }
497  }
498 
499  } else
500  {
501  SCLogConfig("Protocol detection and parser disabled for %s protocol.",
502  proto_name);
503  return;
504  }
505 
506  if (AppLayerParserConfParserEnabled("udp", proto_name))
507  {
509  STREAM_TOSERVER, ENIPParse);
511  STREAM_TOCLIENT, ENIPParse);
512 
514  ENIPStateAlloc, ENIPStateFree);
515 
516  AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetEvents);
517 
519  ENIPGetTxDetectState, ENIPSetTxDetectState);
520 
521  AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTx);
522  AppLayerParserRegisterTxDataFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxData);
523  AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetTxCnt);
524  AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateTransactionFree);
525 
526  AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_ENIP, ENIPGetAlstateProgress);
528 
529  AppLayerParserRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateGetEventInfo);
530  AppLayerParserRegisterGetEventInfoById(IPPROTO_UDP, ALPROTO_ENIP, ENIPStateGetEventInfoById);
531 
536  } else
537  {
538  SCLogInfo(
539  "Parsed disabled for %s protocol. Protocol detection" "still on.",
540  proto_name);
541  }
542 
543 #ifdef UNITTESTS
545 #endif
546 
547  SCReturn;
548 }
549 
550 /**
551  * \brief Function to register the ENIP protocol parsers and other functions
552  */
554 {
555  SCEnter();
556  const char *proto_name = "enip";
557 
558  if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name))
559  {
561 
562  if (RunmodeIsUnittests())
563  {
564  AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
565  0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
566 
567  AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
568  0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
569 
570  } else
571  {
572  if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
573  proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
574  ENIPProbingParser, ENIPProbingParser))
575  {
576  return;
577  }
578  }
579 
580  } else
581  {
582  SCLogDebug("Protocol detection and parser disabled for %s protocol.",
583  proto_name);
584  return;
585  }
586 
587  if (AppLayerParserConfParserEnabled("tcp", proto_name))
588  {
590  STREAM_TOSERVER, ENIPParse);
592  STREAM_TOCLIENT, ENIPParse);
594  ENIPStateAlloc, ENIPStateFree);
595 
596  AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetEvents);
597 
599  ENIPGetTxDetectState, ENIPSetTxDetectState);
600 
601  AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTx);
602  AppLayerParserRegisterTxDataFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxData);
603  AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetTxCnt);
604  AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPStateTransactionFree);
605 
606  AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_ENIP, ENIPGetAlstateProgress);
608 
609  AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_ENIP, ENIPStateGetEventInfo);
610 
613 
614  /* This parser accepts gaps. */
617 
620  } else
621  {
622  SCLogConfig("Parser disabled for %s protocol. Protocol detection still on.",
623  proto_name);
624  }
625 
626 #ifdef UNITTESTS
628 #endif
629 
630  SCReturn;
631 }
632 
633 /* UNITTESTS */
634 #ifdef UNITTESTS
635 #include "app-layer-parser.h"
636 #include "detect-parse.h"
637 #include "detect-engine.h"
638 #include "flow-util.h"
639 #include "stream-tcp.h"
640 #include "util-unittest.h"
641 #include "util-unittest-helper.h"
642 
643 static uint8_t listIdentity[] = {/* List ID */ 0x63, 0x00,
644  /* Length */ 0x00, 0x00,
645  /* Session */ 0x00, 0x00, 0x00, 0x00,
646  /* Status */ 0x00, 0x00, 0x00, 0x00,
647  /* Delay*/ 0x00,
648  /* Context */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649  /* Quantity of coils */ 0x00, 0x00, 0x00, 0x00, 0x00};
650 
651 /**
652  * \brief Test if ENIP Packet matches signature
653  */
654 static int ALDecodeENIPTest(void)
655 {
657  Flow f;
658  TcpSession ssn;
659 
660  memset(&f, 0, sizeof(f));
661  memset(&ssn, 0, sizeof(ssn));
662 
663  f.protoctx = (void *)&ssn;
664  f.proto = IPPROTO_TCP;
665  f.alproto = ALPROTO_ENIP;
666 
667  StreamTcpInitConfig(true);
668 
670  listIdentity, sizeof(listIdentity));
671  FAIL_IF(r != 0);
672 
673  ENIPState *enip_state = f.alstate;
674  FAIL_IF_NULL(enip_state);
675 
676  ENIPTransaction *tx = ENIPGetTx(enip_state, 0);
677  FAIL_IF_NULL(tx);
678 
679  FAIL_IF(tx->header.command != 99);
680 
682  StreamTcpFreeConfig(true);
683  FLOW_DESTROY(&f);
684 
685  PASS;
686 }
687 
688 #endif /* UNITTESTS */
689 
691 {
692 #ifdef UNITTESTS
693  UtRegisterTest("ALDecodeENIPTest", ALDecodeENIPTest);
694 #endif /* UNITTESTS */
695 }
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:474
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:1711
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:381
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:93
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:372
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:77
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:300
Flow_
Flow data structure.
Definition: flow.h:350
AppLayerEventType
enum AppLayerEventType_ AppLayerEventType
AppLayerParserRegisterGetEventsFunc
void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, AppLayerDecoderEvents *(*StateGetEvents)(void *))
Definition: app-layer-parser.c:435
AppLayerParserRegisterStateProgressCompletionStatus
void AppLayerParserRegisterStateProgressCompletionStatus(AppProto alproto, const int ts, const int tc)
Definition: app-layer-parser.c:526
ENIP_LEN_REGISTER_SESSION
#define ENIP_LEN_REGISTER_SESSION
Definition: app-layer-enip.c:362
AppLayerParserRegisterParserAcceptableDataDirection
void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction)
Definition: app-layer-parser.c:370
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:485
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:277
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:565
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:448
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:1677
app-layer-detect-proto.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
AppLayerParserStateIssetFlag
int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
Definition: app-layer-parser.c:1638
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:153
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:20
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:553
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:397
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
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:1736
ENIPState_::buffer
uint8_t * buffer
Definition: app-layer-enip-common.h:231
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:553
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1889
ENIPParserRegisterTests
void ENIPParserRegisterTests(void)
Definition: app-layer-enip.c:690
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:265
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:358
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:173
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:251
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:507
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
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:670
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:1195
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:463
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:577
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:483
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:541
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
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:67
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:496
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:85
TcpSession_
Definition: stream-tcp-private.h:260
util-misc.h
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:457
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:1987
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