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