suricata
detect-icmp-id.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 Gerardo Iglesias Galvan <iglesiasg@gmail.com>
22 *
23 * Implements the icmp_id keyword
24 */
25
26#include "suricata-common.h"
27#include "decode.h"
28
29#include "detect.h"
30#include "detect-parse.h"
32#include "detect-engine-build.h"
33#include "detect-engine-alert.h"
34
35#include "detect-icmp-id.h"
36
37#include "util-byte.h"
38#include "util-unittest.h"
40#include "util-debug.h"
41
42#define PARSE_REGEX "^\\s*(\"\\s*)?([0-9]+)(\\s*\")?\\s*$"
43
44static DetectParseRegex parse_regex;
45
46static int DetectIcmpIdMatch(DetectEngineThreadCtx *, Packet *,
47 const Signature *, const SigMatchCtx *);
48static int DetectIcmpIdSetup(DetectEngineCtx *, Signature *, const char *);
49#ifdef UNITTESTS
50static void DetectIcmpIdRegisterTests(void);
51#endif
52void DetectIcmpIdFree(DetectEngineCtx *, void *);
53static int PrefilterSetupIcmpId(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
54static bool PrefilterIcmpIdIsPrefilterable(const Signature *s);
55
56/**
57 * \brief Registration function for icode: icmp_id
58 */
60{
62 sigmatch_table[DETECT_ICMP_ID].desc = "check for a ICMP ID";
63 sigmatch_table[DETECT_ICMP_ID].url = "/rules/header-keywords.html#icmp-id";
64 sigmatch_table[DETECT_ICMP_ID].Match = DetectIcmpIdMatch;
65 sigmatch_table[DETECT_ICMP_ID].Setup = DetectIcmpIdSetup;
67#ifdef UNITTESTS
68 sigmatch_table[DETECT_ICMP_ID].RegisterTests = DetectIcmpIdRegisterTests;
69#endif
70 sigmatch_table[DETECT_ICMP_ID].SupportsPrefilter = PrefilterIcmpIdIsPrefilterable;
71 sigmatch_table[DETECT_ICMP_ID].SetupPrefilter = PrefilterSetupIcmpId;
72
74}
75
76static inline bool GetIcmpId(Packet *p, uint16_t *id)
77{
78 uint16_t pid;
79 if (PacketIsICMPv4(p)) {
80 switch (p->icmp_s.type) {
81 case ICMP_ECHOREPLY:
82 case ICMP_ECHO:
83 case ICMP_TIMESTAMP:
86 case ICMP_INFO_REPLY:
87 case ICMP_ADDRESS:
89 SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), "
90 "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p),
92
93 pid = ICMPV4_GET_ID(p);
94 break;
95 default:
96 SCLogDebug("Packet has no id field");
97 return false;
98 }
99 } else if (PacketIsICMPv6(p)) {
100 switch (ICMPV6_GET_TYPE(PacketGetICMPv6(p))) {
102 case ICMP6_ECHO_REPLY:
103 SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), "
104 "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p),
106
107 pid = ICMPV6_GET_ID(p);
108 break;
109 default:
110 SCLogDebug("Packet has no id field");
111 return false;
112 }
113 } else {
114 SCLogDebug("Packet not ICMPV4 nor ICMPV6");
115 return false;
116 }
117
118 *id = pid;
119 return true;
120}
121
122/**
123 * \brief This function is used to match icmp_id rule option set on a packet
124 *
125 * \param t pointer to thread vars
126 * \param det_ctx pointer to the pattern matcher thread
127 * \param p pointer to the current packet
128 * \param m pointer to the sigmatch that we will cast into DetectIcmpIdData
129 *
130 * \retval 0 no match
131 * \retval 1 match
132 */
133static int DetectIcmpIdMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
134 const Signature *s, const SigMatchCtx *ctx)
135{
136 uint16_t pid;
137
138 if (!GetIcmpId(p, &pid))
139 return 0;
140
141 const DetectIcmpIdData *iid = (const DetectIcmpIdData *)ctx;
142 if (pid == iid->id)
143 return 1;
144
145 return 0;
146}
147
148/**
149 * \brief This function is used to parse icmp_id option passed via icmp_id: keyword
150 *
151 * \param de_ctx Pointer to the detection engine context
152 * \param icmpidstr Pointer to the user provided icmp_id options
153 *
154 * \retval iid pointer to DetectIcmpIdData on success
155 * \retval NULL on failure
156 */
157static DetectIcmpIdData *DetectIcmpIdParse (DetectEngineCtx *de_ctx, const char *icmpidstr)
158{
159 DetectIcmpIdData *iid = NULL;
160 char *substr[3] = {NULL, NULL, NULL};
161 int res = 0;
162 size_t pcre2_len;
163
164 pcre2_match_data *match = NULL;
165 int ret = DetectParsePcreExec(&parse_regex, &match, icmpidstr, 0, 0);
166 if (ret < 1 || ret > 4) {
167 SCLogError("Parse error %s", icmpidstr);
168 goto error;
169 }
170
171 int i;
172 const char *str_ptr;
173 for (i = 1; i < ret; i++) {
174 res = SC_Pcre2SubstringGet(match, i, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
175 if (res < 0) {
176 SCLogError("pcre2_substring_get_bynumber failed");
177 goto error;
178 }
179 substr[i-1] = (char *)str_ptr;
180 }
181
182 iid = SCMalloc(sizeof(DetectIcmpIdData));
183 if (unlikely(iid == NULL))
184 goto error;
185 iid->id = 0;
186
187 if (substr[0]!= NULL && strlen(substr[0]) != 0) {
188 if (substr[2] == NULL) {
189 SCLogError("Missing close quote in input");
190 goto error;
191 }
192 } else {
193 if (substr[2] != NULL) {
194 SCLogError("Missing open quote in input");
195 goto error;
196 }
197 }
198
199 uint16_t id = 0;
200 if (StringParseUint16(&id, 10, 0, substr[1]) < 0) {
201 SCLogError("specified icmp id %s is not "
202 "valid",
203 substr[1]);
204 goto error;
205 }
206 iid->id = htons(id);
207
208 for (i = 0; i < 3; i++) {
209 if (substr[i] != NULL)
210 pcre2_substring_free((PCRE2_UCHAR8 *)substr[i]);
211 }
212 pcre2_match_data_free(match);
213 return iid;
214
215error:
216 if (match) {
217 pcre2_match_data_free(match);
218 }
219 for (i = 0; i < 3; i++) {
220 if (substr[i] != NULL)
221 pcre2_substring_free((PCRE2_UCHAR8 *)substr[i]);
222 }
223 if (iid != NULL) DetectIcmpIdFree(de_ctx, iid);
224 return NULL;
225
226}
227
228/**
229 * \brief this function is used to add the parsed icmp_id data into the current signature
230 *
231 * \param de_ctx pointer to the Detection Engine Context
232 * \param s pointer to the Current Signature
233 * \param icmpidstr pointer to the user provided icmp_id option
234 *
235 * \retval 0 on Success
236 * \retval -1 on Failure
237 */
238static int DetectIcmpIdSetup (DetectEngineCtx *de_ctx, Signature *s, const char *icmpidstr)
239{
240 DetectIcmpIdData *iid = NULL;
241
242 iid = DetectIcmpIdParse(de_ctx, icmpidstr);
243 if (iid == NULL) goto error;
244
247 goto error;
248 }
250
251 return 0;
252
253error:
254 if (iid != NULL)
256 return -1;
257
258}
259
260/**
261 * \brief this function will free memory associated with DetectIcmpIdData
262 *
263 * \param ptr pointer to DetectIcmpIdData
264 */
266{
268 SCFree(iid);
269}
270
271/* prefilter code */
272
273static void
274PrefilterPacketIcmpIdMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
275{
276 const PrefilterPacketHeaderCtx *ctx = pectx;
277
278 uint16_t pid;
279 if (!GetIcmpId(p, &pid))
280 return;
281
282 if (pid == ctx->v1.u16[0])
283 {
284 SCLogDebug("packet matches ICMP ID %u", ctx->v1.u16[0]);
285 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
286 }
287}
288
289static void
290PrefilterPacketIcmpIdSet(PrefilterPacketHeaderValue *v, void *smctx)
291{
292 const DetectIcmpIdData *a = smctx;
293 v->u16[0] = a->id;
294}
295
296static bool
297PrefilterPacketIcmpIdCompare(PrefilterPacketHeaderValue v, void *smctx)
298{
299 const DetectIcmpIdData *a = smctx;
300 if (v.u16[0] == a->id)
301 return true;
302 return false;
303}
304
305static int PrefilterSetupIcmpId(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
306{
308 PrefilterPacketIcmpIdSet, PrefilterPacketIcmpIdCompare, PrefilterPacketIcmpIdMatch);
309}
310
311static bool PrefilterIcmpIdIsPrefilterable(const Signature *s)
312{
313 const SigMatch *sm;
314 for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
315 switch (sm->type) {
316 case DETECT_ICMP_ID:
317 return true;
318 }
319 }
320 return false;
321}
322
323#ifdef UNITTESTS
324#include "detect-engine.h"
325#include "detect-engine-mpm.h"
326
327/**
328 * \test DetectIcmpIdParseTest01 is a test for setting a valid icmp_id value
329 */
330static int DetectIcmpIdParseTest01 (void)
331{
332 DetectIcmpIdData *iid = DetectIcmpIdParse(NULL, "300");
333 FAIL_IF_NULL(iid);
334 FAIL_IF_NOT(iid->id == htons(300));
335 DetectIcmpIdFree(NULL, iid);
336 PASS;
337}
338
339/**
340 * \test DetectIcmpIdParseTest02 is a test for setting a valid icmp_id value
341 * with spaces all around
342 */
343static int DetectIcmpIdParseTest02 (void)
344{
345 DetectIcmpIdData *iid = DetectIcmpIdParse(NULL, " 300 ");
346 FAIL_IF_NULL(iid);
347 FAIL_IF_NOT(iid->id == htons(300));
348 DetectIcmpIdFree(NULL, iid);
349 PASS;
350}
351
352/**
353 * \test DetectIcmpIdParseTest03 is a test for setting a valid icmp_id value
354 * with quotation marks
355 */
356static int DetectIcmpIdParseTest03 (void)
357{
358 DetectIcmpIdData *iid = DetectIcmpIdParse(NULL, "\"300\"");
359 FAIL_IF_NULL(iid);
360 FAIL_IF_NOT(iid->id == htons(300));
361 DetectIcmpIdFree(NULL, iid);
362 PASS;
363}
364
365/**
366 * \test DetectIcmpIdParseTest04 is a test for setting a valid icmp_id value
367 * with quotation marks and spaces all around
368 */
369static int DetectIcmpIdParseTest04 (void)
370{
371 DetectIcmpIdData *iid = DetectIcmpIdParse(NULL, " \" 300 \"");
372 FAIL_IF_NULL(iid);
373 FAIL_IF_NOT(iid->id == htons(300));
374 DetectIcmpIdFree(NULL, iid);
375 PASS;
376}
377
378/**
379 * \test DetectIcmpIdParseTest05 is a test for setting an invalid icmp_id
380 * value with missing quotation marks
381 */
382static int DetectIcmpIdParseTest05 (void)
383{
384 DetectIcmpIdData *iid = DetectIcmpIdParse(NULL, "\"300");
385 FAIL_IF_NOT_NULL(iid);
386 PASS;
387}
388
389/**
390 * \test DetectIcmpIdMatchTest01 is a test for checking the working of
391 * icmp_id keyword by creating 2 rules and matching a crafted packet
392 * against them. Only the first one shall trigger.
393 */
394static int DetectIcmpIdMatchTest01 (void)
395{
396 int result = 0;
397 Packet *p = NULL;
398 Signature *s = NULL;
399 ThreadVars th_v;
400 DetectEngineThreadCtx *det_ctx = NULL;
401
402 memset(&th_v, 0, sizeof(ThreadVars));
403
404 p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP);
405 p->l4.vars.icmpv4.id = htons(21781);
406
408 if (de_ctx == NULL) {
409 goto end;
410 }
411
413
414 s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:21781; sid:1;)");
415 if (s == NULL) {
416 goto end;
417 }
418
419 s = s->next = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:21782; sid:2;)");
420 if (s == NULL) {
421 goto end;
422 }
423
425 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
426
427 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
428 if (PacketAlertCheck(p, 1) == 0) {
429 printf("sid 1 did not alert, but should have: ");
430 goto cleanup;
431 } else if (PacketAlertCheck(p, 2)) {
432 printf("sid 2 alerted, but should not have: ");
433 goto cleanup;
434 }
435
436 result = 1;
437
438cleanup:
441
442 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
444
445 UTHFreePackets(&p, 1);
446end:
447 return result;
448
449}
450
451/**
452 * \test DetectIcmpIdMatchTest02 is a test for checking the working of
453 * icmp_id keyword by creating 1 rule and matching a crafted packet
454 * against them. The packet is an ICMP packet with no "id" field,
455 * therefore the rule should not trigger.
456 */
457static int DetectIcmpIdMatchTest02 (void)
458{
459 int result = 0;
460
461 uint8_t raw_icmpv4[] = {
462 0x0b, 0x00, 0x8a, 0xdf, 0x00, 0x00, 0x00, 0x00,
463 0x45, 0x00, 0x00, 0x14, 0x25, 0x0c, 0x00, 0x00,
464 0xff, 0x11, 0x00, 0x00, 0x85, 0x64, 0xea, 0x5b,
465 0x51, 0xa6, 0xbb, 0x35, 0x59, 0x8a, 0x5a, 0xe2,
466 0x00, 0x14, 0x00, 0x00 };
467
469 if (unlikely(p == NULL))
470 return 0;
471 Signature *s = NULL;
473 ThreadVars th_v;
474 DetectEngineThreadCtx *det_ctx = NULL;
475 IPV4Hdr ip4h;
476
477 memset(&ip4h, 0, sizeof(IPV4Hdr));
478 memset(&dtv, 0, sizeof(DecodeThreadVars));
479 memset(&th_v, 0, sizeof(ThreadVars));
480
482
483 p->src.addr_data32[0] = 0x01020304;
484 p->dst.addr_data32[0] = 0x04030201;
485
486 ip4h.s_ip_src.s_addr = p->src.addr_data32[0];
487 ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0];
488 UTHSetIPV4Hdr(p, &ip4h);
489
490 DecodeICMPV4(&th_v, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4));
491
493 if (de_ctx == NULL) {
494 goto end;
495 }
496
498
499 s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:0; sid:1;)");
500 if (s == NULL) {
501 goto end;
502 }
503
505 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
506
507 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
508 if (PacketAlertCheck(p, 1)) {
509 printf("sid 1 alerted, but should not have: ");
510 goto cleanup;
511 }
512
513 result = 1;
514
515cleanup:
518
519 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
521
522 FlowShutdown();
523end:
524 SCFree(p);
525 return result;
526}
527
528static void DetectIcmpIdRegisterTests (void)
529{
530 UtRegisterTest("DetectIcmpIdParseTest01", DetectIcmpIdParseTest01);
531 UtRegisterTest("DetectIcmpIdParseTest02", DetectIcmpIdParseTest02);
532 UtRegisterTest("DetectIcmpIdParseTest03", DetectIcmpIdParseTest03);
533 UtRegisterTest("DetectIcmpIdParseTest04", DetectIcmpIdParseTest04);
534 UtRegisterTest("DetectIcmpIdParseTest05", DetectIcmpIdParseTest05);
535 UtRegisterTest("DetectIcmpIdMatchTest01", DetectIcmpIdMatchTest01);
536 UtRegisterTest("DetectIcmpIdMatchTest02", DetectIcmpIdMatchTest02);
537}
538#endif /* UNITTESTS */
int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Main ICMPv4 decoding function.
#define ICMP_TIMESTAMPREPLY
#define ICMP_ADDRESSREPLY
#define ICMP_ADDRESS
#define ICMPV4_GET_ID(p)
#define ICMP_TIMESTAMP
#define ICMP_ECHOREPLY
#define ICMP_INFO_REPLY
#define ICMP_INFO_REQUEST
#define ICMP_ECHO
#define ICMP6_ECHO_REPLY
#define ICMPV6_GET_ID(p)
#define ICMPV6_GET_TYPE(icmp6h)
#define ICMP6_ECHO_REQUEST
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void SigCleanSignatures(DetectEngineCtx *de_ctx)
int SigGroupCleanup(DetectEngineCtx *de_ctx)
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
void DetectIcmpIdRegister(void)
Registration function for icode: icmp_id.
void DetectIcmpIdFree(DetectEngineCtx *, void *)
this function will free memory associated with DetectIcmpIdData
#define PARSE_REGEX
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition detect.c:2420
#define DE_QUIET
Definition detect.h:330
#define SIG_FLAG_REQUIRE_PACKET
Definition detect.h:254
#define SIG_MASK_REQUIRE_REAL_PKT
Definition detect.h:316
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
void FlowInitConfig(bool quiet)
initialize the configuration
Definition flow.c:547
void FlowShutdown(void)
shutdown the flow engine
Definition flow.c:691
#define FLOW_QUIET
Definition flow.h:43
DecodeThreadVars * dtv
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition decode.c:258
struct Thresholds ctx
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
Signature * sig_list
Definition detect.h:941
PrefilterRuleStore pmq
Definition detect.h:1349
union PacketL4::L4Vars vars
struct Packet_::@33::@40 icmp_s
struct PacketL4 l4
Definition decode.h:601
Address src
Definition decode.h:505
uint8_t type
Definition decode.h:511
Address dst
Definition decode.h:506
Container for matching data for a signature group.
Definition detect.h:1629
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * next
Definition detect.h:360
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition detect.h:1444
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
bool(* SupportsPrefilter)(const Signature *s)
Definition detect.h:1443
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
Signature container.
Definition detect.h:668
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
struct Signature_ * next
Definition detect.h:750
Per thread variable structure.
Definition threadvars.h:58
#define SCNtohs(x)
ICMPV4Vars icmpv4
Definition decode.h:479
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition util-byte.c:337
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)