/src/suricata7/src/util-unittest-helper.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2017 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 Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com> |
22 | | * |
23 | | * This file provide a set of helper functions for reducing the complexity |
24 | | * when constructing unittests |
25 | | */ |
26 | | |
27 | | #include "suricata-common.h" |
28 | | |
29 | | #include "decode.h" |
30 | | |
31 | | #include "flow-private.h" |
32 | | #include "flow-util.h" |
33 | | #include "flow-spare-pool.h" |
34 | | |
35 | | #include "detect.h" |
36 | | #include "detect-parse.h" |
37 | | #include "detect-engine.h" |
38 | | #include "detect-engine-alert.h" |
39 | | #include "detect-engine-sigorder.h" |
40 | | #include "detect-engine-build.h" |
41 | | |
42 | | #include "stream-tcp.h" |
43 | | #include "stream-tcp-private.h" |
44 | | |
45 | | #include "util-debug.h" |
46 | | #include "util-time.h" |
47 | | #include "util-error.h" |
48 | | #include "util-unittest.h" |
49 | | #include "util-unittest-helper.h" |
50 | | |
51 | | #if defined(UNITTESTS) || defined(FUZZ) |
52 | | Flow *TestHelperBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp) |
53 | 24.9k | { |
54 | 24.9k | struct in_addr in; |
55 | | |
56 | 24.9k | Flow *f = SCMalloc(sizeof(Flow)); |
57 | 24.9k | if (unlikely(f == NULL)) { |
58 | 0 | printf("FlowAlloc failed\n"); |
59 | 0 | ; |
60 | 0 | return NULL; |
61 | 0 | } |
62 | 24.9k | memset(f, 0x00, sizeof(Flow)); |
63 | | |
64 | 24.9k | FLOW_INITIALIZE(f); |
65 | | |
66 | 24.9k | if (family == AF_INET) { |
67 | 24.9k | f->flags |= FLOW_IPV4; |
68 | 24.9k | } else if (family == AF_INET6) { |
69 | 0 | f->flags |= FLOW_IPV6; |
70 | 0 | } |
71 | | |
72 | 24.9k | if (src != NULL) { |
73 | 24.9k | if (family == AF_INET) { |
74 | 24.9k | if (inet_pton(AF_INET, src, &in) != 1) { |
75 | 0 | printf("invalid address %s\n", src); |
76 | 0 | SCFree(f); |
77 | 0 | return NULL; |
78 | 0 | } |
79 | 24.9k | f->src.addr_data32[0] = in.s_addr; |
80 | 24.9k | } else { |
81 | 0 | BUG_ON(1); |
82 | 0 | } |
83 | 24.9k | } |
84 | 24.9k | if (dst != NULL) { |
85 | 24.9k | if (family == AF_INET) { |
86 | 24.9k | if (inet_pton(AF_INET, dst, &in) != 1) { |
87 | 0 | printf("invalid address %s\n", dst); |
88 | 0 | SCFree(f); |
89 | 0 | return NULL; |
90 | 0 | } |
91 | 24.9k | f->dst.addr_data32[0] = in.s_addr; |
92 | 24.9k | } else { |
93 | 0 | BUG_ON(1); |
94 | 0 | } |
95 | 24.9k | } |
96 | | |
97 | 24.9k | f->sp = sp; |
98 | 24.9k | f->dp = dp; |
99 | | |
100 | 24.9k | return f; |
101 | 24.9k | } |
102 | | /** \brief writes the contents of a buffer into a file */ |
103 | | int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size) |
104 | 217k | { |
105 | 217k | if (remove(name) != 0) { |
106 | 2.12k | if (errno != ENOENT) { |
107 | 0 | printf("failed remove, errno=%d\n", errno); |
108 | 0 | return -1; |
109 | 0 | } |
110 | 2.12k | } |
111 | 217k | FILE *fd = fopen(name, "wb"); |
112 | 217k | if (fd == NULL) { |
113 | 0 | printf("failed open, errno=%d\n", errno); |
114 | 0 | return -2; |
115 | 0 | } |
116 | 217k | if (fwrite (data, 1, size, fd) != size) { |
117 | 0 | fclose(fd); |
118 | 0 | return -3; |
119 | 0 | } |
120 | 217k | fclose(fd); |
121 | 217k | return 0; |
122 | 217k | } |
123 | | |
124 | | #endif |
125 | | #ifdef UNITTESTS |
126 | | |
127 | | /** |
128 | | * \brief return the uint32_t for a ipv4 address string |
129 | | * |
130 | | * \param str Valid ipaddress in string form (e.g. 1.2.3.4) |
131 | | * |
132 | | * \retval uint the uin32_t representation |
133 | | */ |
134 | | uint32_t UTHSetIPv4Address(const char *str) |
135 | | { |
136 | | struct in_addr in; |
137 | | if (inet_pton(AF_INET, str, &in) != 1) { |
138 | | printf("invalid IPv6 address %s\n", str); |
139 | | exit(EXIT_FAILURE); |
140 | | } |
141 | | return (uint32_t)in.s_addr; |
142 | | } |
143 | | |
144 | | /** |
145 | | * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests |
146 | | * specifying ip and port sources and destinations (IPV6) |
147 | | * |
148 | | * \param payload pointer to the payload buffer |
149 | | * \param payload_len pointer to the length of the payload |
150 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
151 | | * \param src pointer to a string containing the ip source |
152 | | * \param dst pointer to a string containing the ip destination |
153 | | * \param sport pointer to a string containing the port source |
154 | | * \param dport pointer to a string containing the port destination |
155 | | * |
156 | | * \retval Packet pointer to the built in packet |
157 | | */ |
158 | | Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, |
159 | | uint8_t ipproto, const char *src, const char *dst, |
160 | | uint16_t sport, uint16_t dport) |
161 | | { |
162 | | uint32_t in[4]; |
163 | | |
164 | | Packet *p = PacketGetFromAlloc(); |
165 | | if (unlikely(p == NULL)) |
166 | | return NULL; |
167 | | |
168 | | p->ts = TimeGet(); |
169 | | |
170 | | p->src.family = AF_INET6; |
171 | | p->dst.family = AF_INET6; |
172 | | p->payload = payload; |
173 | | p->payload_len = payload_len; |
174 | | p->proto = ipproto; |
175 | | |
176 | | p->ip6h = SCMalloc(sizeof(IPV6Hdr)); |
177 | | if (p->ip6h == NULL) |
178 | | goto error; |
179 | | memset(p->ip6h, 0, sizeof(IPV6Hdr)); |
180 | | p->ip6h->s_ip6_nxt = ipproto; |
181 | | p->ip6h->s_ip6_plen = htons(payload_len + sizeof(TCPHdr)); |
182 | | |
183 | | if (inet_pton(AF_INET6, src, &in) != 1) |
184 | | goto error; |
185 | | p->src.addr_data32[0] = in[0]; |
186 | | p->src.addr_data32[1] = in[1]; |
187 | | p->src.addr_data32[2] = in[2]; |
188 | | p->src.addr_data32[3] = in[3]; |
189 | | p->sp = sport; |
190 | | p->ip6h->s_ip6_src[0] = in[0]; |
191 | | p->ip6h->s_ip6_src[1] = in[1]; |
192 | | p->ip6h->s_ip6_src[2] = in[2]; |
193 | | p->ip6h->s_ip6_src[3] = in[3]; |
194 | | |
195 | | if (inet_pton(AF_INET6, dst, &in) != 1) |
196 | | goto error; |
197 | | p->dst.addr_data32[0] = in[0]; |
198 | | p->dst.addr_data32[1] = in[1]; |
199 | | p->dst.addr_data32[2] = in[2]; |
200 | | p->dst.addr_data32[3] = in[3]; |
201 | | p->dp = dport; |
202 | | p->ip6h->s_ip6_dst[0] = in[0]; |
203 | | p->ip6h->s_ip6_dst[1] = in[1]; |
204 | | p->ip6h->s_ip6_dst[2] = in[2]; |
205 | | p->ip6h->s_ip6_dst[3] = in[3]; |
206 | | |
207 | | p->tcph = SCMalloc(sizeof(TCPHdr)); |
208 | | if (p->tcph == NULL) |
209 | | goto error; |
210 | | memset(p->tcph, 0, sizeof(TCPHdr)); |
211 | | p->tcph->th_sport = htons(sport); |
212 | | p->tcph->th_dport = htons(dport); |
213 | | |
214 | | SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(TCPHdr) + payload_len); |
215 | | return p; |
216 | | |
217 | | error: |
218 | | if (p != NULL) { |
219 | | if (p->ip6h != NULL) { |
220 | | SCFree(p->ip6h); |
221 | | } |
222 | | if (p->tcph != NULL) { |
223 | | SCFree(p->tcph); |
224 | | } |
225 | | SCFree(p); |
226 | | } |
227 | | return NULL; |
228 | | } |
229 | | |
230 | | /** |
231 | | * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests |
232 | | * specifying ip and port sources and destinations |
233 | | * |
234 | | * \param payload pointer to the payload buffer |
235 | | * \param payload_len pointer to the length of the payload |
236 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
237 | | * \param src pointer to a string containing the ip source |
238 | | * \param dst pointer to a string containing the ip destination |
239 | | * \param sport pointer to a string containing the port source |
240 | | * \param dport pointer to a string containing the port destination |
241 | | * |
242 | | * \retval Packet pointer to the built in packet |
243 | | */ |
244 | | Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, |
245 | | uint8_t ipproto, const char *src, const char *dst, |
246 | | uint16_t sport, uint16_t dport) |
247 | | { |
248 | | struct in_addr in; |
249 | | |
250 | | Packet *p = PacketGetFromAlloc(); |
251 | | if (unlikely(p == NULL)) |
252 | | return NULL; |
253 | | |
254 | | p->ts = TimeGet(); |
255 | | |
256 | | p->src.family = AF_INET; |
257 | | p->dst.family = AF_INET; |
258 | | p->payload = payload; |
259 | | p->payload_len = payload_len; |
260 | | p->proto = ipproto; |
261 | | |
262 | | if (inet_pton(AF_INET, src, &in) != 1) |
263 | | goto error; |
264 | | p->src.addr_data32[0] = in.s_addr; |
265 | | p->sp = sport; |
266 | | |
267 | | if (inet_pton(AF_INET, dst, &in) != 1) |
268 | | goto error; |
269 | | p->dst.addr_data32[0] = in.s_addr; |
270 | | p->dp = dport; |
271 | | |
272 | | p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); |
273 | | if (p->ip4h == NULL) |
274 | | goto error; |
275 | | |
276 | | p->ip4h->s_ip_src.s_addr = p->src.addr_data32[0]; |
277 | | p->ip4h->s_ip_dst.s_addr = p->dst.addr_data32[0]; |
278 | | p->ip4h->ip_proto = ipproto; |
279 | | p->ip4h->ip_verhl = sizeof(IPV4Hdr); |
280 | | p->proto = ipproto; |
281 | | |
282 | | int hdr_offset = sizeof(IPV4Hdr); |
283 | | switch (ipproto) { |
284 | | case IPPROTO_UDP: |
285 | | p->udph = (UDPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); |
286 | | if (p->udph == NULL) |
287 | | goto error; |
288 | | |
289 | | p->udph->uh_sport = sport; |
290 | | p->udph->uh_dport = dport; |
291 | | hdr_offset += sizeof(UDPHdr); |
292 | | break; |
293 | | case IPPROTO_TCP: |
294 | | p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); |
295 | | if (p->tcph == NULL) |
296 | | goto error; |
297 | | |
298 | | p->tcph->th_sport = htons(sport); |
299 | | p->tcph->th_dport = htons(dport); |
300 | | hdr_offset += sizeof(TCPHdr); |
301 | | break; |
302 | | case IPPROTO_ICMP: |
303 | | p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); |
304 | | if (p->icmpv4h == NULL) |
305 | | goto error; |
306 | | |
307 | | hdr_offset += sizeof(ICMPV4Hdr); |
308 | | break; |
309 | | default: |
310 | | break; |
311 | | /* TODO: Add more protocols */ |
312 | | } |
313 | | |
314 | | if (payload && payload_len) { |
315 | | PacketCopyDataOffset(p, hdr_offset, payload, payload_len); |
316 | | } |
317 | | SET_PKT_LEN(p, hdr_offset + payload_len); |
318 | | p->payload = GET_PKT_DATA(p)+hdr_offset; |
319 | | p->app_update_direction = UPDATE_DIR_BOTH; |
320 | | |
321 | | return p; |
322 | | |
323 | | error: |
324 | | SCFree(p); |
325 | | return NULL; |
326 | | } |
327 | | |
328 | | /** |
329 | | * \brief UTHBuildPacket is a wrapper that build packets with default ip |
330 | | * and port fields |
331 | | * |
332 | | * \param payload pointer to the payload buffer |
333 | | * \param payload_len pointer to the length of the payload |
334 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
335 | | * |
336 | | * \retval Packet pointer to the built in packet |
337 | | */ |
338 | | Packet *UTHBuildPacket(uint8_t *payload, uint16_t payload_len, |
339 | | uint8_t ipproto) |
340 | | { |
341 | | return UTHBuildPacketReal(payload, payload_len, ipproto, |
342 | | "192.168.1.5", "192.168.1.1", |
343 | | 41424, 80); |
344 | | } |
345 | | |
346 | | /** |
347 | | * \brief UTHBuildPacketArrayFromEth is a wrapper that build a packets from an array of |
348 | | * packets in ethernet rawbytes. Hint: It also share the flows. |
349 | | * |
350 | | * \param raw_eth pointer to the array of ethernet packets in rawbytes |
351 | | * \param pktsize pointer to the array of sizes corresponding to each buffer pointed |
352 | | * from pktsize. |
353 | | * \param numpkts number of packets in the array |
354 | | * |
355 | | * \retval Packet pointer to the array of built in packets; NULL if something fail |
356 | | */ |
357 | | Packet **UTHBuildPacketArrayFromEth(uint8_t *raw_eth[], int *pktsize, int numpkts) |
358 | | { |
359 | | DecodeThreadVars dtv; |
360 | | ThreadVars th_v; |
361 | | if (raw_eth == NULL || pktsize == NULL || numpkts <= 0) { |
362 | | SCLogError("The arrays cant be null, and the number" |
363 | | " of packets should be grater thatn zero"); |
364 | | return NULL; |
365 | | } |
366 | | Packet **p = NULL; |
367 | | p = SCMalloc(sizeof(Packet *) * numpkts); |
368 | | if (unlikely(p == NULL)) |
369 | | return NULL; |
370 | | |
371 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
372 | | memset(&th_v, 0, sizeof(th_v)); |
373 | | |
374 | | int i = 0; |
375 | | for (; i < numpkts; i++) { |
376 | | p[i] = PacketGetFromAlloc(); |
377 | | if (p[i] == NULL) { |
378 | | SCFree(p); |
379 | | return NULL; |
380 | | } |
381 | | DecodeEthernet(&th_v, &dtv, p[i], raw_eth[i], pktsize[i]); |
382 | | } |
383 | | return p; |
384 | | } |
385 | | |
386 | | /** |
387 | | * \brief UTHBuildPacketFromEth is a wrapper that build a packet for the rawbytes |
388 | | * |
389 | | * \param raw_eth pointer to the rawbytes containing an ethernet packet |
390 | | * (and any other headers inside) |
391 | | * \param pktsize pointer to the length of the payload |
392 | | * |
393 | | * \retval Packet pointer to the built in packet; NULL if something fail |
394 | | */ |
395 | | Packet *UTHBuildPacketFromEth(uint8_t *raw_eth, uint16_t pktsize) |
396 | | { |
397 | | DecodeThreadVars dtv; |
398 | | ThreadVars th_v; |
399 | | Packet *p = PacketGetFromAlloc(); |
400 | | if (unlikely(p == NULL)) |
401 | | return NULL; |
402 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
403 | | memset(&th_v, 0, sizeof(th_v)); |
404 | | |
405 | | DecodeEthernet(&th_v, &dtv, p, raw_eth, pktsize); |
406 | | return p; |
407 | | } |
408 | | |
409 | | /** |
410 | | * \brief UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs |
411 | | * and defaulting ports |
412 | | * |
413 | | * \param payload pointer to the payload buffer |
414 | | * \param payload_len pointer to the length of the payload |
415 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
416 | | * |
417 | | * \retval Packet pointer to the built in packet |
418 | | */ |
419 | | Packet *UTHBuildPacketSrcDst(uint8_t *payload, uint16_t payload_len, |
420 | | uint8_t ipproto, const char *src, const char *dst) |
421 | | { |
422 | | return UTHBuildPacketReal(payload, payload_len, ipproto, |
423 | | src, dst, |
424 | | 41424, 80); |
425 | | } |
426 | | |
427 | | /** |
428 | | * \brief UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs |
429 | | * and defaulting ports (IPV6) |
430 | | * |
431 | | * \param payload pointer to the payload buffer |
432 | | * \param payload_len pointer to the length of the payload |
433 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
434 | | * |
435 | | * \retval Packet pointer to the built in packet |
436 | | */ |
437 | | Packet *UTHBuildPacketIPV6SrcDst(uint8_t *payload, uint16_t payload_len, |
438 | | uint8_t ipproto, const char *src, const char *dst) |
439 | | { |
440 | | return UTHBuildPacketIPV6Real(payload, payload_len, ipproto, |
441 | | src, dst, |
442 | | 41424, 80); |
443 | | } |
444 | | |
445 | | /** |
446 | | * \brief UTHBuildPacketSrcDstPorts is a wrapper that build packets specifying |
447 | | * src and dst ports and defaulting IPs |
448 | | * |
449 | | * \param payload pointer to the payload buffer |
450 | | * \param payload_len pointer to the length of the payload |
451 | | * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP |
452 | | * |
453 | | * \retval Packet pointer to the built in packet |
454 | | */ |
455 | | Packet *UTHBuildPacketSrcDstPorts(uint8_t *payload, uint16_t payload_len, |
456 | | uint8_t ipproto, uint16_t sport, uint16_t dport) |
457 | | { |
458 | | return UTHBuildPacketReal(payload, payload_len, ipproto, |
459 | | "192.168.1.5", "192.168.1.1", |
460 | | sport, dport); |
461 | | } |
462 | | |
463 | | /** |
464 | | * \brief UTHFreePackets: function to release the allocated data |
465 | | * from UTHBuildPacket and the packet itself |
466 | | * |
467 | | * \param p pointer to the Packet |
468 | | */ |
469 | | void UTHFreePackets(Packet **p, int numpkts) |
470 | | { |
471 | | if (p == NULL) |
472 | | return; |
473 | | |
474 | | int i = 0; |
475 | | for (; i < numpkts; i++) { |
476 | | UTHFreePacket(p[i]); |
477 | | } |
478 | | } |
479 | | |
480 | | /** |
481 | | * \brief UTHFreePacket: function to release the allocated data |
482 | | * from UTHBuildPacket and the packet itself |
483 | | * |
484 | | * \param p pointer to the Packet |
485 | | */ |
486 | | void UTHFreePacket(Packet *p) |
487 | | { |
488 | | if (p == NULL) |
489 | | return; |
490 | | #if 0 // VJ we now use one buffer |
491 | | switch (p->proto) { |
492 | | case IPPROTO_UDP: |
493 | | if (p->udph != NULL) |
494 | | SCFree(p->udph); |
495 | | if (p->ip4h != NULL) |
496 | | SCFree(p->ip4h); |
497 | | break; |
498 | | case IPPROTO_TCP: |
499 | | if (p->tcph != NULL) |
500 | | SCFree(p->tcph); |
501 | | if (p->ip4h != NULL) |
502 | | SCFree(p->ip4h); |
503 | | break; |
504 | | case IPPROTO_ICMP: |
505 | | if (p->ip4h != NULL) |
506 | | SCFree(p->ip4h); |
507 | | break; |
508 | | /* TODO: Add more protocols */ |
509 | | } |
510 | | #endif |
511 | | SCFree(p); |
512 | | } |
513 | | |
514 | | void UTHAssignFlow(Packet *p, Flow *f) |
515 | | { |
516 | | if (p && f) { |
517 | | p->flow = f; |
518 | | p->flags |= PKT_HAS_FLOW; |
519 | | } |
520 | | } |
521 | | |
522 | | Flow *UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp) |
523 | | { |
524 | | return TestHelperBuildFlow(family, src, dst, sp, dp); |
525 | | } |
526 | | |
527 | | void UTHFreeFlow(Flow *flow) |
528 | | { |
529 | | if (flow != NULL) { |
530 | | SCFree(flow);//FlowFree(flow); |
531 | | } |
532 | | } |
533 | | |
534 | | int UTHAddStreamToFlow(Flow *f, int direction, |
535 | | uint8_t *data, uint32_t data_len) |
536 | | { |
537 | | FAIL_IF_NULL(f); |
538 | | FAIL_IF_NOT(f->proto == IPPROTO_TCP); |
539 | | FAIL_IF_NULL(f->protoctx); |
540 | | TcpSession *ssn = f->protoctx; |
541 | | |
542 | | StreamingBufferSegment seg; |
543 | | TcpStream *stream = direction == 0 ? &ssn->client : &ssn->server; |
544 | | int r = StreamingBufferAppend(&stream->sb, &stream_config.sbcnf, &seg, data, data_len); |
545 | | FAIL_IF_NOT(r == 0); |
546 | | stream->last_ack += data_len; |
547 | | return 1; |
548 | | } |
549 | | |
550 | | int UTHAddSessionToFlow(Flow *f, |
551 | | uint32_t ts_isn, |
552 | | uint32_t tc_isn) |
553 | | { |
554 | | FAIL_IF_NULL(f); |
555 | | |
556 | | TcpSession *ssn = SCCalloc(1, sizeof(*ssn)); |
557 | | FAIL_IF_NULL(ssn); |
558 | | |
559 | | StreamingBuffer x = STREAMING_BUFFER_INITIALIZER; |
560 | | ssn->client.sb = x; |
561 | | ssn->server.sb = x; |
562 | | |
563 | | ssn->client.isn = ts_isn; |
564 | | ssn->server.isn = tc_isn; |
565 | | |
566 | | f->protoctx = ssn; |
567 | | return 1; |
568 | | } |
569 | | |
570 | | int UTHRemoveSessionFromFlow(Flow *f) |
571 | | { |
572 | | FAIL_IF_NULL(f); |
573 | | FAIL_IF_NOT(f->proto == IPPROTO_TCP); |
574 | | TcpSession *ssn = f->protoctx; |
575 | | FAIL_IF_NULL(ssn); |
576 | | StreamTcpSessionCleanup(ssn); |
577 | | SCFree(ssn); |
578 | | f->protoctx = NULL; |
579 | | return 1; |
580 | | } |
581 | | |
582 | | /** |
583 | | * \brief UTHGenericTest: function that perform a generic check taking care of |
584 | | * as maximum common unittest elements as possible. |
585 | | * It will create a detection engine, append an array |
586 | | * of signatures an check the expected results for each |
587 | | * of them, it check matches for an array of packets |
588 | | * |
589 | | * \param pkt pointer to the array of packets |
590 | | * \param numpkts number of packets to match |
591 | | * \param sigs array of char* pointing to signatures to load |
592 | | * \param numsigs number of signatures to load and check |
593 | | * \param results pointer to arrays of numbers, each of them foreach packet |
594 | | * to check if sids matches that packet as expected with |
595 | | * that number of times or not. The size of results should be |
596 | | * numpkts * numsigs * sizeof(uint16_t *) |
597 | | * |
598 | | * Example: |
599 | | * result[1][3] would mean the number of times the pkt[1] |
600 | | * match the sid[3] |
601 | | * |
602 | | * \retval int 1 if the match of all the sids is the specified has the |
603 | | * specified results; 0 if not |
604 | | */ |
605 | | int UTHGenericTest(Packet **pkt, int numpkts, const char *sigs[], uint32_t sids[], uint32_t *results, int numsigs) |
606 | | { |
607 | | |
608 | | int result = 0; |
609 | | if (pkt == NULL || sigs == NULL || numpkts == 0 |
610 | | || sids == NULL || results == NULL || numsigs == 0) { |
611 | | SCLogError("Arguments invalid, that the pointer/arrays are not NULL, and the number of " |
612 | | "signatures and packets is > 0"); |
613 | | goto end; |
614 | | } |
615 | | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
616 | | if (de_ctx == NULL) { |
617 | | goto end; |
618 | | } |
619 | | de_ctx->flags |= DE_QUIET; |
620 | | |
621 | | if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) |
622 | | goto cleanup; |
623 | | |
624 | | result = UTHMatchPacketsWithResults(de_ctx, pkt, numpkts, sids, results, numsigs); |
625 | | |
626 | | cleanup: |
627 | | DetectEngineCtxFree(de_ctx); |
628 | | end: |
629 | | return result; |
630 | | } |
631 | | |
632 | | /** |
633 | | * \brief UTHCheckPacketMatches: function to check if a packet match some sids |
634 | | * |
635 | | * |
636 | | * \param p pointer to the Packet |
637 | | * \param sigs array of char* pointing to signatures to load |
638 | | * \param numsigs number of signatures to load from the array |
639 | | * \param results pointer to an array of numbers to check if sids matches |
640 | | * that number of times or not. |
641 | | * |
642 | | * \retval int 1 if the match of all the sids is the specified has the |
643 | | * specified results; 0 if not |
644 | | */ |
645 | | int UTHCheckPacketMatchResults(Packet *p, uint32_t sids[], uint32_t results[], int numsigs) |
646 | | { |
647 | | if (p == NULL || sids == NULL) { |
648 | | SCLogError("Arguments invalid, check if the " |
649 | | "packet is NULL, and if the array contain sids is set"); |
650 | | return 0; |
651 | | } |
652 | | |
653 | | int i = 0; |
654 | | int res = 1; |
655 | | for (; i < numsigs; i++) { |
656 | | uint32_t r = PacketAlertCheck(p, sids[i]); |
657 | | if (r != results[i]) { |
658 | | SCLogInfo("Sid %" PRIu32 " matched %" PRIu32 " times, and not %" PRIu32 " as expected", |
659 | | sids[i], r, results[i]); |
660 | | res = 0; |
661 | | } else { |
662 | | SCLogInfo("Sid %" PRIu32 " matched %" PRIu32 " times, as expected", sids[i], r); |
663 | | } |
664 | | } |
665 | | return res; |
666 | | } |
667 | | |
668 | | /** |
669 | | * \brief UTHAppendSigs: Add sigs to the detection_engine checking for errors |
670 | | * |
671 | | * \param de_ctx pointer to the DetectEngineCtx used |
672 | | * \param sigs array of char* pointing to signatures to load |
673 | | * \param numsigs number of signatures to load from the array |
674 | | * (size of the array) |
675 | | * |
676 | | * \retval int 0 if we have errors; 1 if all the signatures loaded successfully |
677 | | */ |
678 | | int UTHAppendSigs(DetectEngineCtx *de_ctx, const char *sigs[], int numsigs) |
679 | | { |
680 | | BUG_ON(de_ctx == NULL); |
681 | | BUG_ON(numsigs <= 0); |
682 | | BUG_ON(sigs == NULL); |
683 | | |
684 | | for (int i = 0; i < numsigs; i++) { |
685 | | if (sigs[i] == NULL) { |
686 | | SCLogError("Check the signature" |
687 | | " at position %d", |
688 | | i); |
689 | | return 0; |
690 | | } |
691 | | Signature *s = DetectEngineAppendSig(de_ctx, sigs[i]); |
692 | | if (s == NULL) { |
693 | | SCLogError("Check the signature at" |
694 | | " position %d (%s)", |
695 | | i, sigs[i]); |
696 | | return 0; |
697 | | } |
698 | | } |
699 | | return 1; |
700 | | } |
701 | | |
702 | | /** |
703 | | * \test UTHMatchPacketsWithResults Match a packet or a array of packets against sigs |
704 | | * of a de_ctx, checking that each signature matches X times for certain packets |
705 | | * |
706 | | * \param de_ctx pointer with the signatures loaded |
707 | | * \param p pointer to the array of packets |
708 | | * \param num_packets number of packets in the array |
709 | | * |
710 | | * \retval return 1 if all goes well |
711 | | * \retval return 0 if something fail |
712 | | */ |
713 | | int UTHMatchPacketsWithResults(DetectEngineCtx *de_ctx, Packet **p, int num_packets, uint32_t sids[], uint32_t *results, int numsigs) |
714 | | { |
715 | | BUG_ON(de_ctx == NULL); |
716 | | BUG_ON(p == NULL); |
717 | | |
718 | | int result = 0; |
719 | | DecodeThreadVars dtv; |
720 | | ThreadVars th_v; |
721 | | DetectEngineThreadCtx *det_ctx = NULL; |
722 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
723 | | memset(&th_v, 0, sizeof(th_v)); |
724 | | |
725 | | SigGroupBuild(de_ctx); |
726 | | DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); |
727 | | |
728 | | for (int i = 0; i < num_packets; i++) { |
729 | | SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); |
730 | | if (UTHCheckPacketMatchResults(p[i], sids, &results[(i * numsigs)], numsigs) == 0) |
731 | | goto cleanup; |
732 | | } |
733 | | |
734 | | result = 1; |
735 | | cleanup: |
736 | | DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); |
737 | | return result; |
738 | | } |
739 | | |
740 | | /** |
741 | | * \test UTHMatchPackets Match a packet or a array of packets against sigs |
742 | | * of a de_ctx, but note that the return value doesn't mean that we have a |
743 | | * match, we have to check it later with PacketAlertCheck() |
744 | | * |
745 | | * \param de_ctx pointer with the signatures loaded |
746 | | * \param p pointer to the array of packets |
747 | | * \param num_packets number of packets in the array |
748 | | * |
749 | | * \retval return 1 if all goes well |
750 | | * \retval return 0 if something fail |
751 | | */ |
752 | | int UTHMatchPackets(DetectEngineCtx *de_ctx, Packet **p, int num_packets) |
753 | | { |
754 | | BUG_ON(de_ctx == NULL); |
755 | | BUG_ON(p == NULL); |
756 | | int result = 1; |
757 | | DecodeThreadVars dtv; |
758 | | ThreadVars th_v; |
759 | | DetectEngineThreadCtx *det_ctx = NULL; |
760 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
761 | | memset(&th_v, 0, sizeof(th_v)); |
762 | | SCSigRegisterSignatureOrderingFuncs(de_ctx); |
763 | | SCSigOrderSignatures(de_ctx); |
764 | | SCSigSignatureOrderingModuleCleanup(de_ctx); |
765 | | SigGroupBuild(de_ctx); |
766 | | DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); |
767 | | |
768 | | for (int i = 0; i < num_packets; i++) |
769 | | SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); |
770 | | |
771 | | /* Here we don't check if the packet matched or not, because |
772 | | * the de_ctx can have multiple signatures, and some of them may match |
773 | | * and others may not. That check will be outside |
774 | | */ |
775 | | DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); |
776 | | if (de_ctx != NULL) SigGroupCleanup(de_ctx); |
777 | | return result; |
778 | | } |
779 | | |
780 | | /** |
781 | | * \test Test if a packet match a signature given as string and a mpm_type |
782 | | * Hint: Useful for unittests with only one packet and one signature |
783 | | * |
784 | | * \param sig pointer to the string signature to test |
785 | | * \param sid sid number of the signature |
786 | | * |
787 | | * \retval return 1 if match |
788 | | * \retval return 0 if not |
789 | | */ |
790 | | int UTHPacketMatchSigMpm(Packet *p, char *sig, uint16_t mpm_type) |
791 | | { |
792 | | SCEnter(); |
793 | | |
794 | | int result = 0; |
795 | | |
796 | | DecodeThreadVars dtv; |
797 | | ThreadVars th_v; |
798 | | DetectEngineThreadCtx *det_ctx = NULL; |
799 | | |
800 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
801 | | memset(&th_v, 0, sizeof(th_v)); |
802 | | |
803 | | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
804 | | if (de_ctx == NULL) { |
805 | | printf("de_ctx == NULL: "); |
806 | | goto end; |
807 | | } |
808 | | |
809 | | de_ctx->flags |= DE_QUIET; |
810 | | de_ctx->mpm_matcher = mpm_type; |
811 | | |
812 | | de_ctx->sig_list = SigInit(de_ctx, sig); |
813 | | if (de_ctx->sig_list == NULL) { |
814 | | printf("signature == NULL: "); |
815 | | goto end; |
816 | | } |
817 | | |
818 | | SigGroupBuild(de_ctx); |
819 | | DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); |
820 | | |
821 | | SigMatchSignatures(&th_v, de_ctx, det_ctx, p); |
822 | | if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) { |
823 | | printf("signature didn't alert: "); |
824 | | goto end; |
825 | | } |
826 | | |
827 | | result = 1; |
828 | | end: |
829 | | DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); |
830 | | DetectEngineCtxFree(de_ctx); |
831 | | SCReturnInt(result); |
832 | | } |
833 | | |
834 | | /** |
835 | | * \test Test if a packet match a signature given as string |
836 | | * Hint: Useful for unittests with only one packet and one signature |
837 | | * |
838 | | * \param sig pointer to the string signature to test |
839 | | * \param sid sid number of the signature |
840 | | * |
841 | | * \retval return 1 if match |
842 | | * \retval return 0 if not |
843 | | */ |
844 | | int UTHPacketMatchSig(Packet *p, const char *sig) |
845 | | { |
846 | | int result = 1; |
847 | | |
848 | | DecodeThreadVars dtv; |
849 | | |
850 | | ThreadVars th_v; |
851 | | DetectEngineThreadCtx *det_ctx = NULL; |
852 | | |
853 | | memset(&dtv, 0, sizeof(DecodeThreadVars)); |
854 | | memset(&th_v, 0, sizeof(th_v)); |
855 | | |
856 | | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
857 | | if (de_ctx == NULL) { |
858 | | result=0; |
859 | | goto end; |
860 | | } |
861 | | |
862 | | de_ctx->flags |= DE_QUIET; |
863 | | |
864 | | de_ctx->sig_list = SigInit(de_ctx, sig); |
865 | | if (de_ctx->sig_list == NULL) { |
866 | | result = 0; |
867 | | goto end; |
868 | | } |
869 | | |
870 | | SigGroupBuild(de_ctx); |
871 | | DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); |
872 | | |
873 | | SigMatchSignatures(&th_v, de_ctx, det_ctx, p); |
874 | | if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) { |
875 | | result = 0; |
876 | | goto end; |
877 | | } |
878 | | |
879 | | end: |
880 | | if (de_ctx) { |
881 | | SigGroupCleanup(de_ctx); |
882 | | SigCleanSignatures(de_ctx); |
883 | | } |
884 | | |
885 | | if (det_ctx != NULL) |
886 | | DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); |
887 | | if (de_ctx != NULL) |
888 | | DetectEngineCtxFree(de_ctx); |
889 | | |
890 | | return result; |
891 | | } |
892 | | |
893 | | uint32_t UTHBuildPacketOfFlows(uint32_t start, uint32_t end, uint8_t dir) |
894 | | { |
895 | | FlowLookupStruct fls; |
896 | | memset(&fls, 0, sizeof(fls)); |
897 | | ThreadVars tv; |
898 | | memset(&tv, 0, sizeof(tv)); |
899 | | |
900 | | uint32_t i = start; |
901 | | uint8_t payload[] = "Payload"; |
902 | | for (; i < end; i++) { |
903 | | Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); |
904 | | if (dir == 0) { |
905 | | p->src.addr_data32[0] = i; |
906 | | p->dst.addr_data32[0] = i + 1; |
907 | | } else { |
908 | | p->src.addr_data32[0] = i + 1; |
909 | | p->dst.addr_data32[0] = i; |
910 | | } |
911 | | FlowHandlePacket(&tv, &fls, p); |
912 | | if (p->flow != NULL) { |
913 | | FLOWLOCK_UNLOCK(p->flow); |
914 | | } |
915 | | |
916 | | /* Now the queues should be updated */ |
917 | | UTHFreePacket(p); |
918 | | } |
919 | | |
920 | | Flow *f; |
921 | | while ((f = FlowQueuePrivateGetFromTop(&fls.spare_queue))) { |
922 | | FlowFree(f); |
923 | | } |
924 | | while ((f = FlowQueuePrivateGetFromTop(&fls.work_queue))) { |
925 | | FlowFree(f); |
926 | | } |
927 | | |
928 | | return i; |
929 | | } |
930 | | |
931 | | /** \brief parser a sig and see if the expected result is correct */ |
932 | | int UTHParseSignature(const char *str, bool expect) |
933 | | { |
934 | | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
935 | | FAIL_IF_NULL(de_ctx); |
936 | | de_ctx->flags |= DE_QUIET; |
937 | | |
938 | | Signature *s = DetectEngineAppendSig(de_ctx, str); |
939 | | if (expect) |
940 | | FAIL_IF_NULL(s); |
941 | | else |
942 | | FAIL_IF_NOT_NULL(s); |
943 | | |
944 | | DetectEngineCtxFree(de_ctx); |
945 | | PASS; |
946 | | } |
947 | | |
948 | | /* |
949 | | * unittests for the unittest helpers |
950 | | */ |
951 | | |
952 | | /** |
953 | | * \brief CheckUTHTestPacket wrapper to check packets for unittests |
954 | | */ |
955 | | static int CheckUTHTestPacket(Packet *p, uint8_t ipproto) |
956 | | { |
957 | | uint16_t sport = 41424; |
958 | | uint16_t dport = 80; |
959 | | uint8_t payload[] = "Payload"; |
960 | | |
961 | | uint8_t len = sizeof(payload); |
962 | | |
963 | | if (p == NULL) |
964 | | return 0; |
965 | | |
966 | | if (p->payload_len != len) |
967 | | return 0; |
968 | | |
969 | | if (strncmp((char *)payload, (char *)p->payload, len) != 0) |
970 | | return 0; |
971 | | |
972 | | if (p->src.family != AF_INET) |
973 | | return 0; |
974 | | if (p->dst.family != AF_INET) |
975 | | return 0; |
976 | | if (p->proto != ipproto) |
977 | | return 0; |
978 | | |
979 | | switch(ipproto) { |
980 | | case IPPROTO_UDP: |
981 | | if (p->udph == NULL) |
982 | | return 0; |
983 | | if (p->udph->uh_sport != sport) |
984 | | return 0; |
985 | | if (p->udph->uh_dport != dport) |
986 | | return 0; |
987 | | break; |
988 | | case IPPROTO_TCP: |
989 | | if (p->tcph == NULL) |
990 | | return 0; |
991 | | if (SCNtohs(p->tcph->th_sport) != sport) |
992 | | return 0; |
993 | | if (SCNtohs(p->tcph->th_dport) != dport) |
994 | | return 0; |
995 | | break; |
996 | | } |
997 | | return 1; |
998 | | } |
999 | | |
1000 | | #ifdef HAVE_MEMMEM |
1001 | | #include <string.h> |
1002 | | void * UTHmemsearch(const void *big, size_t big_len, const void *little, size_t little_len) { |
1003 | | return memmem(big, big_len, little, little_len); |
1004 | | } |
1005 | | #else |
1006 | | #include "util-spm-bs.h" |
1007 | | void * UTHmemsearch(const void *big, size_t big_len, const void *little, size_t little_len) { |
1008 | | return BasicSearch(big, big_len, little, little_len); |
1009 | | } |
1010 | | #endif //HAVE_MEMMEM |
1011 | | |
1012 | | /** |
1013 | | * \brief UTHBuildPacketRealTest01 wrapper to check packets for unittests |
1014 | | */ |
1015 | | static int UTHBuildPacketRealTest01(void) |
1016 | | { |
1017 | | uint8_t payload[] = "Payload"; |
1018 | | |
1019 | | Packet *p = UTHBuildPacketReal(payload, sizeof(payload), IPPROTO_TCP, |
1020 | | "192.168.1.5", "192.168.1.1", 41424, 80); |
1021 | | |
1022 | | int ret = CheckUTHTestPacket(p, IPPROTO_TCP); |
1023 | | UTHFreePacket(p); |
1024 | | |
1025 | | return ret; |
1026 | | } |
1027 | | |
1028 | | /** |
1029 | | * \brief UTHBuildPacketRealTest02 wrapper to check packets for unittests |
1030 | | */ |
1031 | | static int UTHBuildPacketRealTest02(void) |
1032 | | { |
1033 | | uint8_t payload[] = "Payload"; |
1034 | | |
1035 | | Packet *p = UTHBuildPacketReal(payload, sizeof(payload), IPPROTO_UDP, |
1036 | | "192.168.1.5", "192.168.1.1", 41424, 80); |
1037 | | |
1038 | | int ret = CheckUTHTestPacket(p, IPPROTO_UDP); |
1039 | | UTHFreePacket(p); |
1040 | | return ret; |
1041 | | } |
1042 | | |
1043 | | /** |
1044 | | * \brief UTHBuildPacketTest01 wrapper to check packets for unittests |
1045 | | */ |
1046 | | static int UTHBuildPacketTest01(void) |
1047 | | { |
1048 | | uint8_t payload[] = "Payload"; |
1049 | | |
1050 | | Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); |
1051 | | |
1052 | | int ret = CheckUTHTestPacket(p, IPPROTO_TCP); |
1053 | | UTHFreePacket(p); |
1054 | | |
1055 | | return ret; |
1056 | | } |
1057 | | |
1058 | | /** |
1059 | | * \brief UTHBuildPacketTest02 wrapper to check packets for unittests |
1060 | | */ |
1061 | | static int UTHBuildPacketTest02(void) |
1062 | | { |
1063 | | uint8_t payload[] = "Payload"; |
1064 | | |
1065 | | Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_UDP); |
1066 | | |
1067 | | int ret = CheckUTHTestPacket(p, IPPROTO_UDP); |
1068 | | UTHFreePacket(p); |
1069 | | |
1070 | | return ret; |
1071 | | } |
1072 | | |
1073 | | /** |
1074 | | * \brief UTHBuildPacketOfFlowsTest01 wrapper to check packets for unittests |
1075 | | */ |
1076 | | static int UTHBuildPacketOfFlowsTest01(void) |
1077 | | { |
1078 | | int result = 0; |
1079 | | |
1080 | | FlowInitConfig(FLOW_QUIET); |
1081 | | uint32_t flow_spare_q_len = FlowSpareGetPoolSize(); |
1082 | | |
1083 | | UTHBuildPacketOfFlows(0, 100, 0); |
1084 | | |
1085 | | if (FlowSpareGetPoolSize() != flow_spare_q_len - 100) |
1086 | | result = 0; |
1087 | | else |
1088 | | result = 1; |
1089 | | FlowShutdown(); |
1090 | | |
1091 | | return result; |
1092 | | } |
1093 | | |
1094 | | |
1095 | | /** |
1096 | | * \brief UTHBuildPacketSrcDstTest01 wrapper to check packets for unittests |
1097 | | */ |
1098 | | static int UTHBuildPacketSrcDstTest01(void) |
1099 | | { |
1100 | | uint8_t payload[] = "Payload"; |
1101 | | |
1102 | | Packet *p = UTHBuildPacketSrcDst(payload, sizeof(payload), IPPROTO_TCP, |
1103 | | "192.168.1.5", "192.168.1.1"); |
1104 | | |
1105 | | int ret = CheckUTHTestPacket(p, IPPROTO_TCP); |
1106 | | UTHFreePacket(p); |
1107 | | |
1108 | | return ret; |
1109 | | } |
1110 | | |
1111 | | /** |
1112 | | * \brief UTHBuildPacketSrcDstTest02 wrapper to check packets for unittests |
1113 | | */ |
1114 | | static int UTHBuildPacketSrcDstTest02(void) |
1115 | | { |
1116 | | uint8_t payload[] = "Payload"; |
1117 | | |
1118 | | Packet *p = UTHBuildPacketSrcDst(payload, sizeof(payload), IPPROTO_UDP, |
1119 | | "192.168.1.5", "192.168.1.1"); |
1120 | | |
1121 | | int ret = CheckUTHTestPacket(p, IPPROTO_UDP); |
1122 | | UTHFreePacket(p); |
1123 | | |
1124 | | return ret; |
1125 | | } |
1126 | | |
1127 | | /** |
1128 | | * \brief UTHBuildPacketSrcDstPortsTest01 wrapper to check packets for unittests |
1129 | | */ |
1130 | | static int UTHBuildPacketSrcDstPortsTest01(void) |
1131 | | { |
1132 | | uint8_t payload[] = "Payload"; |
1133 | | |
1134 | | Packet *p = UTHBuildPacketSrcDstPorts(payload, sizeof(payload), IPPROTO_TCP, |
1135 | | 41424, 80); |
1136 | | |
1137 | | int ret = CheckUTHTestPacket(p, IPPROTO_TCP); |
1138 | | UTHFreePacket(p); |
1139 | | |
1140 | | return ret; |
1141 | | } |
1142 | | |
1143 | | /** |
1144 | | * \brief UTHBuildPacketSrcDstPortsTest02 wrapper to check packets for unittests |
1145 | | */ |
1146 | | static int UTHBuildPacketSrcDstPortsTest02(void) |
1147 | | { |
1148 | | uint8_t payload[] = "Payload"; |
1149 | | |
1150 | | Packet *p = UTHBuildPacketSrcDstPorts(payload, sizeof(payload), IPPROTO_UDP, |
1151 | | 41424, 80); |
1152 | | |
1153 | | int ret = CheckUTHTestPacket(p, IPPROTO_UDP); |
1154 | | UTHFreePacket(p); |
1155 | | |
1156 | | return ret; |
1157 | | } |
1158 | | |
1159 | | #endif /* UNITTESTS */ |
1160 | | |
1161 | | void UTHRegisterTests(void) |
1162 | 0 | { |
1163 | | #ifdef UNITTESTS |
1164 | | UtRegisterTest("UTHBuildPacketRealTest01", UTHBuildPacketRealTest01); |
1165 | | UtRegisterTest("UTHBuildPacketRealTest02", UTHBuildPacketRealTest02); |
1166 | | UtRegisterTest("UTHBuildPacketTest01", UTHBuildPacketTest01); |
1167 | | UtRegisterTest("UTHBuildPacketTest02", UTHBuildPacketTest02); |
1168 | | UtRegisterTest("UTHBuildPacketSrcDstTest01", UTHBuildPacketSrcDstTest01); |
1169 | | UtRegisterTest("UTHBuildPacketSrcDstTest02", UTHBuildPacketSrcDstTest02); |
1170 | | UtRegisterTest("UTHBuildPacketSrcDstPortsTest01", |
1171 | | UTHBuildPacketSrcDstPortsTest01); |
1172 | | UtRegisterTest("UTHBuildPacketSrcDstPortsTest02", |
1173 | | UTHBuildPacketSrcDstPortsTest02); |
1174 | | UtRegisterTest("UTHBuildPacketOfFlowsTest01", UTHBuildPacketOfFlowsTest01); |
1175 | | |
1176 | | #endif /* UNITTESTS */ |
1177 | 0 | } |
1178 | | |