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