suricata
detect-urilen.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 Gurvinder Singh <gurvindersighdahiya@gmail.com>
22 *
23 * Implements the urilen keyword
24 */
25
26#include "suricata-common.h"
27#include "app-layer.h"
28#include "app-layer-protos.h"
29#include "app-layer-htp.h"
30#include "util-unittest.h"
32
33#include "detect.h"
34#include "detect-parse.h"
35#include "detect-engine.h"
36#include "detect-engine-state.h"
37#include "detect-engine-build.h"
38#include "detect-content.h"
39#include "detect-engine-uint.h"
40
41#include "detect-urilen.h"
42#include "util-debug.h"
43#include "util-byte.h"
44#include "flow-util.h"
45#include "stream-tcp.h"
46
47
48/*prototypes*/
49static int DetectUrilenSetup (DetectEngineCtx *, Signature *, const char *);
50static void DetectUrilenFree (DetectEngineCtx *, void *);
51#ifdef UNITTESTS
52static void DetectUrilenRegisterTests (void);
53#endif
54static int g_http_uri_buffer_id = 0;
55static int g_http_raw_uri_buffer_id = 0;
56
57/**
58 * \brief Registration function for urilen: keyword
59 */
60
62{
64 sigmatch_table[DETECT_URILEN].desc = "match on the length of the HTTP uri";
65 sigmatch_table[DETECT_URILEN].url = "/rules/http-keywords.html#urilen";
67 sigmatch_table[DETECT_URILEN].Setup = DetectUrilenSetup;
68 sigmatch_table[DETECT_URILEN].Free = DetectUrilenFree;
69#ifdef UNITTESTS
70 sigmatch_table[DETECT_URILEN].RegisterTests = DetectUrilenRegisterTests;
71#endif
72
73 g_http_uri_buffer_id = DetectBufferTypeRegister("http_uri");
74 g_http_raw_uri_buffer_id = DetectBufferTypeRegister("http_raw_uri");
75}
76
77/**
78 * \brief This function is used to parse urilen options passed via urilen: keyword
79 *
80 * \param urilenstr Pointer to the user provided urilen options
81 *
82 * \retval urilend pointer to DetectUrilenData on success
83 * \retval NULL on failure
84 */
85
86static DetectUrilenData *DetectUrilenParse (const char *urilenstr)
87{
88 return SCDetectUrilenParse(urilenstr);
89}
90
91/**
92 * \brief this function is used to parse urilen data into the current signature
93 *
94 * \param de_ctx pointer to the Detection Engine Context
95 * \param s pointer to the Current Signature
96 * \param urilenstr pointer to the user provided urilen options
97 *
98 * \retval 0 on Success
99 * \retval -1 on Failure
100 */
101static int DetectUrilenSetup (DetectEngineCtx *de_ctx, Signature *s, const char *urilenstr)
102{
103 SCEnter();
104 DetectUrilenData *urilend = NULL;
105
107 return -1;
108
109 urilend = DetectUrilenParse(urilenstr);
110 if (urilend == NULL)
111 goto error;
112
113 if (urilend->raw_buffer) {
115 g_http_raw_uri_buffer_id) == NULL) {
116 goto error;
117 }
118 } else {
120 g_http_uri_buffer_id) == NULL) {
121 goto error;
122 }
123 }
124
125 SCReturnInt(0);
126
127error:
128 DetectUrilenFree(de_ctx, urilend);
129 SCReturnInt(-1);
130}
131
132/**
133 * \brief this function will free memory associated with DetectUrilenData
134 *
135 * \param ptr pointer to DetectUrilenData
136 */
137static void DetectUrilenFree(DetectEngineCtx *de_ctx, void *ptr)
138{
139 if (ptr == NULL)
140 return;
141
142 DetectUrilenData *urilend = (DetectUrilenData *)ptr;
143 SCDetectUrilenFree(urilend);
144}
145
146/** \brief set prefilter dsize pair
147 * \param s signature to get dsize value from
148 */
150{
151 for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
152 if (s->init_data->buffers[x].id != (uint32_t)list)
153 continue;
154
155 uint16_t high = UINT16_MAX;
156 bool found = false;
157
158 for (SigMatch *sm = s->init_data->buffers[x].head; sm != NULL; sm = sm->next) {
159 if (sm->type != DETECT_URILEN)
160 continue;
161
162 DetectUrilenData *dd = (DetectUrilenData *)sm->ctx;
163
164 switch (dd->du16.mode) {
165 case DETECT_UINT_LT:
166 if (dd->du16.arg1 < UINT16_MAX) {
167 high = dd->du16.arg1 + 1;
168 }
169 break;
170 case DETECT_UINT_LTE:
171 // fallthrough
172 case DETECT_UINT_EQ:
173 high = dd->du16.arg1;
174 break;
175 case DETECT_UINT_RA:
176 if (dd->du16.arg2 < UINT16_MAX) {
177 high = dd->du16.arg2 + 1;
178 }
179 break;
180 case DETECT_UINT_NE:
181 // fallthrough
182 case DETECT_UINT_GTE:
183 // fallthrough
184 case DETECT_UINT_GT:
185 high = UINT16_MAX;
186 break;
187 }
188 found = true;
189 }
190
191 // skip 65535 to avoid mismatch on uri > 64k
192 if (!found || high == UINT16_MAX)
193 return;
194
195 SCLogDebug("high %u", high);
196
197 for (SigMatch *sm = s->init_data->buffers[x].head; sm != NULL; sm = sm->next) {
198 if (sm->type != DETECT_CONTENT) {
199 continue;
200 }
201 DetectContentData *cd = (DetectContentData *)sm->ctx;
202 if (cd == NULL) {
203 continue;
204 }
205
206 if (cd->depth == 0 || cd->depth > high) {
207 cd->depth = high;
209 SCLogDebug("updated %u, content %u to have depth %u "
210 "because of urilen.",
211 s->id, cd->id, cd->depth);
212 }
213 }
214 }
215}
216
218 const Signature *s, const char **sigerror, const DetectBufferType *dbt)
219{
220 for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
221 if (s->init_data->buffers[x].id != (uint32_t)dbt->id)
222 continue;
223 for (const SigMatch *sm = s->init_data->buffers[x].head; sm != NULL; sm = sm->next) {
224 if (sm->type != DETECT_CONTENT) {
225 continue;
226 }
227 DetectContentData *cd = (DetectContentData *)sm->ctx;
228 if (cd == NULL) {
229 continue;
230 }
231
232 if (cd->depth && cd->depth < cd->content_len) {
233 *sigerror = "depth or urilen smaller than content len";
234 SCLogError("depth or urilen %u smaller "
235 "than content len %u",
236 cd->depth, cd->content_len);
237 return false;
238 }
239 }
240 }
241 return true;
242}
243
244#ifdef UNITTESTS
245
246#include "stream.h"
247#include "stream-tcp-private.h"
249#include "detect-engine-mpm.h"
250#include "app-layer-parser.h"
251#include "detect-engine-alert.h"
252
253/** \test Test the Urilen keyword setup */
254static int DetectUrilenParseTest01(void)
255{
256 int ret = 0;
257 DetectUrilenData *urilend = NULL;
258
259 urilend = DetectUrilenParse("10");
260 if (urilend != NULL) {
261 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_EQ &&
262 !urilend->raw_buffer)
263 ret = 1;
264
265 DetectUrilenFree(NULL, urilend);
266 }
267 return ret;
268}
269
270/** \test Test the Urilen keyword setup */
271static int DetectUrilenParseTest02(void)
272{
273 int ret = 0;
274 DetectUrilenData *urilend = NULL;
275
276 urilend = DetectUrilenParse(" < 10 ");
277 if (urilend != NULL) {
278 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_LT &&
279 !urilend->raw_buffer)
280 ret = 1;
281
282 DetectUrilenFree(NULL, urilend);
283 }
284 return ret;
285}
286
287/** \test Test the Urilen keyword setup */
288static int DetectUrilenParseTest03(void)
289{
290 int ret = 0;
291 DetectUrilenData *urilend = NULL;
292
293 urilend = DetectUrilenParse(" > 10 ");
294 if (urilend != NULL) {
295 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_GT &&
296 !urilend->raw_buffer)
297 ret = 1;
298
299 DetectUrilenFree(NULL, urilend);
300 }
301 return ret;
302}
303
304/** \test Test the Urilen keyword setup */
305static int DetectUrilenParseTest04(void)
306{
307 int ret = 0;
308 DetectUrilenData *urilend = NULL;
309
310 urilend = DetectUrilenParse(" 5 <> 10 ");
311 if (urilend != NULL) {
312 if (urilend->du16.arg1 == 5 && urilend->du16.arg2 == 10 &&
313 urilend->du16.mode == DETECT_UINT_RA && !urilend->raw_buffer)
314 ret = 1;
315
316 DetectUrilenFree(NULL, urilend);
317 }
318 return ret;
319}
320
321/** \test Test the Urilen keyword setup */
322static int DetectUrilenParseTest05(void)
323{
324 int ret = 0;
325 DetectUrilenData *urilend = NULL;
326
327 urilend = DetectUrilenParse("5<>10,norm");
328 if (urilend != NULL) {
329 if (urilend->du16.arg1 == 5 && urilend->du16.arg2 == 10 &&
330 urilend->du16.mode == DETECT_UINT_RA && !urilend->raw_buffer)
331 ret = 1;
332
333 DetectUrilenFree(NULL, urilend);
334 }
335 return ret;
336}
337
338/** \test Test the Urilen keyword setup */
339static int DetectUrilenParseTest06(void)
340{
341 int ret = 0;
342 DetectUrilenData *urilend = NULL;
343
344 urilend = DetectUrilenParse("5<>10,raw");
345 if (urilend != NULL) {
346 if (urilend->du16.arg1 == 5 && urilend->du16.arg2 == 10 &&
347 urilend->du16.mode == DETECT_UINT_RA && urilend->raw_buffer)
348 ret = 1;
349
350 DetectUrilenFree(NULL, urilend);
351 }
352 return ret;
353}
354
355/** \test Test the Urilen keyword setup */
356static int DetectUrilenParseTest07(void)
357{
358 int ret = 0;
359 DetectUrilenData *urilend = NULL;
360
361 urilend = DetectUrilenParse(">10, norm ");
362 if (urilend != NULL) {
363 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_GT &&
364 !urilend->raw_buffer)
365 ret = 1;
366
367 DetectUrilenFree(NULL, urilend);
368 }
369 return ret;
370}
371
372/** \test Test the Urilen keyword setup */
373static int DetectUrilenParseTest08(void)
374{
375 int ret = 0;
376 DetectUrilenData *urilend = NULL;
377
378 urilend = DetectUrilenParse("<10, norm ");
379 if (urilend != NULL) {
380 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_LT &&
381 !urilend->raw_buffer)
382 ret = 1;
383
384 DetectUrilenFree(NULL, urilend);
385 }
386 return ret;
387}
388
389/** \test Test the Urilen keyword setup */
390static int DetectUrilenParseTest09(void)
391{
392 int ret = 0;
393 DetectUrilenData *urilend = NULL;
394
395 urilend = DetectUrilenParse(">10, raw ");
396 if (urilend != NULL) {
397 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_GT && urilend->raw_buffer)
398 ret = 1;
399
400 DetectUrilenFree(NULL, urilend);
401 }
402 return ret;
403}
404
405/** \test Test the Urilen keyword setup */
406static int DetectUrilenParseTest10(void)
407{
408 int ret = 0;
409 DetectUrilenData *urilend = NULL;
410
411 urilend = DetectUrilenParse("<10, raw ");
412 if (urilend != NULL) {
413 if (urilend->du16.arg1 == 10 && urilend->du16.mode == DETECT_UINT_LT && urilend->raw_buffer)
414 ret = 1;
415
416 DetectUrilenFree(NULL, urilend);
417 }
418 return ret;
419}
420
421/**
422 * \brief this function is used to initialize the detection engine context and
423 * setup the signature with passed values.
424 *
425 */
426
427static int DetectUrilenInitTest(DetectEngineCtx **de_ctx, Signature **sig,
428 DetectUrilenData **urilend, const char *str)
429{
430 char fullstr[1024];
431 int result = 0;
432
433 *de_ctx = NULL;
434 *sig = NULL;
435
436 if (snprintf(fullstr, 1024, "alert ip any any -> any any (msg:\"Urilen "
437 "test\"; urilen:%s; sid:1;)", str) >= 1024) {
438 goto end;
439 }
440
442 if (*de_ctx == NULL) {
443 goto end;
444 }
445
446 (*de_ctx)->flags |= DE_QUIET;
447
448 (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr);
449 if ((*de_ctx)->sig_list == NULL) {
450 goto end;
451 }
452
453 *sig = (*de_ctx)->sig_list;
454
455 *urilend = DetectUrilenParse(str);
456
457 result = 1;
458
459end:
460 return result;
461}
462
463/**
464 * \test DetectUrilenSetpTest01 is a test for setting up an valid urilen values
465 * with valid "<>" operator and include spaces arround the given values.
466 * In the test the values are setup with initializing the detection engine
467 * context and setting up the signature itself.
468 */
469
470static int DetectUrilenSetpTest01(void)
471{
472
473 DetectUrilenData *urilend = NULL;
474 uint8_t res = 0;
475 Signature *sig = NULL;
476 DetectEngineCtx *de_ctx = NULL;
477
478 res = DetectUrilenInitTest(&de_ctx, &sig, &urilend, "1 <> 2 ");
479 if (res == 0) {
480 goto end;
481 }
482
483 if(urilend == NULL)
484 goto cleanup;
485
486 if (urilend != NULL) {
487 if (urilend->du16.arg1 == 1 && urilend->du16.arg2 == 2 &&
488 urilend->du16.mode == DETECT_UINT_RA)
489 res = 1;
490 }
491
492cleanup:
493 if (urilend)
494 DetectUrilenFree(NULL, urilend);
498end:
499 return res;
500}
501
502/** \test Check a signature with given urilen */
503static int DetectUrilenSigTest01(void)
504{
505 int result = 0;
506 Flow f;
507 uint8_t httpbuf1[] = "POST /suricata HTTP/1.0\r\n"
508 "Host: foo.bar.tld\r\n"
509 "\r\n";
510 uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
511 TcpSession ssn;
512 Packet *p = NULL;
513 Signature *s = NULL;
514 ThreadVars th_v;
515 DetectEngineThreadCtx *det_ctx;
517
518 memset(&th_v, 0, sizeof(th_v));
519 memset(&f, 0, sizeof(f));
520 memset(&ssn, 0, sizeof(ssn));
521
522 p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
523
524 FLOW_INITIALIZE(&f);
525 f.protoctx = (void *)&ssn;
526 f.proto = IPPROTO_TCP;
527 f.flags |= FLOW_IPV4;
528
529 p->flow = &f;
534
536
538 if (de_ctx == NULL) {
539 goto end;
540 }
541
543
545 "alert tcp any any -> any any "
546 "(msg:\"Testing urilen\"; "
547 "urilen: <5; sid:1;)");
548 if (s == NULL) {
549 goto end;
550 }
551
552 s = s->next = SigInit(de_ctx,
553 "alert tcp any any -> any any "
554 "(msg:\"Testing http_method\"; "
555 "urilen: >5; sid:2;)");
556 if (s == NULL) {
557 goto end;
558 }
559
561 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
562
563 int r = AppLayerParserParse(
564 NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
565 if (r != 0) {
566 SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
567 goto end;
568 }
569
570 HtpState *htp_state = f.alstate;
571 if (htp_state == NULL) {
572 SCLogDebug("no http state: ");
573 goto end;
574 }
575
576 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
577
578 if ((PacketAlertCheck(p, 1))) {
579 printf("sid 1 alerted, but should not have: \n");
580 goto end;
581 }
582 if (!PacketAlertCheck(p, 2)) {
583 printf("sid 2 did not alerted, but should have: \n");
584 goto end;
585 }
586
587 result = 1;
588
589end:
590 if (alp_tctx != NULL)
592 if (de_ctx != NULL) SigGroupCleanup(de_ctx);
593 if (de_ctx != NULL) SigCleanSignatures(de_ctx);
594 if (de_ctx != NULL) DetectEngineCtxFree(de_ctx);
595
597 FLOW_DESTROY(&f);
598 UTHFreePackets(&p, 1);
599 return result;
600}
601
602/**
603 * \brief this function registers unit tests for DetectUrilen
604 */
605void DetectUrilenRegisterTests(void)
606{
607 UtRegisterTest("DetectUrilenParseTest01", DetectUrilenParseTest01);
608 UtRegisterTest("DetectUrilenParseTest02", DetectUrilenParseTest02);
609 UtRegisterTest("DetectUrilenParseTest03", DetectUrilenParseTest03);
610 UtRegisterTest("DetectUrilenParseTest04", DetectUrilenParseTest04);
611 UtRegisterTest("DetectUrilenParseTest05", DetectUrilenParseTest05);
612 UtRegisterTest("DetectUrilenParseTest06", DetectUrilenParseTest06);
613 UtRegisterTest("DetectUrilenParseTest07", DetectUrilenParseTest07);
614 UtRegisterTest("DetectUrilenParseTest08", DetectUrilenParseTest08);
615 UtRegisterTest("DetectUrilenParseTest09", DetectUrilenParseTest09);
616 UtRegisterTest("DetectUrilenParseTest10", DetectUrilenParseTest10);
617 UtRegisterTest("DetectUrilenSetpTest01", DetectUrilenSetpTest01);
618 UtRegisterTest("DetectUrilenSigTest01", DetectUrilenSigTest01);
619}
620#endif /* UNITTESTS */
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
@ ALPROTO_HTTP
@ ALPROTO_HTTP1
#define PKT_HAS_FLOW
Definition decode.h:1266
#define PKT_STREAM_EST
Definition decode.h:1262
#define DETECT_CONTENT_DEPTH
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)
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Data structures and function prototypes for keeping state for the detection engine.
#define DETECT_UINT_LT
#define DETECT_UINT_LTE
#define DETECT_UINT_GTE
#define DETECT_UINT_NE
#define DETECT_UINT_EQ
#define DETECT_UINT_GT
#define DETECT_UINT_RA
int DetectBufferTypeRegister(const char *name)
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
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 DetectUrilenRegister(void)
Registration function for urilen: keyword.
bool DetectUrilenValidateContent(const Signature *s, const char **sigerror, const DetectBufferType *dbt)
void DetectUrilenApplyToContent(Signature *s, int list)
set prefilter dsize pair
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 FLOW_INITIALIZE(f)
Definition flow-util.h:38
#define FLOW_DESTROY(f)
Definition flow-util.h:119
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_PKT_ESTABLISHED
Definition flow.h:235
#define FLOW_IPV4
Definition flow.h:100
AppLayerParserThreadCtx * alp_tctx
DetectEngineCtx * de_ctx
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void StreamTcpFreeConfig(bool quiet)
Definition stream-tcp.c:859
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition stream-tcp.c:488
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
Signature * sig_list
Definition detect.h:941
Flow data structure.
Definition flow.h:356
uint8_t proto
Definition flow.h:378
uint32_t flags
Definition flow.h:421
AppProto alproto
application level protocol
Definition flow.h:450
void * alstate
Definition flow.h:479
void * protoctx
Definition flow.h:441
uint8_t flowflags
Definition decode.h:532
struct Flow_ * flow
Definition decode.h:546
uint32_t flags
Definition decode.h:544
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
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
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
SignatureInitDataBuffer * buffers
Definition detect.h:647
uint32_t buffer_index
Definition detect.h:648
Signature container.
Definition detect.h:668
SignatureInitData * init_data
Definition detect.h:747
uint32_t id
Definition detect.h:713
struct Signature_ * next
Definition detect.h:750
Per thread variable structure.
Definition threadvars.h:58
#define str(s)
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
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.