00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2014-2017 Cisco and/or its affiliates. All rights reserved.
00003 // Copyright (C) 2005-2013 Sourcefire, Inc.
00004 //
00005 // This program is free software; you can redistribute it and/or modify it
00006 // under the terms of the GNU General Public License Version 2 as published
00007 // by the Free Software Foundation. You may not use, modify or distribute
00008 // this program under any other version of the GNU General Public License.
00009 //
00010 // This program is distributed in the hope that it will be useful, but
00011 // WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License along
00016 // with this program; if not, write to the Free Software Foundation, Inc.,
00017 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 //--------------------------------------------------------------------------
00019
00020 // sfdaq.cc author Michael Altizer <mialtize@cisco.com>
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025
00026 #include "sfdaq.h"
00027
00028 extern "C" {
00029 #include <daq.h>
00030 #include <sfbpf_dlt.h>
00031 }
00032
00033 #include <mutex>
00034
00035 #include "log/messages.h"
00036 #include "main/snort_config.h"
00037 #include "protocols/packet.h"
00038 #include "protocols/vlan.h"
00039
00040 #include "sfdaq_config.h"
00041
00042 using namespace std;
00043
00044 #ifdef DEFAULT_DAQ
00045 #define XSTR(s) STR(s)
00046 #define STR(s) #s
00047 #define DAQ_DEFAULT XSTR(DEFAULT_DAQ)
00048 #else
00049 #define DAQ_DEFAULT "pcap"
00050 #endif
00051
00052 static const int DEFAULT_PKT_SNAPLEN = 1514;
00053
00054 // common for all daq threads / instances
00055 static const DAQ_Module_t* daq_mod = nullptr;
00056 static DAQ_Mode daq_mode = DAQ_MODE_PASSIVE;
00057 static uint32_t snap = DEFAULT_PKT_SNAPLEN;
00058 static bool loaded = false;
00059 static std::mutex bpf_gate;
00060
00061 // specific for each thread / instance
00062 static THREAD_LOCAL SFDAQInstance *local_instance = nullptr;
00063
00064 /*
00065 * SFDAQ
00066 */
00067
00068 void SFDAQ::load(const SnortConfig* sc)
00069 {
00070 const char** dirs = new const char*[sc->daq_config->module_dirs.size() + 1];
00071 int i = 0;
00072
00073 for (string& module_dir : sc->daq_config->module_dirs)
00074 dirs[i++] = module_dir.c_str();
00075 dirs[i] = nullptr;
00076
00077 int err = daq_load_modules(dirs);
00078
00079 if (err)
00080 FatalError("Can't load DAQ modules = %d\n", err);
00081
00082 delete[] dirs;
00083
00084 loaded = true;
00085 }
00086
00087 void SFDAQ::unload()
00088 {
00089 daq_unload_modules();
00090 loaded = false;
00091 }
00092
00093 void SFDAQ::print_types(ostream& ostr)
00094 {
00095 DAQ_Module_Info_t* list = nullptr;
00096 int i, nMods = daq_get_module_list(&list);
00097
00098 if (nMods)
00099 ostr << "Available DAQ modules:" << endl;
00100 else
00101 ostr << "No available DAQ modules (try adding directories with --daq-dir)." << endl;
00102
00103 for (i = 0; i < nMods; i++)
00104 {
00105 ostr << list[i].name << "(v" << list[i].version << "):";
00106
00107 if (list[i].type & DAQ_TYPE_FILE_CAPABLE)
00108 ostr << " readback";
00109
00110 if (list[i].type & DAQ_TYPE_INTF_CAPABLE)
00111 ostr << " live";
00112
00113 if (list[i].type & DAQ_TYPE_INLINE_CAPABLE)
00114 ostr << " inline";
00115
00116 if (list[i].type & DAQ_TYPE_MULTI_INSTANCE)
00117 ostr << " multi";
00118
00119 if (!(list[i].type & DAQ_TYPE_NO_UNPRIV))
00120 ostr << " unpriv";
00121
00122 ostr << endl;
00123 }
00124 daq_free_module_list(list, nMods);
00125 }
00126
00127 static int DAQ_ValidateModule(DAQ_Mode mode)
00128 {
00129 uint32_t have = daq_get_type(daq_mod);
00130 uint32_t need = 0;
00131
00132 if (mode == DAQ_MODE_READ_FILE)
00133 need |= DAQ_TYPE_FILE_CAPABLE;
00134
00135 else if (mode == DAQ_MODE_PASSIVE)
00136 need |= DAQ_TYPE_INTF_CAPABLE;
00137
00138 else
00139 need |= DAQ_TYPE_INLINE_CAPABLE;
00140
00141 return ((have & need) != 0);
00142 }
00143
00144 void SFDAQ::init(const SnortConfig* sc)
00145 {
00146 if (!loaded)
00147 load(sc);
00148
00149 const char* type = DAQ_DEFAULT;
00150
00151 if (!sc->daq_config->module_name.empty())
00152 type = sc->daq_config->module_name.c_str();
00153
00154 daq_mod = daq_find_module(type);
00155
00156 if (!daq_mod)
00157 FatalError("Can't find %s DAQ\n", type);
00158
00159 snap = (sc->daq_config->mru_size > 0) ? sc->daq_config->mru_size : DEFAULT_PKT_SNAPLEN;
00160
00161 if (SnortConfig::adaptor_inline_mode())
00162 daq_mode = DAQ_MODE_INLINE;
00163 else if (SnortConfig::read_mode())
00164 daq_mode = DAQ_MODE_READ_FILE;
00165 else
00166 daq_mode = DAQ_MODE_PASSIVE;
00167
00168 if (!DAQ_ValidateModule(daq_mode))
00169 FatalError("%s DAQ does not support %s.\n", type, daq_mode_string(daq_mode));
00170
00171 LogMessage("%s DAQ configured to %s.\n", type, daq_mode_string(daq_mode));
00172 }
00173
00174 void SFDAQ::term()
00175 {
00176 if (loaded)
00177 unload();
00178 daq_mod = nullptr;
00179 }
00180
00181 const char* SFDAQ::verdict_to_string(DAQ_Verdict verdict)
00182 {
00183 return daq_verdict_string(verdict);
00184 }
00185
00186 bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t* h)
00187 {
00188 // DAQ mode is inline and the packet will be forwarded?
00189 return (daq_mode == DAQ_MODE_INLINE && !(h->flags & DAQ_PKT_FLAG_NOT_FORWARDING));
00190 }
00191
00192 const char* SFDAQ::get_type()
00193 {
00194 return daq_mod ? daq_get_name(daq_mod) : "error";
00195 }
00196
00197 // Snort has its own snap applied to packets it acquires via the DAQ. This
00198 // should not be confused with the snap that was used to capture a pcap which
00199 // may be different.
00200 uint32_t SFDAQ::get_snap_len()
00201 {
00202 return snap;
00203 }
00204
00205 bool SFDAQ::unprivileged()
00206 {
00207 return !(daq_get_type(daq_mod) & DAQ_TYPE_NO_UNPRIV);
00208 }
00209
00210 /*
00211 * SFDAQ local instance wrappers (to be removed)
00212 */
00213
00214 void SFDAQ::set_local_instance(SFDAQInstance* sdi)
00215 {
00216 local_instance = sdi;
00217 }
00218
00219 SFDAQInstance* SFDAQ::get_local_instance()
00220 {
00221 return local_instance;
00222 }
00223
00224 const char* SFDAQ::get_interface_spec()
00225 {
00226 return local_instance->get_interface_spec();
00227 }
00228
00229 int SFDAQ::get_base_protocol()
00230 {
00231 return local_instance->get_base_protocol();
00232 }
00233
00234 bool SFDAQ::can_inject()
00235 {
00236 return local_instance && local_instance->can_inject();
00237 }
00238
00239 bool SFDAQ::can_inject_raw()
00240 {
00241 return local_instance && local_instance->can_inject_raw();
00242 }
00243
00244 bool SFDAQ::can_replace()
00245 {
00246 return local_instance && local_instance->can_replace();
00247 }
00248
00249 bool SFDAQ::can_retry()
00250 {
00251 return local_instance && local_instance->can_retry();
00252 }
00253
00254 int SFDAQ::inject(const DAQ_PktHdr_t* hdr, int rev, const uint8_t* buf, uint32_t len)
00255 {
00256 return local_instance->inject(hdr, rev, buf, len);
00257 }
00258
00259 bool SFDAQ::break_loop(int error)
00260 {
00261 return local_instance->break_loop(error);
00262 }
00263
00264 const DAQ_Stats_t* SFDAQ::get_stats()
00265 {
00266 return local_instance->get_stats();
00267 }
00268
00269 const char* SFDAQ::get_input_spec(const SnortConfig* sc, unsigned instance_id)
00270 {
00271 auto it = sc->daq_config->instances.find(instance_id);
00272 if (it != sc->daq_config->instances.end() && !it->second->input_spec.empty())
00273 return it->second->input_spec.c_str();
00274
00275 if (!sc->daq_config->input_spec.empty())
00276 return sc->daq_config->input_spec.c_str();
00277
00278 return nullptr;
00279 }
00280
00281 const char* SFDAQ::default_type()
00282 {
00283 return DAQ_DEFAULT;
00284 }
00285
00286 /*
00287 * SFDAQInstance
00288 */
00289
00290 SFDAQInstance::SFDAQInstance(const char* intf)
00291 {
00292 if (intf)
00293 interface_spec = intf;
00294 daq_hand = nullptr;
00295 daq_dlt = -1;
00296 s_error = DAQ_SUCCESS;
00297 memset(&daq_stats, 0, sizeof(daq_stats));
00298 }
00299
00300 SFDAQInstance::~SFDAQInstance()
00301 {
00302 if (daq_hand)
00303 daq_shutdown(daq_mod, daq_hand);
00304 }
00305
00306 static bool DAQ_ValidateInstance(void* daq_hand)
00307 {
00308 uint32_t caps = daq_get_capabilities(daq_mod, daq_hand);
00309
00310 if (!SnortConfig::adaptor_inline_mode())
00311 return true;
00312
00313 if (!(caps & DAQ_CAPA_BLOCK))
00314 ParseWarning(WARN_DAQ, "inline mode configured but DAQ can't block packets.\n");
00315
00316 return true;
00317 }
00318
00319 bool SFDAQInstance::configure(const SnortConfig* sc)
00320 {
00321 DAQ_Config_t cfg;
00322 const char* type = daq_get_name(daq_mod);
00323 char buf[256] = "";
00324 int err;
00325
00326 memset(&cfg, 0, sizeof(cfg));
00327
00328 cfg.name = const_cast<char*>(interface_spec.c_str());
00329 cfg.snaplen = snap;
00330 cfg.timeout = sc->daq_config->timeout;
00331 cfg.mode = daq_mode;
00332 cfg.extra = nullptr;
00333 cfg.flags = 0;
00334
00335 for (auto& kvp : sc->daq_config->variables)
00336 {
00337 daq_config_set_value(&cfg, kvp.first.c_str(),
00338 kvp.second.length() ? kvp.second.c_str() : nullptr);
00339 }
00340
00341 auto it = sc->daq_config->instances.find(get_instance_id());
00342 if (it != sc->daq_config->instances.end())
00343 {
00344 for (auto& kvp : it->second->variables)
00345 {
00346 daq_config_set_value(&cfg, kvp.first.c_str(),
00347 kvp.second.length() ? kvp.second.c_str() : nullptr);
00348 }
00349 }
00350
00351 if (!SnortConfig::read_mode())
00352 {
00353 if (!(sc->run_flags & RUN_FLAG__NO_PROMISCUOUS))
00354 cfg.flags |= DAQ_CFG_PROMISC;
00355 }
00356
00357 // FIXIT-M - This is sort of an abomination and would ideally be configurable ...
00358 if (!strcasecmp(type, "dump") or !strcasecmp(type, "regtest"))
00359 cfg.extra = reinterpret_cast<char*>(const_cast<DAQ_Module_t*>(daq_find_module("pcap")));
00360
00361 err = daq_initialize(daq_mod, &cfg, &daq_hand, buf, sizeof(buf));
00362 if (err)
00363 {
00364 ErrorMessage("Can't initialize DAQ %s (%d) - %s\n", type, err, buf);
00365 return false;
00366 }
00367 daq_config_clear_values(&cfg);
00368
00369 if (!DAQ_ValidateInstance(daq_hand))
00370 FatalError("DAQ configuration incompatible with intended operation.\n");
00371
00372 set_filter(sc->bpf_filter.c_str());
00373
00374 return true;
00375 }
00376
00377 void SFDAQInstance::reload()
00378 {
00379 void* old_config = nullptr;
00380 void* new_config = nullptr;
00381 if (daq_mod && daq_hand)
00382 {
00383 if ( ( daq_hup_prep(daq_mod, daq_hand, &new_config) == DAQ_SUCCESS ) and
00384 ( daq_hup_apply(daq_mod, daq_hand, new_config, &old_config) == DAQ_SUCCESS ) )
00385 {
00386 daq_hup_post(daq_mod, daq_hand, old_config);
00387 }
00388 }
00389 }
00390
00391 void SFDAQInstance::abort()
00392 {
00393 if (was_started())
00394 stop();
00395
00396 //DAQ_Delete();
00397 //DAQ_Term(); FIXIT-L this must be called from main thread on abort
00398 }
00399
00400 const char* SFDAQInstance::get_interface_spec()
00401 {
00402 return interface_spec.c_str();
00403 }
00404
00405 // That distinction does not hold with datalink types. Snort must use whatever
00406 // datalink type the DAQ coughs up as its base protocol decoder. For pcaps,
00407 // the datalink type in the file must be used - which may not be known until
00408 // start. The value is cached here since it used for packet operations like
00409 // logging and is needed at shutdown. This avoids sequencing issues.
00410 int SFDAQInstance::get_base_protocol()
00411 {
00412 return daq_dlt;
00413 }
00414
00415 bool SFDAQInstance::can_inject()
00416 {
00417 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT) != 0;
00418 }
00419
00420 bool SFDAQInstance::can_inject_raw()
00421 {
00422 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT_RAW) != 0;
00423 }
00424
00425 bool SFDAQInstance::can_replace()
00426 {
00427 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_REPLACE) != 0;
00428 }
00429
00430 bool SFDAQInstance::can_retry()
00431 {
00432 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_RETRY) != 0;
00433 }
00434
00435 bool SFDAQInstance::can_start_unprivileged()
00436 {
00437 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_UNPRIV_START) != 0;
00438 }
00439
00440 bool SFDAQInstance::can_whitelist()
00441 {
00442 return (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_WHITELIST) != 0;
00443 }
00444
00445 bool SFDAQInstance::set_filter(const char* bpf)
00446 {
00447 int err = 0;
00448
00449 // The BPF can be compiled either during daq_set_filter() or daq_start(),
00450 // so protect the thread-unsafe BPF scanner/compiler in both places.
00451
00452 if (bpf and *bpf)
00453 {
00454 std::lock_guard<std::mutex> lock(bpf_gate);
00455 err = daq_set_filter(daq_mod, daq_hand, bpf);
00456 }
00457
00458 if (err)
00459 FatalError("Can't set DAQ BPF filter to '%s' (%s)\n",
00460 bpf, daq_get_error(daq_mod, daq_hand));
00461
00462 return (err == DAQ_SUCCESS);
00463 }
00464
00465 bool SFDAQInstance::start()
00466 {
00467 int err;
00468
00469 // The BPF can be compiled either during daq_set_filter() or daq_start(),
00470 // so protect the thread-unsafe BPF scanner/compiler in both places.
00471 {
00472 std::lock_guard<std::mutex> lock(bpf_gate);
00473 err = daq_start(daq_mod, daq_hand);
00474 }
00475
00476 if (err)
00477 ErrorMessage("Can't start DAQ (%d) - %s\n", err, daq_get_error(daq_mod, daq_hand));
00478 else
00479 daq_dlt = daq_get_datalink_type(daq_mod, daq_hand);
00480
00481 return (err == DAQ_SUCCESS);
00482 }
00483
00484 bool SFDAQInstance::was_started()
00485 {
00486 DAQ_State s;
00487
00488 if (!daq_hand)
00489 return false;
00490
00491 s = daq_check_status(daq_mod, daq_hand);
00492
00493 return (DAQ_STATE_STARTED == s);
00494 }
00495
00496 bool SFDAQInstance::stop()
00497 {
00498 int err = daq_stop(daq_mod, daq_hand);
00499
00500 if (err)
00501 LogMessage("Can't stop DAQ (%d) - %s\n", err, daq_get_error(daq_mod, daq_hand));
00502
00503 return (err == DAQ_SUCCESS);
00504 }
00505
00506 void SFDAQInstance::set_metacallback(DAQ_Meta_Func_t meta_callback)
00507 {
00508 daq_meta_callback = meta_callback;
00509 }
00510
00511 int SFDAQInstance::acquire(int max, DAQ_Analysis_Func_t callback)
00512 {
00513 int err = daq_acquire_with_meta(daq_mod, daq_hand, max, callback, daq_meta_callback, nullptr);
00514
00515 if (err && err != DAQ_READFILE_EOF)
00516 LogMessage("Can't acquire (%d) - %s\n", err, daq_get_error(daq_mod, daq_hand));
00517
00518 if (s_error != DAQ_SUCCESS)
00519 {
00520 err = s_error;
00521 s_error = DAQ_SUCCESS;
00522 }
00523 return err;
00524 }
00525
00526 int SFDAQInstance::inject(const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len)
00527 {
00528 int err = daq_inject(daq_mod, daq_hand, h, buf, len, rev);
00529 #ifdef DEBUG_MSGS
00530 if (err)
00531 LogMessage("Can't inject (%d) - %s\n", err, daq_get_error(daq_mod, daq_hand));
00532 #endif
00533 return err;
00534 }
00535
00536 bool SFDAQInstance::break_loop(int error)
00537 {
00538 if (error)
00539 s_error = error;
00540 return (daq_breakloop(daq_mod, daq_hand) == DAQ_SUCCESS);
00541 }
00542
00543 // returns statically allocated stats - don't free
00544 const DAQ_Stats_t* SFDAQInstance::get_stats()
00545 {
00546 if (daq_hand)
00547 {
00548 int err = daq_get_stats(daq_mod, daq_hand, &daq_stats);
00549
00550 if (err)
00551 LogMessage("Can't get DAQ stats (%d) - %s\n", err, daq_get_error(daq_mod, daq_hand));
00552
00553 // Some DAQs don't provide hw numbers, so we default HW RX to the SW equivalent
00554 // (this means outstanding packets = 0)
00555 if (!daq_stats.hw_packets_received)
00556 daq_stats.hw_packets_received = daq_stats.packets_received + daq_stats.packets_filtered;
00557 }
00558
00559 return &daq_stats;
00560 }
00561
00562 int SFDAQInstance::query_flow(const DAQ_PktHdr_t* hdr, DAQ_QueryFlow_t* query)
00563 {
00564 return daq_query_flow(daq_mod, daq_hand, hdr, query);
00565 }
00566
00567 int SFDAQInstance::modify_flow_opaque(const DAQ_PktHdr_t* hdr, uint32_t opaque)
00568 {
00569 DAQ_ModFlow_t mod;
00570
00571 mod.type = DAQ_MODFLOW_TYPE_OPAQUE;
00572 mod.length = sizeof(opaque);
00573 mod.value = &opaque;
00574
00575 return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
00576 }
00577
00578 int SFDAQInstance::modify_flow_pkt_trace(const DAQ_PktHdr_t* hdr, DAQ_Verdict verdict,
00579 uint8_t* buff, uint32_t buff_len)
00580 {
00581 DAQ_ModFlow_t mod;
00582 DAQ_ModFlowPktTrace_t mod_tr;
00583 mod_tr.vreason = (uint8_t)verdict;
00584 mod_tr.pkt_trace_data_len = buff_len;
00585 mod_tr.pkt_trace_data = buff;
00586 mod.type = DAQ_MODFLOW_TYPE_PKT_TRACE;
00587 mod.length = sizeof(DAQ_ModFlowPktTrace_t);
00588 mod.value = (void*)&mod_tr;
00589 return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
00590 }
00591
00592 // FIXIT-L X Add Snort flag definitions for callers to use and translate/pass them through to
00593 // the DAQ module
00594 int SFDAQInstance::add_expected(const Packet* ctrlPkt, const SfIp* cliIP, uint16_t cliPort,
00595 const SfIp* srvIP, uint16_t srvPort, IpProtocol protocol, unsigned timeout_ms, unsigned /* flags */)
00596 {
00597 DAQ_Data_Channel_Params_t daq_params;
00598 DAQ_DP_key_t dp_key;
00599
00600 dp_key.src_af = cliIP->get_family();
00601 if (cliIP->is_ip4())
00602 dp_key.sa.src_ip4.s_addr = cliIP->get_ip4_value();
00603 else
00604 memcpy(&dp_key.sa.src_ip6, cliIP->get_ip6_ptr(), sizeof(dp_key.sa.src_ip6));
00605 dp_key.src_port = cliPort;
00606
00607 dp_key.dst_af = srvIP->get_family();
00608 if (srvIP->is_ip4())
00609 dp_key.da.dst_ip4.s_addr = srvIP->get_ip4_value();
00610 else
00611 memcpy(&dp_key.da.dst_ip6, srvIP->get_ip6_ptr(), sizeof(dp_key.da.dst_ip6));
00612 dp_key.dst_port = srvPort;
00613
00614 dp_key.protocol = (uint8_t) protocol;
00615 dp_key.vlan_cnots = 1;
00616 if (ctrlPkt->proto_bits & PROTO_BIT__VLAN)
00617 dp_key.vlan_id = layer::get_vlan_layer(ctrlPkt)->vid();
00618 else
00619 dp_key.vlan_id = 0xFFFF;
00620
00621 if (ctrlPkt->proto_bits & PROTO_BIT__GTP)
00622 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GTP_TUNNEL;
00623 else if (ctrlPkt->proto_bits & PROTO_BIT__MPLS)
00624 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL;
00625 /*
00626 else if ( ctrlPkt->encapsulated )
00627 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_OTHER_TUNNEL;
00628 */
00629 else
00630 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_NON_TUNNEL;
00631
00632 memset(&daq_params, 0, sizeof(daq_params));
00633 daq_params.timeout_ms = timeout_ms;
00634 /*
00635 if (flags & DAQ_DC_FLOAT)
00636 daq_params.flags |= DAQ_DATA_CHANNEL_FLOAT;
00637 if (flags & DAQ_DC_ALLOW_MULTIPLE)
00638 daq_params.flags |= DAQ_DATA_CHANNEL_ALLOW_MULTIPLE;
00639 if (flags & DAQ_DC_PERSIST)
00640 daq_params.flags |= DAQ_DATA_CHANNEL_PERSIST;
00641 */
00642
00643 return daq_dp_add_dc(daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, nullptr, &daq_params);
00644 }
END OF CODE