1 //--------------------------------------------------------------------------
2 // Copyright (C) 2015-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // ips_http.cc author Tom Peters <thopeter@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "ips_http.h"
25
26 #include "framework/cursor.h"
27 #include "hash/hash_key_operations.h"
28 #include "log/messages.h"
29 #include "parser/parse_utils.h"
30 #include "protocols/packet.h"
31 #include "service_inspectors/http2_inspect/http2_flow_data.h"
32
33 #include "http_common.h"
34 #include "http_enum.h"
35 #include "http_flow_data.h"
36 #include "http_inspect.h"
37 #include "http_msg_head_shared.h"
38 #include "http_param.h"
39
40 using namespace snort;
41 using namespace HttpCommon;
42 using namespace HttpEnums;
43
44 THREAD_LOCAL std::array<ProfileStats, PSI_MAX> HttpRuleOptModule::http_ps;
45
46 const std::string hdrs_num_range = "0:" + std::to_string(HttpMsgHeadShared::MAX_HEADERS);
47
begin(const char *,int,SnortConfig *)48 bool HttpRuleOptModule::begin(const char*, int, SnortConfig*)
49 {
50 para_list.reset();
51 sub_id = 0;
52 form = 0;
53 switch (rule_opt_index)
54 {
55 case HTTP_BUFFER_RAW_STATUS:
56 case HTTP_BUFFER_STAT_CODE:
57 case HTTP_BUFFER_STAT_MSG:
58 inspect_section = IS_HEADER;
59 break;
60 case HTTP_BUFFER_COOKIE:
61 case HTTP_BUFFER_HEADER:
62 case HTTP_BUFFER_METHOD:
63 case HTTP_BUFFER_PARAM:
64 case HTTP_BUFFER_RAW_COOKIE:
65 case HTTP_BUFFER_RAW_HEADER:
66 case HTTP_BUFFER_RAW_REQUEST:
67 case HTTP_BUFFER_RAW_URI:
68 case HTTP_BUFFER_TRUE_IP:
69 case HTTP_BUFFER_URI:
70 case HTTP_BUFFER_VERSION:
71 case HTTP_RANGE_NUM_HDRS:
72 inspect_section = IS_FLEX_HEADER;
73 break;
74 case HTTP_BUFFER_CLIENT_BODY:
75 case HTTP_BUFFER_RAW_BODY:
76 case BUFFER_JS_DATA:
77 inspect_section = IS_BODY;
78 break;
79 case HTTP_BUFFER_RAW_TRAILER:
80 case HTTP_BUFFER_TRAILER:
81 case HTTP_RANGE_NUM_TRAILERS:
82 inspect_section = IS_TRAILER;
83 break;
84 default:
85 assert(false);
86 }
87 return true;
88 }
89
set(const char *,Value & v,SnortConfig *)90 bool HttpRuleOptModule::set(const char*, Value& v, SnortConfig*)
91 {
92 if (v.is("field"))
93 {
94 if (sub_id != 0)
95 ParseError("Only specify one header field to match");
96 para_list.field = v.get_string();
97 const int32_t name_size = (para_list.field.size() <= MAX_FIELD_NAME_LENGTH) ?
98 para_list.field.size() : MAX_FIELD_NAME_LENGTH;
99 uint8_t lower_name[MAX_FIELD_NAME_LENGTH];
100 for (int32_t k=0; k < name_size; k++)
101 {
102 lower_name[k] = ((para_list.field[k] < 'A') || (para_list.field[k] > 'Z')) ?
103 para_list.field[k] : para_list.field[k] - ('A' - 'a');
104 }
105 sub_id = str_to_code(lower_name, name_size, HttpMsgHeadShared::header_list);
106 if (sub_id == STAT_OTHER)
107 ParseError("Unrecognized header field name");
108 }
109 else if (v.is("~param"))
110 {
111 std::string bc = v.get_string();
112 bool negated = false;
113 if (!parse_byte_code(bc.c_str(), negated, para_list.param) or negated)
114 ParseError("Invalid http_param");
115 }
116 else if (v.is("nocase"))
117 {
118 para_list.nocase = true;
119 }
120 else if (v.is("request"))
121 {
122 para_list.request = true;
123 form |= FORM_REQUEST;
124 }
125 else if (v.is("with_header"))
126 {
127 para_list.with_header = true;
128 inspect_section = IS_HEADER;
129 }
130 else if (v.is("with_body"))
131 {
132 para_list.with_body = true;
133 inspect_section = IS_BODY;
134 }
135 else if (v.is("with_trailer"))
136 {
137 para_list.with_trailer = true;
138 inspect_section = IS_TRAILER;
139 }
140 else if (v.is("scheme"))
141 {
142 para_list.scheme = true;
143 sub_id = UC_SCHEME;
144 }
145 else if (v.is("host"))
146 {
147 para_list.host = true;
148 sub_id = UC_HOST;
149 }
150 else if (v.is("port"))
151 {
152 para_list.port = true;
153 sub_id = UC_PORT;
154 }
155 else if (v.is("path"))
156 {
157 para_list.path = true;
158 sub_id = UC_PATH;
159 }
160 else if (v.is("query"))
161 {
162 para_list.query = true;
163 sub_id = UC_QUERY;
164 }
165 else if (v.is("fragment"))
166 {
167 para_list.fragment = true;
168 sub_id = UC_FRAGMENT;
169 }
170 else if (v.is("~range"))
171 {
172 return para_list.range.validate(v.get_string(), hdrs_num_range.c_str());
173 }
174 return true;
175 }
176
end(const char *,int,SnortConfig *)177 bool HttpRuleOptModule::end(const char*, int, SnortConfig*)
178 {
179 // Check for option conflicts
180 if (para_list.with_header + para_list.with_body + para_list.with_trailer > 1)
181 ParseError("Only specify one with_ option. Use the one that happens last.");
182 if (((rule_opt_index == HTTP_BUFFER_TRAILER) || (rule_opt_index == HTTP_BUFFER_RAW_TRAILER) || (rule_opt_index == HTTP_RANGE_NUM_TRAILERS)) &&
183 (para_list.with_header || para_list.with_body) &&
184 !para_list.request)
185 ParseError("Trailers with with_ option must also specify request");
186 if (para_list.scheme + para_list.host + para_list.port + para_list.path + para_list.query +
187 para_list.fragment > 1)
188 ParseError("Only specify one part of the URI");
189 if (rule_opt_index == HTTP_BUFFER_PARAM && para_list.param.length() == 0)
190 ParseError("Specify parameter name");
191 return true;
192 }
193
reset()194 void HttpRuleOptModule::HttpRuleParaList::reset()
195 {
196 field.clear();
197 param.clear();
198 nocase = false;
199 request = false;
200 with_header = false;
201 with_body = false;
202 with_trailer = false;
203 scheme = false;
204 host = false;
205 port = false;
206 path = false;
207 query = false;
208 fragment = false;
209 range.init();
210 }
211
hash() const212 uint32_t HttpIpsOption::hash() const
213 {
214 uint32_t a = IpsOption::hash();
215 uint32_t b = (uint32_t)inspect_section;
216 uint32_t c = buffer_info.hash();
217 mix(a,b,c);
218 a += range.hash();
219 finalize(a,b,c);
220 return c;
221 }
222
operator ==(const IpsOption & ips) const223 bool HttpIpsOption::operator==(const IpsOption& ips) const
224 {
225 const HttpIpsOption& hio = static_cast<const HttpIpsOption&>(ips);
226 return IpsOption::operator==(ips) &&
227 inspect_section == hio.inspect_section &&
228 buffer_info == hio.buffer_info &&
229 range == hio.range;
230 }
231
retry(Cursor & current_cursor,const Cursor &)232 bool HttpIpsOption::retry(Cursor& current_cursor, const Cursor&)
233 {
234 if (buffer_info.type == HTTP_BUFFER_PARAM)
235 {
236 HttpCursorData* cd = (HttpCursorData*)current_cursor.get_data(HttpCursorData::id);
237
238 if (cd)
239 return cd->retry();
240 }
241 return false;
242 }
243
eval(Cursor & c,Packet * p)244 IpsOption::EvalStatus HttpIpsOption::eval(Cursor& c, Packet* p)
245 {
246 RuleProfile profile(HttpRuleOptModule::http_ps[psi]);
247
248 if (!p->flow || !p->flow->gadget || (HttpInspect::get_latest_is(p) == IS_NONE))
249 return NO_MATCH;
250
251 const bool section_match =
252 (HttpInspect::get_latest_is(p) == inspect_section) ||
253 ((HttpInspect::get_latest_is(p) == IS_HEADER) && (inspect_section == IS_FLEX_HEADER)) ||
254 ((HttpInspect::get_latest_is(p) == IS_FIRST_BODY) && (inspect_section == IS_BODY)) ||
255 ((HttpInspect::get_latest_src(p) == SRC_CLIENT) && (inspect_section == IS_FLEX_HEADER));
256 if (!section_match)
257 return NO_MATCH;
258
259 const Http2FlowData* const h2i_flow_data =
260 (Http2FlowData*)p->flow->get_flow_data(Http2FlowData::inspector_id);
261
262 const HttpInspect* const hi = (h2i_flow_data != nullptr) ?
263 (HttpInspect*)(p->flow->assistant_gadget) : (HttpInspect*)(p->flow->gadget);
264
265 if (buffer_info.type <= HTTP_BUFFER_MAX)
266 {
267 const Field& http_buffer = hi->http_get_buf(c, p, buffer_info);
268
269 if (http_buffer.length() <= 0)
270 return NO_MATCH;
271
272 c.set(key, http_buffer.start(), http_buffer.length());
273
274 return MATCH;
275 }
276 else
277 {
278 const int32_t num_lines = hi->http_get_num_headers(p, buffer_info);
279 if (num_lines != HttpCommon::STAT_NOT_PRESENT && range.eval(num_lines))
280 return MATCH;
281
282 return NO_MATCH;
283 }
284 }
285
286 //-------------------------------------------------------------------------
287 // http_client_body
288 //-------------------------------------------------------------------------
289
290 #undef IPS_OPT
291 #define IPS_OPT "http_client_body"
292 #undef IPS_HELP
293 #define IPS_HELP "rule option to set the detection cursor to the request body"
294
client_body_mod_ctor()295 static Module* client_body_mod_ctor()
296 {
297 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_CLIENT_BODY, CAT_SET_BODY,
298 PSI_CLIENT_BODY);
299 }
300
301 static const IpsApi client_body_api =
302 {
303 {
304 PT_IPS_OPTION,
305 sizeof(IpsApi),
306 IPSAPI_VERSION,
307 1,
308 API_RESERVED,
309 API_OPTIONS,
310 IPS_OPT,
311 IPS_HELP,
312 client_body_mod_ctor,
313 HttpRuleOptModule::mod_dtor
314 },
315 OPT_TYPE_DETECTION,
316 0, PROTO_BIT__TCP,
317 nullptr,
318 nullptr,
319 nullptr,
320 nullptr,
321 HttpIpsOption::opt_ctor,
322 HttpIpsOption::opt_dtor,
323 nullptr
324 };
325
326 //-------------------------------------------------------------------------
327 // http_cookie
328 //-------------------------------------------------------------------------
329
330 static const Parameter http_cookie_params[] =
331 {
332 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
333 "match against the cookie from the request message even when examining the response" },
334 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
335 "this rule is limited to examining HTTP message headers" },
336 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
337 "parts of this rule examine HTTP message body" },
338 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
339 "parts of this rule examine HTTP message trailers" },
340 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
341 };
342
343 #undef IPS_OPT
344 #define IPS_OPT "http_cookie"
345 #undef IPS_HELP
346 #define IPS_HELP "rule option to set the detection cursor to the HTTP cookie"
347
cookie_mod_ctor()348 static Module* cookie_mod_ctor()
349 {
350 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_COOKIE, CAT_SET_COOKIE, PSI_COOKIE,
351 http_cookie_params);
352 }
353
354 static const IpsApi cookie_api =
355 {
356 {
357 PT_IPS_OPTION,
358 sizeof(IpsApi),
359 IPSAPI_VERSION,
360 1,
361 API_RESERVED,
362 API_OPTIONS,
363 IPS_OPT,
364 IPS_HELP,
365 cookie_mod_ctor,
366 HttpRuleOptModule::mod_dtor
367 },
368 OPT_TYPE_DETECTION,
369 0, PROTO_BIT__TCP,
370 nullptr,
371 nullptr,
372 nullptr,
373 nullptr,
374 HttpIpsOption::opt_ctor,
375 HttpIpsOption::opt_dtor,
376 nullptr
377 };
378
379 //-------------------------------------------------------------------------
380 // http_header
381 //-------------------------------------------------------------------------
382
383 // FIXIT-M add match_unknown option to look at HEAD__UNKNOWN.
384
385 // FIXIT-M if http_header is the fast pattern buffer and the content to be
386 // matched appears in the normalized field but not in the raw field
387 // detection will fail.
388
389 static const Parameter http_header_params[] =
390 {
391 { "field", Parameter::PT_STRING, nullptr, nullptr,
392 "restrict to given header. Header name is case insensitive." },
393 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
394 "match against the headers from the request message even when examining the response" },
395 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
396 "this rule is limited to examining HTTP message headers" },
397 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
398 "parts of this rule examine HTTP message body" },
399 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
400 "parts of this rule examine HTTP message trailers" },
401 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
402 };
403
404 #undef IPS_OPT
405 #define IPS_OPT "http_header"
406 #undef IPS_HELP
407 #define IPS_HELP "rule option to set the detection cursor to the normalized headers"
408
header_mod_ctor()409 static Module* header_mod_ctor()
410 {
411 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_HEADER, CAT_SET_HEADER,
412 PSI_HEADER, http_header_params);
413 }
414
415 static const IpsApi header_api =
416 {
417 {
418 PT_IPS_OPTION,
419 sizeof(IpsApi),
420 IPSAPI_VERSION,
421 1,
422 API_RESERVED,
423 API_OPTIONS,
424 IPS_OPT,
425 IPS_HELP,
426 header_mod_ctor,
427 HttpRuleOptModule::mod_dtor
428 },
429 OPT_TYPE_DETECTION,
430 0, PROTO_BIT__TCP,
431 nullptr,
432 nullptr,
433 nullptr,
434 nullptr,
435 HttpIpsOption::opt_ctor,
436 HttpIpsOption::opt_dtor,
437 nullptr
438 };
439
440 //-------------------------------------------------------------------------
441 // http_method
442 //-------------------------------------------------------------------------
443
444 static const Parameter http_method_params[] =
445 {
446 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
447 "this rule is limited to examining HTTP message headers" },
448 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
449 "parts of this rule examine HTTP message body" },
450 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
451 "parts of this rule examine HTTP message trailers" },
452 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
453 };
454
455 #undef IPS_OPT
456 #define IPS_OPT "http_method"
457 #undef IPS_HELP
458 #define IPS_HELP "rule option to set the detection cursor to the HTTP request method"
459
method_mod_ctor()460 static Module* method_mod_ctor()
461 {
462 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_METHOD, CAT_SET_METHOD, PSI_METHOD,
463 http_method_params);
464 }
465
466 static const IpsApi method_api =
467 {
468 {
469 PT_IPS_OPTION,
470 sizeof(IpsApi),
471 IPSAPI_VERSION,
472 1,
473 API_RESERVED,
474 API_OPTIONS,
475 IPS_OPT,
476 IPS_HELP,
477 method_mod_ctor,
478 HttpRuleOptModule::mod_dtor
479 },
480 OPT_TYPE_DETECTION,
481 0, PROTO_BIT__TCP,
482 nullptr,
483 nullptr,
484 nullptr,
485 nullptr,
486 HttpIpsOption::opt_ctor,
487 HttpIpsOption::opt_dtor,
488 nullptr
489 };
490
491 //-------------------------------------------------------------------------
492 // http_param
493 //-------------------------------------------------------------------------
494
495 static const Parameter http_param_params[] =
496 {
497 { "~param", Parameter::PT_STRING, nullptr, nullptr,
498 "parameter to match" },
499 { "nocase", Parameter::PT_IMPLIED, nullptr, nullptr,
500 "case insensitive match" },
501 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
502 };
503
504 #undef IPS_OPT
505 #define IPS_OPT "http_param"
506 #undef IPS_HELP
507 #define IPS_HELP "rule option to set the detection cursor to the value of the specified HTTP parameter key which may be in the query or body"
508
param_mod_ctor()509 static Module* param_mod_ctor()
510 {
511 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_PARAM, CAT_SET_OTHER, PSI_PARAM,
512 http_param_params);
513 }
514
515 static const IpsApi param_api =
516 {
517 {
518 PT_IPS_OPTION,
519 sizeof(IpsApi),
520 IPSAPI_VERSION,
521 1,
522 API_RESERVED,
523 API_OPTIONS,
524 IPS_OPT,
525 IPS_HELP,
526 param_mod_ctor,
527 HttpRuleOptModule::mod_dtor
528 },
529 OPT_TYPE_DETECTION,
530 0, PROTO_BIT__TCP,
531 nullptr,
532 nullptr,
533 nullptr,
534 nullptr,
535 HttpIpsOption::opt_ctor,
536 HttpIpsOption::opt_dtor,
537 nullptr
538 };
539
540 //-------------------------------------------------------------------------
541 // http_raw_body
542 //-------------------------------------------------------------------------
543
544 #undef IPS_OPT
545 #define IPS_OPT "http_raw_body"
546 #undef IPS_HELP
547 #define IPS_HELP "rule option to set the detection cursor to the unnormalized message body"
548
raw_body_mod_ctor()549 static Module* raw_body_mod_ctor()
550 {
551 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_BODY, CAT_SET_OTHER,
552 PSI_RAW_BODY);
553 }
554
555 static const IpsApi raw_body_api =
556 {
557 {
558 PT_IPS_OPTION,
559 sizeof(IpsApi),
560 IPSAPI_VERSION,
561 1,
562 API_RESERVED,
563 API_OPTIONS,
564 IPS_OPT,
565 IPS_HELP,
566 raw_body_mod_ctor,
567 HttpRuleOptModule::mod_dtor
568 },
569 OPT_TYPE_DETECTION,
570 0, PROTO_BIT__TCP,
571 nullptr,
572 nullptr,
573 nullptr,
574 nullptr,
575 HttpIpsOption::opt_ctor,
576 HttpIpsOption::opt_dtor,
577 nullptr
578 };
579
580 //-------------------------------------------------------------------------
581 // http_raw_cookie
582 //-------------------------------------------------------------------------
583
584 static const Parameter http_raw_cookie_params[] =
585 {
586 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
587 "match against the cookie from the request message even when examining the response" },
588 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
589 "this rule is limited to examining HTTP message headers" },
590 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
591 "parts of this rule examine HTTP message body" },
592 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
593 "parts of this rule examine HTTP message trailers" },
594 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
595 };
596
597 #undef IPS_OPT
598 #define IPS_OPT "http_raw_cookie"
599 #undef IPS_HELP
600 #define IPS_HELP "rule option to set the detection cursor to the unnormalized cookie"
601
raw_cookie_mod_ctor()602 static Module* raw_cookie_mod_ctor()
603 {
604 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_COOKIE, CAT_SET_OTHER,
605 PSI_RAW_COOKIE, http_raw_cookie_params);
606 }
607
608 static const IpsApi raw_cookie_api =
609 {
610 {
611 PT_IPS_OPTION,
612 sizeof(IpsApi),
613 IPSAPI_VERSION,
614 1,
615 API_RESERVED,
616 API_OPTIONS,
617 IPS_OPT,
618 IPS_HELP,
619 raw_cookie_mod_ctor,
620 HttpRuleOptModule::mod_dtor
621 },
622 OPT_TYPE_DETECTION,
623 0, PROTO_BIT__TCP,
624 nullptr,
625 nullptr,
626 nullptr,
627 nullptr,
628 HttpIpsOption::opt_ctor,
629 HttpIpsOption::opt_dtor,
630 nullptr
631 };
632
633 //-------------------------------------------------------------------------
634 // http_raw_header
635 //-------------------------------------------------------------------------
636
637 static const Parameter http_raw_header_params[] =
638 {
639 { "field", Parameter::PT_STRING, nullptr, nullptr,
640 "restrict to given header. Header name is case insensitive." },
641 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
642 "match against the headers from the request message even when examining the response" },
643 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
644 "this rule is limited to examining HTTP message headers" },
645 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
646 "parts of this rule examine HTTP message body" },
647 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
648 "parts of this rule examine HTTP message trailers" },
649 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
650 };
651
652 #undef IPS_OPT
653 #define IPS_OPT "http_raw_header"
654 #undef IPS_HELP
655 #define IPS_HELP "rule option to set the detection cursor to the unnormalized headers"
656
raw_header_mod_ctor()657 static Module* raw_header_mod_ctor()
658 {
659 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_HEADER, CAT_SET_RAW_HEADER,
660 PSI_RAW_HEADER, http_raw_header_params);
661 }
662
663 static const IpsApi raw_header_api =
664 {
665 {
666 PT_IPS_OPTION,
667 sizeof(IpsApi),
668 IPSAPI_VERSION,
669 1,
670 API_RESERVED,
671 API_OPTIONS,
672 IPS_OPT,
673 IPS_HELP,
674 raw_header_mod_ctor,
675 HttpRuleOptModule::mod_dtor
676 },
677 OPT_TYPE_DETECTION,
678 0, PROTO_BIT__TCP,
679 nullptr,
680 nullptr,
681 nullptr,
682 nullptr,
683 HttpIpsOption::opt_ctor,
684 HttpIpsOption::opt_dtor,
685 nullptr
686 };
687
688 //-------------------------------------------------------------------------
689 // http_raw_request
690 //-------------------------------------------------------------------------
691
692 static const Parameter http_raw_request_params[] =
693 {
694 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
695 "this rule is limited to examining HTTP message headers" },
696 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
697 "parts of this rule examine HTTP message body" },
698 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
699 "parts of this rule examine HTTP message trailers" },
700 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
701 };
702
703 #undef IPS_OPT
704 #define IPS_OPT "http_raw_request"
705 #undef IPS_HELP
706 #define IPS_HELP "rule option to set the detection cursor to the unnormalized request line"
707
raw_request_mod_ctor()708 static Module* raw_request_mod_ctor()
709 {
710 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_REQUEST, CAT_SET_OTHER,
711 PSI_RAW_REQUEST, http_raw_request_params);
712 }
713
714 static const IpsApi raw_request_api =
715 {
716 {
717 PT_IPS_OPTION,
718 sizeof(IpsApi),
719 IPSAPI_VERSION,
720 1,
721 API_RESERVED,
722 API_OPTIONS,
723 IPS_OPT,
724 IPS_HELP,
725 raw_request_mod_ctor,
726 HttpRuleOptModule::mod_dtor
727 },
728 OPT_TYPE_DETECTION,
729 0, PROTO_BIT__TCP,
730 nullptr,
731 nullptr,
732 nullptr,
733 nullptr,
734 HttpIpsOption::opt_ctor,
735 HttpIpsOption::opt_dtor,
736 nullptr
737 };
738
739 //-------------------------------------------------------------------------
740 // http_raw_status
741 //-------------------------------------------------------------------------
742
743 static const Parameter http_raw_status_params[] =
744 {
745 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
746 "parts of this rule examine HTTP message body" },
747 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
748 "parts of this rule examine HTTP message trailers" },
749 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
750 };
751
752 #undef IPS_OPT
753 #define IPS_OPT "http_raw_status"
754 #undef IPS_HELP
755 #define IPS_HELP "rule option to set the detection cursor to the unnormalized status line"
756
raw_status_mod_ctor()757 static Module* raw_status_mod_ctor()
758 {
759 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_STATUS, CAT_SET_OTHER,
760 PSI_RAW_STATUS, http_raw_status_params);
761 }
762
763 static const IpsApi raw_status_api =
764 {
765 {
766 PT_IPS_OPTION,
767 sizeof(IpsApi),
768 IPSAPI_VERSION,
769 1,
770 API_RESERVED,
771 API_OPTIONS,
772 IPS_OPT,
773 IPS_HELP,
774 raw_status_mod_ctor,
775 HttpRuleOptModule::mod_dtor
776 },
777 OPT_TYPE_DETECTION,
778 0, PROTO_BIT__TCP,
779 nullptr,
780 nullptr,
781 nullptr,
782 nullptr,
783 HttpIpsOption::opt_ctor,
784 HttpIpsOption::opt_dtor,
785 nullptr
786 };
787
788 //-------------------------------------------------------------------------
789 // http_raw_trailer
790 //-------------------------------------------------------------------------
791
792 static const Parameter http_raw_trailer_params[] =
793 {
794 { "field", Parameter::PT_STRING, nullptr, nullptr,
795 "restrict to given trailer. Trailer name is case insensitive." },
796 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
797 "match against the trailers from the request message even when examining the response" },
798 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
799 "parts of this rule examine HTTP response message headers (must be combined with request)"
800 },
801 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
802 "parts of this rule examine HTTP response message body (must be combined with request)" },
803 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
804 };
805
806 #undef IPS_OPT
807 #define IPS_OPT "http_raw_trailer"
808 #undef IPS_HELP
809 #define IPS_HELP "rule option to set the detection cursor to the unnormalized trailers"
810
raw_trailer_mod_ctor()811 static Module* raw_trailer_mod_ctor()
812 {
813 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_TRAILER, CAT_SET_RAW_HEADER,
814 PSI_RAW_TRAILER, http_raw_trailer_params);
815 }
816
817 static const IpsApi raw_trailer_api =
818 {
819 {
820 PT_IPS_OPTION,
821 sizeof(IpsApi),
822 IPSAPI_VERSION,
823 1,
824 API_RESERVED,
825 API_OPTIONS,
826 IPS_OPT,
827 IPS_HELP,
828 raw_trailer_mod_ctor,
829 HttpRuleOptModule::mod_dtor
830 },
831 OPT_TYPE_DETECTION,
832 0, PROTO_BIT__TCP,
833 nullptr,
834 nullptr,
835 nullptr,
836 nullptr,
837 HttpIpsOption::opt_ctor,
838 HttpIpsOption::opt_dtor,
839 nullptr
840 };
841
842 //-------------------------------------------------------------------------
843 // http_raw_uri
844 //-------------------------------------------------------------------------
845
846 static const Parameter http_raw_uri_params[] =
847 {
848 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
849 "this rule is limited to examining HTTP message headers" },
850 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
851 "parts of this rule examine HTTP message body" },
852 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
853 "parts of this rule examine HTTP message trailers" },
854 { "scheme", Parameter::PT_IMPLIED, nullptr, nullptr,
855 "match against scheme section of URI only" },
856 { "host", Parameter::PT_IMPLIED, nullptr, nullptr,
857 "match against host section of URI only" },
858 { "port", Parameter::PT_IMPLIED, nullptr, nullptr,
859 "match against port section of URI only" },
860 { "path", Parameter::PT_IMPLIED, nullptr, nullptr,
861 "match against path section of URI only" },
862 { "query", Parameter::PT_IMPLIED, nullptr, nullptr,
863 "match against query section of URI only" },
864 { "fragment", Parameter::PT_IMPLIED, nullptr, nullptr,
865 "match against fragment section of URI only" },
866 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
867 };
868
869 #undef IPS_OPT
870 #define IPS_OPT "http_raw_uri"
871 #undef IPS_HELP
872 #define IPS_HELP "rule option to set the detection cursor to the unnormalized URI"
873
raw_uri_mod_ctor()874 static Module* raw_uri_mod_ctor()
875 {
876 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_RAW_URI, CAT_SET_RAW_KEY,
877 PSI_RAW_URI, http_raw_uri_params);
878 }
879
880 static const IpsApi raw_uri_api =
881 {
882 {
883 PT_IPS_OPTION,
884 sizeof(IpsApi),
885 IPSAPI_VERSION,
886 1,
887 API_RESERVED,
888 API_OPTIONS,
889 IPS_OPT,
890 IPS_HELP,
891 raw_uri_mod_ctor,
892 HttpRuleOptModule::mod_dtor
893 },
894 OPT_TYPE_DETECTION,
895 0, PROTO_BIT__TCP,
896 nullptr,
897 nullptr,
898 nullptr,
899 nullptr,
900 HttpIpsOption::opt_ctor,
901 HttpIpsOption::opt_dtor,
902 nullptr
903 };
904
905 //-------------------------------------------------------------------------
906 // http_stat_code
907 //-------------------------------------------------------------------------
908
909 static const Parameter http_stat_code_params[] =
910 {
911 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
912 "parts of this rule examine HTTP message body" },
913 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
914 "parts of this rule examine HTTP message trailers" },
915 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
916 };
917
918 #undef IPS_OPT
919 #define IPS_OPT "http_stat_code"
920 #undef IPS_HELP
921 #define IPS_HELP "rule option to set the detection cursor to the HTTP status code"
922
stat_code_mod_ctor()923 static Module* stat_code_mod_ctor()
924 {
925 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_CODE, CAT_SET_STAT_CODE,
926 PSI_STAT_CODE, http_stat_code_params);
927 }
928
929 static const IpsApi stat_code_api =
930 {
931 {
932 PT_IPS_OPTION,
933 sizeof(IpsApi),
934 IPSAPI_VERSION,
935 1,
936 API_RESERVED,
937 API_OPTIONS,
938 IPS_OPT,
939 IPS_HELP,
940 stat_code_mod_ctor,
941 HttpRuleOptModule::mod_dtor
942 },
943 OPT_TYPE_DETECTION,
944 0, PROTO_BIT__TCP,
945 nullptr,
946 nullptr,
947 nullptr,
948 nullptr,
949 HttpIpsOption::opt_ctor,
950 HttpIpsOption::opt_dtor,
951 nullptr
952 };
953
954 //-------------------------------------------------------------------------
955 // http_stat_msg
956 //-------------------------------------------------------------------------
957
958 static const Parameter http_stat_msg_params[] =
959 {
960 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
961 "parts of this rule examine HTTP message body" },
962 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
963 "parts of this rule examine HTTP message trailers" },
964 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
965 };
966
967 #undef IPS_OPT
968 #define IPS_OPT "http_stat_msg"
969 #undef IPS_HELP
970 #define IPS_HELP "rule option to set the detection cursor to the HTTP status message"
971
stat_msg_mod_ctor()972 static Module* stat_msg_mod_ctor()
973 {
974 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_STAT_MSG, CAT_SET_STAT_MSG,
975 PSI_STAT_MSG, http_stat_msg_params);
976 }
977
978 static const IpsApi stat_msg_api =
979 {
980 {
981 PT_IPS_OPTION,
982 sizeof(IpsApi),
983 IPSAPI_VERSION,
984 1,
985 API_RESERVED,
986 API_OPTIONS,
987 IPS_OPT,
988 IPS_HELP,
989 stat_msg_mod_ctor,
990 HttpRuleOptModule::mod_dtor
991 },
992 OPT_TYPE_DETECTION,
993 0, PROTO_BIT__TCP,
994 nullptr,
995 nullptr,
996 nullptr,
997 nullptr,
998 HttpIpsOption::opt_ctor,
999 HttpIpsOption::opt_dtor,
1000 nullptr
1001 };
1002
1003 //-------------------------------------------------------------------------
1004 // http_trailer
1005 //-------------------------------------------------------------------------
1006
1007 static const Parameter http_trailer_params[] =
1008 {
1009 { "field", Parameter::PT_STRING, nullptr, nullptr, "restrict to given trailer" },
1010 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
1011 "match against the trailers from the request message even when examining the response" },
1012 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
1013 "parts of this rule examine HTTP response message headers (must be combined with request)"
1014 },
1015 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
1016 "parts of this rule examine HTTP message body (must be combined with request)" },
1017 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
1018 };
1019
1020 #undef IPS_OPT
1021 #define IPS_OPT "http_trailer"
1022 #undef IPS_HELP
1023 #define IPS_HELP "rule option to set the detection cursor to the normalized trailers"
1024
trailer_mod_ctor()1025 static Module* trailer_mod_ctor()
1026 {
1027 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_TRAILER, CAT_SET_HEADER,
1028 PSI_TRAILER, http_trailer_params);
1029 }
1030
1031 static const IpsApi trailer_api =
1032 {
1033 {
1034 PT_IPS_OPTION,
1035 sizeof(IpsApi),
1036 IPSAPI_VERSION,
1037 1,
1038 API_RESERVED,
1039 API_OPTIONS,
1040 IPS_OPT,
1041 IPS_HELP,
1042 trailer_mod_ctor,
1043 HttpRuleOptModule::mod_dtor
1044 },
1045 OPT_TYPE_DETECTION,
1046 0, PROTO_BIT__TCP,
1047 nullptr,
1048 nullptr,
1049 nullptr,
1050 nullptr,
1051 HttpIpsOption::opt_ctor,
1052 HttpIpsOption::opt_dtor,
1053 nullptr
1054 };
1055
1056 //-------------------------------------------------------------------------
1057 // http_true_ip
1058 //-------------------------------------------------------------------------
1059
1060 static const Parameter http_true_ip_params[] =
1061 {
1062 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
1063 "this rule is limited to examining HTTP message headers" },
1064 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
1065 "parts of this rule examine HTTP message body" },
1066 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
1067 "parts of this rule examine HTTP message trailers" },
1068 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
1069 };
1070
1071 #undef IPS_OPT
1072 #define IPS_OPT "http_true_ip"
1073 #undef IPS_HELP
1074 #define IPS_HELP "rule option to set the detection cursor to the final client IP address"
1075
true_ip_mod_ctor()1076 static Module* true_ip_mod_ctor()
1077 {
1078 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_TRUE_IP, CAT_SET_OTHER,
1079 PSI_TRUE_IP, http_true_ip_params);
1080 }
1081
1082 static const IpsApi true_ip_api =
1083 {
1084 {
1085 PT_IPS_OPTION,
1086 sizeof(IpsApi),
1087 IPSAPI_VERSION,
1088 1,
1089 API_RESERVED,
1090 API_OPTIONS,
1091 IPS_OPT,
1092 IPS_HELP,
1093 true_ip_mod_ctor,
1094 HttpRuleOptModule::mod_dtor
1095 },
1096 OPT_TYPE_DETECTION,
1097 0, PROTO_BIT__TCP,
1098 nullptr,
1099 nullptr,
1100 nullptr,
1101 nullptr,
1102 HttpIpsOption::opt_ctor,
1103 HttpIpsOption::opt_dtor,
1104 nullptr
1105 };
1106
1107 //-------------------------------------------------------------------------
1108 // http_uri
1109 //-------------------------------------------------------------------------
1110
1111 static const Parameter http_uri_params[] =
1112 {
1113 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
1114 "this rule is limited to examining HTTP message headers" },
1115 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
1116 "parts of this rule examine HTTP message body" },
1117 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
1118 "parts of this rule examine HTTP message trailers" },
1119 { "scheme", Parameter::PT_IMPLIED, nullptr, nullptr,
1120 "match against scheme section of URI only" },
1121 { "host", Parameter::PT_IMPLIED, nullptr, nullptr,
1122 "match against host section of URI only" },
1123 { "port", Parameter::PT_IMPLIED, nullptr, nullptr,
1124 "match against port section of URI only" },
1125 { "path", Parameter::PT_IMPLIED, nullptr, nullptr,
1126 "match against path section of URI only" },
1127 { "query", Parameter::PT_IMPLIED, nullptr, nullptr,
1128 "match against query section of URI only" },
1129 { "fragment", Parameter::PT_IMPLIED, nullptr, nullptr,
1130 "match against fragment section of URI only" },
1131 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
1132 };
1133
1134 #undef IPS_OPT
1135 #define IPS_OPT "http_uri"
1136 #undef IPS_HELP
1137 #define IPS_HELP "rule option to set the detection cursor to the normalized URI buffer"
1138
uri_mod_ctor()1139 static Module* uri_mod_ctor()
1140 {
1141 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_URI, CAT_SET_KEY, PSI_URI,
1142 http_uri_params);
1143 }
1144
1145 static const IpsApi uri_api =
1146 {
1147 {
1148 PT_IPS_OPTION,
1149 sizeof(IpsApi),
1150 IPSAPI_VERSION,
1151 1,
1152 API_RESERVED,
1153 API_OPTIONS,
1154 IPS_OPT,
1155 IPS_HELP,
1156 uri_mod_ctor,
1157 HttpRuleOptModule::mod_dtor
1158 },
1159 OPT_TYPE_DETECTION,
1160 0, PROTO_BIT__TCP,
1161 nullptr,
1162 nullptr,
1163 nullptr,
1164 nullptr,
1165 HttpIpsOption::opt_ctor,
1166 HttpIpsOption::opt_dtor,
1167 nullptr
1168 };
1169
1170 //-------------------------------------------------------------------------
1171 // http_version
1172 //-------------------------------------------------------------------------
1173
1174 static const Parameter http_version_params[] =
1175 {
1176 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
1177 "match against the version from the request message even when examining the response" },
1178 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
1179 "this rule is limited to examining HTTP message headers" },
1180 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
1181 "parts of this rule examine HTTP message body" },
1182 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
1183 "parts of this rule examine HTTP message trailers" },
1184 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
1185 };
1186
1187 #undef IPS_OPT
1188 #define IPS_OPT "http_version"
1189 #undef IPS_HELP
1190 #define IPS_HELP "rule option to set the detection cursor to the version buffer"
1191
version_mod_ctor()1192 static Module* version_mod_ctor()
1193 {
1194 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_BUFFER_VERSION, CAT_SET_OTHER,
1195 PSI_VERSION, http_version_params);
1196 }
1197
1198 static const IpsApi version_api =
1199 {
1200 {
1201 PT_IPS_OPTION,
1202 sizeof(IpsApi),
1203 IPSAPI_VERSION,
1204 1,
1205 API_RESERVED,
1206 API_OPTIONS,
1207 IPS_OPT,
1208 IPS_HELP,
1209 version_mod_ctor,
1210 HttpRuleOptModule::mod_dtor
1211 },
1212 OPT_TYPE_DETECTION,
1213 0, PROTO_BIT__TCP,
1214 nullptr,
1215 nullptr,
1216 nullptr,
1217 nullptr,
1218 HttpIpsOption::opt_ctor,
1219 HttpIpsOption::opt_dtor,
1220 nullptr
1221 };
1222
1223 //-------------------------------------------------------------------------
1224 // js_data
1225 //-------------------------------------------------------------------------
1226 //
1227
1228 #undef IPS_OPT
1229 #define IPS_OPT "js_data"
1230 #undef IPS_HELP
1231 #define IPS_HELP "rule option to set detection cursor to normalized JavaScript data"
js_data_mod_ctor()1232 static Module* js_data_mod_ctor()
1233 {
1234 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, BUFFER_JS_DATA, CAT_SET_JS_DATA,
1235 PSI_JS_DATA);
1236 }
1237
1238 static const IpsApi js_data_api =
1239 {
1240 {
1241 PT_IPS_OPTION,
1242 sizeof(IpsApi),
1243 IPSAPI_VERSION,
1244 1,
1245 API_RESERVED,
1246 API_OPTIONS,
1247 IPS_OPT,
1248 IPS_HELP,
1249 js_data_mod_ctor,
1250 HttpRuleOptModule::mod_dtor
1251 },
1252 OPT_TYPE_DETECTION,
1253 0, PROTO_BIT__TCP,
1254 nullptr,
1255 nullptr,
1256 nullptr,
1257 nullptr,
1258 HttpIpsOption::opt_ctor,
1259 HttpIpsOption::opt_dtor,
1260 nullptr
1261 };
1262
1263 //-------------------------------------------------------------------------
1264 // num_header_lines
1265 //-------------------------------------------------------------------------
1266 #undef IPS_OPT
1267 #define IPS_OPT "num_headers"
1268 #undef IPS_HELP
1269 #define IPS_HELP "rule option to perform range check on number of headers"
1270
1271 static const Parameter http_num_hdrs_params[] =
1272 {
1273 { "~range", Parameter::PT_INTERVAL, hdrs_num_range.c_str(), nullptr,
1274 "check that number of headers of current buffer are in given range" },
1275 { "request", Parameter::PT_IMPLIED, nullptr, nullptr,
1276 "match against the version from the request message even when examining the response" },
1277 { "with_header", Parameter::PT_IMPLIED, nullptr, nullptr,
1278 "this rule is limited to examining HTTP message headers" },
1279 { "with_body", Parameter::PT_IMPLIED, nullptr, nullptr,
1280 "parts of this rule examine HTTP message body" },
1281 { "with_trailer", Parameter::PT_IMPLIED, nullptr, nullptr,
1282 "parts of this rule examine HTTP message trailers" },
1283 { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
1284 };
1285
num_hdrs_mod_ctor()1286 static Module* num_hdrs_mod_ctor()
1287 {
1288 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_HDRS, CAT_SET_OTHER,
1289 PSI_RANGE_NUM_HDRS, http_num_hdrs_params);
1290 }
1291
1292 static const IpsApi num_headers_api =
1293 {
1294 {
1295 PT_IPS_OPTION,
1296 sizeof(IpsApi),
1297 IPSAPI_VERSION,
1298 1,
1299 API_RESERVED,
1300 API_OPTIONS,
1301 IPS_OPT,
1302 IPS_HELP,
1303 num_hdrs_mod_ctor,
1304 HttpRuleOptModule::mod_dtor
1305 },
1306 OPT_TYPE_DETECTION,
1307 0, PROTO_BIT__TCP,
1308 nullptr,
1309 nullptr,
1310 nullptr,
1311 nullptr,
1312 HttpIpsOption::opt_ctor,
1313 HttpIpsOption::opt_dtor,
1314 nullptr
1315 };
1316
1317 //-------------------------------------------------------------------------
1318 // num_trailer_lines
1319 //-------------------------------------------------------------------------
1320 #undef IPS_OPT
1321 #define IPS_OPT "num_trailers"
1322 #undef IPS_HELP
1323 #define IPS_HELP "rule option to perform range check on number of trailers"
1324
num_trailers_mod_ctor()1325 static Module* num_trailers_mod_ctor()
1326 {
1327 return new HttpRuleOptModule(IPS_OPT, IPS_HELP, HTTP_RANGE_NUM_TRAILERS, CAT_SET_OTHER,
1328 PSI_RANGE_NUM_TRAILERS, http_num_hdrs_params);
1329 }
1330
1331 static const IpsApi num_trailers_api =
1332 {
1333 {
1334 PT_IPS_OPTION,
1335 sizeof(IpsApi),
1336 IPSAPI_VERSION,
1337 1,
1338 API_RESERVED,
1339 API_OPTIONS,
1340 IPS_OPT,
1341 IPS_HELP,
1342 num_trailers_mod_ctor,
1343 HttpRuleOptModule::mod_dtor
1344 },
1345 OPT_TYPE_DETECTION,
1346 0, PROTO_BIT__TCP,
1347 nullptr,
1348 nullptr,
1349 nullptr,
1350 nullptr,
1351 HttpIpsOption::opt_ctor,
1352 HttpIpsOption::opt_dtor,
1353 nullptr
1354 };
1355
1356 //-------------------------------------------------------------------------
1357 // plugins
1358 //-------------------------------------------------------------------------
1359
1360 const BaseApi* ips_http_client_body = &client_body_api.base;
1361 const BaseApi* ips_http_cookie = &cookie_api.base;
1362 const BaseApi* ips_http_header = &header_api.base;
1363 const BaseApi* ips_http_method = &method_api.base;
1364 const BaseApi* ips_http_num_headers = &num_headers_api.base;
1365 const BaseApi* ips_http_num_trailers = &num_trailers_api.base;
1366 const BaseApi* ips_http_param = ¶m_api.base;
1367 const BaseApi* ips_http_raw_body = &raw_body_api.base;
1368 const BaseApi* ips_http_raw_cookie = &raw_cookie_api.base;
1369 const BaseApi* ips_http_raw_header = &raw_header_api.base;
1370 const BaseApi* ips_http_raw_request = &raw_request_api.base;
1371 const BaseApi* ips_http_raw_status = &raw_status_api.base;
1372 const BaseApi* ips_http_raw_trailer = &raw_trailer_api.base;
1373 const BaseApi* ips_http_raw_uri = &raw_uri_api.base;
1374 const BaseApi* ips_http_stat_code = &stat_code_api.base;
1375 const BaseApi* ips_http_stat_msg = &stat_msg_api.base;
1376 const BaseApi* ips_http_trailer = &trailer_api.base;
1377 const BaseApi* ips_http_true_ip = &true_ip_api.base;
1378 const BaseApi* ips_http_uri = &uri_api.base;
1379 const BaseApi* ips_http_version = &version_api.base;
1380 const BaseApi* ips_js_data = &js_data_api.base;
1381
1382