00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018 // binder.cc author Russ Combs <rucombs@cisco.com>
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #include "binder.h"
00025
00026 #include "flow/flow.h"
00027 #include "flow/flow_key.h"
00028 #include "log/messages.h"
00029 #include "main/snort_config.h"
00030 #include "managers/inspector_manager.h"
00031 #include "profiler/profiler.h"
00032 #include "protocols/packet.h"
00033 #include "protocols/tcp.h"
00034 #include "protocols/udp.h"
00035 #include "stream/stream.h"
00036 #include "stream/stream_splitter.h"
00037 #include "target_based/sftarget_reader.h"
00038 #include "target_based/snort_protocols.h"
00039
00040 #include "bind_module.h"
00041 #include "binding.h"
00042
00043 #include "main/snort_debug.h"
00044
00045 using namespace std;
00046
00047 THREAD_LOCAL ProfileStats bindPerfStats;
00048
00049 // FIXIT-P these lookups should be optimized when the dust settles
00050 #define INS_IP "stream_ip"
00051 #define INS_ICMP "stream_icmp"
00052 #define INS_TCP "stream_tcp"
00053 #define INS_UDP "stream_udp"
00054 #define INS_USER "stream_user"
00055 #define INS_FILE "stream_file"
00056
00057 //-------------------------------------------------------------------------
00058 // binding
00059 //-------------------------------------------------------------------------
00060
00061 Binding::Binding()
00062 {
00063 when.split_nets = false;
00064 when.src_nets = nullptr;
00065 when.dst_nets = nullptr;
00066
00067 when.split_ports = false;
00068 when.src_ports.set();
00069 when.dst_ports.set();
00070
00071 when.protos = (unsigned)PktType::ANY;
00072 when.vlans.set();
00073 when.ifaces.reset();
00074
00075 when.src_zone = DAQ_PKTHDR_UNKNOWN;
00076 when.dst_zone = DAQ_PKTHDR_UNKNOWN;
00077
00078 when.ips_id = 0;
00079 when.role = BindWhen::BR_EITHER;
00080
00081 use.inspection_index = 0;
00082 use.ips_index = 0;
00083 use.network_index = 0;
00084 use.action = BindUse::BA_INSPECT;
00085
00086 use.what = BindUse::BW_NONE;
00087 use.object = nullptr;
00088 }
00089
00090 Binding::~Binding()
00091 {
00092 if ( when.src_nets )
00093 sfvar_free(when.src_nets);
00094
00095 if ( when.dst_nets )
00096 sfvar_free(when.dst_nets);
00097 }
00098
00099 bool Binding::check_ips_policy(const Flow* flow) const
00100 {
00101 if ( !when.ips_id )
00102 return true;
00103
00104 if ( when.ips_id == flow->ips_policy_id )
00105 return true;
00106
00107 return false;
00108 }
00109
00110 bool Binding::check_addr(const Flow* flow) const
00111 {
00112 if ( when.split_nets )
00113 return true;
00114
00115 if ( !when.src_nets )
00116 return true;
00117
00118 switch ( when.role )
00119 {
00120 case BindWhen::BR_SERVER:
00121 if ( sfvar_ip_in(when.src_nets, &flow->server_ip) )
00122 return true;
00123 break;
00124
00125 case BindWhen::BR_CLIENT:
00126 if ( sfvar_ip_in(when.src_nets, &flow->client_ip) )
00127 return true;
00128 break;
00129
00130 case BindWhen::BR_EITHER:
00131 if ( sfvar_ip_in(when.src_nets, &flow->client_ip) or
00132 sfvar_ip_in(when.src_nets, &flow->server_ip) )
00133 return true;
00134 break;
00135
00136 default:
00137 break;
00138 }
00139 return false;
00140 }
00141
00142 bool Binding::check_proto(const Flow* flow) const
00143 {
00144 if ( when.protos & (unsigned)flow->pkt_type )
00145 return true;
00146
00147 return false;
00148 }
00149
00150 bool Binding::check_iface(const Packet* p) const
00151 {
00152 if ( !p or when.ifaces.none() )
00153 return true;
00154
00155 auto in = p->pkth->ingress_index;
00156 auto out = p->pkth->egress_index;
00157
00158 if ( in > 0 and when.ifaces.test(out) )
00159 return true;
00160
00161 if ( out > 0 and when.ifaces.test(out) )
00162 return true;
00163
00164 return false;
00165 }
00166
00167 bool Binding::check_vlan(const Flow* flow) const
00168 {
00169 unsigned v = flow->key->vlan_tag;
00170 return when.vlans.test(v);
00171 }
00172
00173 bool Binding::check_port(const Flow* flow) const
00174 {
00175 if ( when.split_ports )
00176 return true;
00177
00178 switch ( when.role )
00179 {
00180 case BindWhen::BR_SERVER:
00181 return when.src_ports.test(flow->server_port);
00182 case BindWhen::BR_CLIENT:
00183 return when.src_ports.test(flow->client_port);
00184 case BindWhen::BR_EITHER:
00185 return (when.src_ports.test(flow->client_port) or when.src_ports.test(flow->server_port) );
00186 default:
00187 break;
00188 }
00189 return false;
00190 }
00191
00192 bool Binding::check_service(const Flow* flow) const
00193 {
00194 if ( !flow->service )
00195 return when.svc.empty();
00196
00197 if ( when.svc == flow->service )
00198 return true;
00199
00200 return false;
00201 }
00202
00203 // we want to correlate src_zone to src_nets and src_ports, and dst_zone to dst_nets and
00204 // dst_ports. it doesn't matter if the packet is actually moving in the opposite direction as
00205 // binder is only evaluated once per flow and we need to capture the correct binding from
00206 // either side of the conversation
00207 template<typename When, typename Traffic, typename Compare>
00208 Binding::DirResult directional_match(const When& when_src, const When& when_dst,
00209 const Traffic& traffic_src, const Traffic& traffic_dst,
00210 const Binding::DirResult dr, const Compare& compare)
00211 {
00212 bool src_in_src = false;
00213 bool src_in_dst = false;
00214 bool dst_in_src = false;
00215 bool dst_in_dst = false;
00216 bool forward_match = false;
00217 bool reverse_match = false;
00218
00219 switch ( dr )
00220 {
00221 case Binding::DR_ANY_MATCH:
00222 src_in_src = compare(when_src, traffic_src);
00223 src_in_dst = compare(when_dst, traffic_src);
00224 dst_in_src = compare(when_src, traffic_dst);
00225 dst_in_dst = compare(when_dst, traffic_dst);
00226
00227 forward_match = src_in_src and dst_in_dst;
00228 reverse_match = dst_in_src and src_in_dst;
00229
00230 if ( forward_match and reverse_match )
00231 return dr;
00232
00233 if ( forward_match )
00234 return Binding::DR_FORWARD;
00235
00236 if ( reverse_match )
00237 return Binding::DR_REVERSE;
00238
00239 return Binding::DR_NO_MATCH;
00240
00241 case Binding::DR_FORWARD:
00242 src_in_src = compare(when_src, traffic_src);
00243 dst_in_dst = compare(when_dst, traffic_dst);
00244 return src_in_src and dst_in_dst ? dr : Binding::DR_NO_MATCH;
00245
00246 case Binding::DR_REVERSE:
00247 src_in_dst = compare(when_dst, traffic_src);
00248 dst_in_src = compare(when_src, traffic_dst);
00249 return src_in_dst and dst_in_src ? dr : Binding::DR_NO_MATCH;
00250
00251 default:
00252 break;
00253 }
00254
00255 return Binding::DR_NO_MATCH;
00256 }
00257
00258 Binding::DirResult Binding::check_split_addr(const Flow* flow, const Packet* p,
00259 const Binding::DirResult dr) const
00260 {
00261 if ( !when.split_nets )
00262 return dr;
00263
00264 if ( !when.src_nets && !when.dst_nets )
00265 return dr;
00266
00267 const SfIp* src_ip = &flow->client_ip;
00268 const SfIp* dst_ip = &flow->server_ip;
00269
00270 if ( p && p->ptrs.ip_api.is_ip() )
00271 {
00272 src_ip = p->ptrs.ip_api.get_src();
00273 dst_ip = p->ptrs.ip_api.get_dst();
00274 }
00275
00276 return directional_match(when.src_nets, when.dst_nets, src_ip, dst_ip, dr,
00277 [](sfip_var_t* when_val, const SfIp* traffic_val)
00278 { return when_val ? sfvar_ip_in(when_val, traffic_val) : true; });
00279
00280 }
00281
00282 Binding::DirResult Binding::check_split_port(const Flow* flow, const Packet* p,
00283 const Binding::DirResult dr) const
00284 {
00285 if ( !when.split_ports )
00286 return dr;
00287
00288 uint16_t src_port = flow->client_port;
00289 uint16_t dst_port = flow->server_port;
00290
00291 if ( p )
00292 {
00293 if ( p->is_tcp() )
00294 {
00295 src_port = p->ptrs.tcph->src_port();
00296 dst_port = p->ptrs.tcph->dst_port();
00297 }
00298 else if ( p->is_udp() )
00299 {
00300 src_port = p->ptrs.udph->src_port();
00301 dst_port = p->ptrs.udph->dst_port();
00302 }
00303 else
00304 return dr;
00305 }
00306
00307 return directional_match(when.src_ports, when.dst_ports, src_port, dst_port, dr,
00308 [](const PortBitSet& when_val, uint16_t traffic_val)
00309 { return when_val.test(traffic_val); });
00310 }
00311
00312 Binding::DirResult Binding::check_zone(const Packet* p, const Binding::DirResult dr) const
00313 {
00314 if ( !p )
00315 return dr;
00316
00317 return directional_match(when.src_zone, when.dst_zone,
00318 p->pkth->ingress_group, p->pkth->egress_group, dr,
00319 [](int32_t when_val, int32_t zone)
00320 { return when_val == DAQ_PKTHDR_UNKNOWN or when_val == zone; });
00321 }
00322
00323 bool Binding::check_all(const Flow* flow, Packet* p) const
00324 {
00325 Binding::DirResult dir = Binding::DR_ANY_MATCH;
00326
00327 if ( !check_ips_policy(flow) )
00328 return false;
00329
00330 if ( !check_iface(p) )
00331 return false;
00332
00333 if ( !check_vlan(flow) )
00334 return false;
00335
00336 // FIXIT-M need to check role and addr/ports relative to it
00337 if ( !check_addr(flow) )
00338 return false;
00339
00340 dir = check_split_addr(flow, p, dir);
00341 if ( dir == Binding::DR_NO_MATCH )
00342 return false;
00343
00344 if ( !check_proto(flow) )
00345 return false;
00346
00347 if ( !check_port(flow) )
00348 return false;
00349
00350 dir = check_split_port(flow, p, dir);
00351 if ( dir == Binding::DR_NO_MATCH )
00352 return false;
00353
00354 if ( !check_service(flow) )
00355 return false;
00356
00357 dir = check_zone(p, dir);
00358 if ( dir == Binding::DR_NO_MATCH )
00359 return false;
00360
00361 return true;
00362 }
00363
00364 //-------------------------------------------------------------------------
00365 // helpers
00366 //-------------------------------------------------------------------------
00367
00368 static void set_session(Flow* flow, const char* key)
00369 {
00370 Inspector* pin = InspectorManager::get_inspector(key);
00371
00372 if ( pin )
00373 {
00374 // FIXIT-M need to set ssn client and server independently
00375 flow->set_client(pin);
00376 flow->set_server(pin);
00377 flow->clouseau = nullptr;
00378 }
00379 }
00380
00381 static void set_session(Flow* flow)
00382 {
00383 flow->ssn_client = nullptr;
00384 flow->ssn_server = nullptr;
00385 flow->clouseau = nullptr;
00386 }
00387
00388 static void set_service(Flow* flow, const HostAttributeEntry* host)
00389 {
00390 Stream::set_application_protocol_id(flow, host, FROM_SERVER);
00391 }
00392
00393 static Inspector* get_gadget(Flow* flow)
00394 {
00395 if ( !flow->ssn_state.application_protocol )
00396 return nullptr;
00397
00398 const char* s = snort_conf->proto_ref->get_name(flow->ssn_state.application_protocol);
00399
00400 return InspectorManager::get_inspector(s);
00401 }
00402
00403 //-------------------------------------------------------------------------
00404 // stuff stuff
00405 //-------------------------------------------------------------------------
00406
00407 struct Stuff
00408 {
00409 BindUse::Action action;
00410
00411 Inspector* client;
00412 Inspector* server;
00413 Inspector* wizard;
00414 Inspector* gadget;
00415 Inspector* data;
00416
00417 Stuff()
00418 {
00419 action = BindUse::BA_INSPECT;
00420 client = server = nullptr;
00421 wizard = gadget = nullptr;
00422 data = nullptr;
00423 }
00424
00425 bool update(Binding*);
00426
00427 bool apply_action(Flow*);
00428 void apply_session(Flow*, const HostAttributeEntry*);
00429 void apply_service(Flow*, const HostAttributeEntry*);
00430 };
00431
00432 bool Stuff::update(Binding* pb)
00433 {
00434 if ( pb->use.action != BindUse::BA_INSPECT )
00435 {
00436 action = pb->use.action;
00437 return true;
00438 }
00439 switch ( pb->use.what )
00440 {
00441 case BindUse::BW_NONE:
00442 break;
00443 case BindUse::BW_PASSIVE:
00444 data = (Inspector*)pb->use.object;
00445 break;
00446 case BindUse::BW_CLIENT:
00447 client = (Inspector*)pb->use.object;
00448 break;
00449 case BindUse::BW_SERVER:
00450 server = (Inspector*)pb->use.object;
00451 break;
00452 case BindUse::BW_STREAM:
00453 client = server = (Inspector*)pb->use.object;
00454 break;
00455 case BindUse::BW_WIZARD:
00456 wizard = (Inspector*)pb->use.object;
00457 return true;
00458 case BindUse::BW_GADGET:
00459 gadget = (Inspector*)pb->use.object;
00460 return true;
00461 default:
00462 break;
00463 }
00464 return false;
00465 }
00466
00467 bool Stuff::apply_action(Flow* flow)
00468 {
00469 switch ( action )
00470 {
00471 case BindUse::BA_RESET:
00472 flow->set_state(Flow::FlowState::RESET);
00473 return false;
00474
00475 case BindUse::BA_BLOCK:
00476 flow->set_state(Flow::FlowState::BLOCK);
00477 return false;
00478
00479 case BindUse::BA_ALLOW:
00480 flow->set_state(Flow::FlowState::ALLOW);
00481 return false;
00482
00483 default:
00484 break;
00485 }
00486 flow->set_state(Flow::FlowState::INSPECT);
00487 return true;
00488 }
00489
00490 void Stuff::apply_session(Flow* flow, const HostAttributeEntry* host)
00491 {
00492 if ( server )
00493 {
00494 flow->set_server(server);
00495
00496 if ( client )
00497 flow->set_client(client);
00498 else
00499 flow->set_client(server);
00500
00501 return;
00502 }
00503
00504 switch ( flow->pkt_type )
00505 {
00506 case PktType::IP:
00507 set_session(flow, INS_IP);
00508 flow->ssn_policy = host ? host->hostInfo.fragPolicy : 0;
00509 break;
00510
00511 case PktType::ICMP:
00512 set_session(flow, INS_ICMP);
00513 break;
00514
00515 case PktType::TCP:
00516 set_session(flow, INS_TCP);
00517 flow->ssn_policy = host ? host->hostInfo.streamPolicy : 0;
00518 break;
00519
00520 case PktType::UDP:
00521 set_session(flow, INS_UDP);
00522 break;
00523
00524 case PktType::PDU:
00525 set_session(flow, INS_USER);
00526 break;
00527
00528 case PktType::FILE:
00529 set_session(flow, INS_FILE);
00530 break;
00531
00532 default:
00533 set_session(flow);
00534 }
00535 }
00536
00537 void Stuff::apply_service(Flow* flow, const HostAttributeEntry* host)
00538 {
00539 if ( data )
00540 flow->set_data(data);
00541
00542 if ( host )
00543 set_service(flow, host);
00544
00545 if ( !gadget )
00546 gadget = get_gadget(flow);
00547
00548 if ( gadget )
00549 {
00550 flow->set_gadget(gadget);
00551
00552 if ( !flow->ssn_state.application_protocol )
00553 flow->ssn_state.application_protocol = gadget->get_service();
00554 }
00555
00556 else if ( wizard )
00557 flow->set_clouseau(wizard);
00558 }
00559
00560 //-------------------------------------------------------------------------
00561 // class stuff
00562 //-------------------------------------------------------------------------
00563
00564 class Binder : public Inspector
00565 {
00566 public:
00567 Binder(vector<Binding*>&);
00568 ~Binder() override;
00569
00570 void show(SnortConfig*) override
00571 { LogMessage("Binder\n"); }
00572
00573 void update(SnortConfig*, const char*) override;
00574
00575 bool configure(SnortConfig*) override;
00576
00577 void eval(Packet*) override;
00578 int exec(int, void*) override;
00579
00580 void add(Binding* b)
00581 { bindings.push_back(b); }
00582
00583 private:
00584 void apply(const Stuff&, Flow*);
00585
00586 void set_binding(SnortConfig*, Binding*);
00587 void get_bindings(Flow*, Stuff&, Packet* = nullptr); // may be null when dealing with HA flows
00588 void apply(Flow*, Stuff&);
00589 Inspector* find_gadget(Flow*);
00590 int exec_handle_gadget(void*);
00591 int exec_eval_standby_flow(void*);
00592
00593 private:
00594 vector<Binding*> bindings;
00595 };
00596
00597 Binder::Binder(vector<Binding*>& v)
00598 {
00599 bindings = std::move(v);
00600 }
00601
00602 Binder::~Binder()
00603 {
00604 for ( auto* p : bindings )
00605 delete p;
00606 }
00607
00608 bool Binder::configure(SnortConfig* sc)
00609 {
00610 Binding* pb;
00611 unsigned i, sz = bindings.size();
00612
00613 for ( i = 0; i < sz; i++ )
00614 {
00615 pb = bindings[i];
00616
00617 // Update with actual policy indices instead of user provided names
00618 if ( pb->when.ips_id )
00619 {
00620 IpsPolicy* p = sc->policy_map->get_user_ips(pb->when.ips_id);
00621 if ( p )
00622 pb->when.ips_id = p->policy_id;
00623 else
00624 ParseError("can't bind. ips_policy_id %u does not exist", pb->when.ips_id);
00625 }
00626
00627 if ( !pb->use.ips_index and !pb->use.inspection_index and !pb->use.network_index )
00628 set_binding(sc, pb);
00629 }
00630 return true;
00631 }
00632
00633 void Binder::update(SnortConfig*, const char* name)
00634 {
00635 vector<Binding*>::iterator it;
00636 for ( it = bindings.begin(); it != bindings.end(); ++it )
00637 {
00638 const char* key;
00639 Binding *pb = *it;
00640 if ( pb->use.svc.empty() )
00641 key = pb->use.name.c_str();
00642 else
00643 key = pb->use.svc.c_str();
00644 if ( !strcmp(key, name) )
00645 {
00646 bindings.erase(it);
00647 delete pb;
00648 return;
00649 }
00650 }
00651 }
00652
00653 void Binder::eval(Packet* p)
00654 {
00655
00656 new_invoked_inspector(3, p, 0);
00657
00658 Stuff stuff;
00659 Flow* flow = p->flow;
00660
00661 get_bindings(flow, stuff, p);
00662 apply(flow, stuff);
00663
00664 ++bstats.verdicts[stuff.action];
00665 ++bstats.packets;
00666 }
00667
00668 int Binder::exec_handle_gadget( void* pv )
00669 {
00670 Flow* flow = (Flow*)pv;
00671 Inspector* ins = find_gadget(flow);
00672
00673 if ( ins )
00674 {
00675 if (flow->gadget != nullptr )
00676 flow->clear_gadget();
00677 flow->set_gadget(ins);
00678 flow->ssn_state.application_protocol = ins->get_service();
00679 }
00680 else if ( flow->service )
00681 flow->ssn_state.application_protocol = snort_conf->proto_ref->find(flow->service);
00682
00683 if ( !flow->is_stream() )
00684 return 0;
00685
00686 if ( ins )
00687 {
00688 Stream::set_splitter(flow, true, ins->get_splitter(true));
00689 Stream::set_splitter(flow, false, ins->get_splitter(false));
00690 }
00691 else
00692 {
00693 Stream::set_splitter(flow, true, new AtomSplitter(true));
00694 Stream::set_splitter(flow, false, new AtomSplitter(false));
00695 }
00696
00697 return 0;
00698 }
00699
00700 // similar to eval(), but working on a Flow in HA Standby mode
00701 int Binder::exec_eval_standby_flow( void* pv )
00702 {
00703 Flow* flow = (Flow*)pv;
00704
00705 Stuff stuff;
00706 get_bindings(flow, stuff);
00707 apply(flow, stuff);
00708
00709 ++bstats.verdicts[stuff.action];
00710 return 0;
00711 }
00712
00713 int Binder::exec(int operation, void* pv)
00714 {
00715
00716 switch( operation )
00717 {
00718 case BinderSpace::ExecOperation::HANDLE_GADGET:
00719 return exec_handle_gadget( pv );
00720 case BinderSpace::ExecOperation::EVAL_STANDBY_FLOW:
00721 return exec_eval_standby_flow( pv );
00722 default:
00723 return (-1);
00724 }
00725 }
00726
00727 //-------------------------------------------------------------------------
00728 // implementation stuff
00729 //-------------------------------------------------------------------------
00730
00731 void Binder::set_binding(SnortConfig*, Binding* pb)
00732 {
00733 if ( pb->use.action != BindUse::BA_INSPECT )
00734 return;
00735
00736 const char* key;
00737 if ( pb->use.svc.empty() )
00738 key = pb->use.name.c_str();
00739 else
00740 key = pb->use.svc.c_str();
00741
00742 if ( (pb->use.object = InspectorManager::get_inspector(key)) )
00743 {
00744 switch ( InspectorManager::get_type(key) )
00745 {
00746 case IT_STREAM: pb->use.what = BindUse::BW_STREAM; break;
00747 case IT_WIZARD: pb->use.what = BindUse::BW_WIZARD; break;
00748 case IT_SERVICE: pb->use.what = BindUse::BW_GADGET; break;
00749 case IT_PASSIVE: pb->use.what = BindUse::BW_PASSIVE; break;
00750 default: break;
00751 }
00752 }
00753 if ( !pb->use.object )
00754 pb->use.what = BindUse::BW_NONE;
00755
00756 if ( pb->use.what == BindUse::BW_NONE )
00757 ParseError("can't bind %s", key);
00758 }
00759
00760 // FIXIT-P this is a simple linear search until functionality is nailed
00761 // down. performance should be the focus of the next iteration.
00762 void Binder::get_bindings(Flow* flow, Stuff& stuff, Packet* p)
00763 {
00764 Binding* pb;
00765 unsigned i, sz = bindings.size();
00766
00767 for ( i = 0; i < sz; i++ )
00768 {
00769 pb = bindings[i];
00770
00771 if ( !pb->check_all(flow, p) )
00772 continue;
00773
00774 if ( !pb->use.ips_index and !pb->use.inspection_index and !pb->use.network_index )
00775 {
00776 if ( stuff.update(pb) )
00777 return;
00778 else
00779 continue;
00780 }
00781
00782 if ( pb->use.inspection_index )
00783 {
00784 set_inspection_policy(snort_conf, pb->use.inspection_index - 1);
00785 flow->inspection_policy_id = pb->use.inspection_index - 1;
00786 }
00787
00788 if ( pb->use.ips_index )
00789 {
00790 set_ips_policy(snort_conf, pb->use.ips_index - 1);
00791 flow->ips_policy_id = pb->use.ips_index - 1;
00792 }
00793
00794 if ( pb->use.network_index )
00795 {
00796 set_network_policy(snort_conf, pb->use.network_index - 1);
00797 flow->network_policy_id = pb->use.network_index - 1;
00798 }
00799
00800 Binder* sub = (Binder*)InspectorManager::get_binder();
00801
00802 // If selected sub-policy is IPS, inspection policy wont
00803 // change and get_binder() will return this binder. Keep
00804 // checking rules in case a new inspection policy is specified
00805 // after.
00806 if ( sub == this )
00807 continue;
00808
00809 if ( sub )
00810 {
00811 sub->get_bindings(flow, stuff, p);
00812 return;
00813 }
00814 }
00815 }
00816
00817 Inspector* Binder::find_gadget(Flow* flow)
00818 {
00819 Stuff stuff;
00820 get_bindings(flow, stuff);
00821 return stuff.gadget;
00822 }
00823
00824 void Binder::apply(Flow* flow, Stuff& stuff)
00825 {
00826 // setup action
00827 if ( !stuff.apply_action(flow) )
00828 return;
00829
00830 const HostAttributeEntry* host = SFAT_LookupHostEntryByIP(&flow->server_ip);
00831
00832 // setup session
00833 stuff.apply_session(flow, host);
00834
00835 // setup service
00836 stuff.apply_service(flow, host);
00837 }
00838
00839 //-------------------------------------------------------------------------
00840 // api stuff
00841 //-------------------------------------------------------------------------
00842
00843 static Module* mod_ctor()
00844 { return new BinderModule; }
00845
00846 static void mod_dtor(Module* m)
00847 { delete m; }
00848
00849 static Inspector* bind_ctor(Module* m)
00850 {
00851 BinderModule* mod = (BinderModule*)m;
00852 vector<Binding*>& pb = mod->get_data();
00853 return new Binder(pb);
00854 }
00855
00856 static void bind_dtor(Inspector* p)
00857 {
00858 delete p;
00859 }
00860
00861 static const InspectApi bind_api =
00862 {
00863 {
00864 PT_INSPECTOR,
00865 sizeof(InspectApi),
00866 INSAPI_VERSION,
00867 0,
00868 API_RESERVED,
00869 API_OPTIONS,
00870 BIND_NAME,
00871 BIND_HELP,
00872 mod_ctor,
00873 mod_dtor
00874 },
00875 IT_BINDER,
00876 (uint16_t)PktType::ANY,
00877 nullptr, // buffers
00878 nullptr, // service
00879 nullptr, // pinit
00880 nullptr, // pterm
00881 nullptr, // tinit
00882 nullptr, // tterm
00883 bind_ctor,
00884 bind_dtor,
00885 nullptr, // ssn
00886 nullptr // reset
00887 };
00888
00889 const BaseApi* nin_binder = &bind_api.base;
00890
END OF CODE