file_service.cc
file_stats.cc
file_stats.h
+ file_cache_share.cc
+ file_cache_share.h
)
install (FILES ${FILE_API_INCLUDES}
#include "packet_io/active.h"
#include "packet_io/packet_tracer.h"
#include "time/packet_time.h"
+#include "pub_sub/file_events.h"
#include "file_flows.h"
#include "file_module.h"
#include "file_service.h"
#include "file_stats.h"
+#include "file_cache_share.h"
#define DEFAULT_FILE_LOOKUP_TIMEOUT_CACHED_ITEM 3600 // 1 hour
FileContext* FileCache::find_add(const FileHashKey& hashKey, int64_t timeout)
{
-
if ( !fileHash->get_num_nodes() )
return nullptr;
return node->file;
}
-FileContext* FileCache::add(const FileHashKey& hashKey, int64_t timeout, bool &cache_full)
+FileContext* FileCache::add(const FileHashKey& hashKey, int64_t timeout, bool &cache_full, int64_t& cache_expire, FileInspect* ins)
{
FileNode new_node;
/*
struct timeval time_to_add = { static_cast<time_t>(timeout), 0 };
timeradd(&now, &time_to_add, &new_node.cache_expire_time);
- new_node.file = new FileContext;
-
std::lock_guard<std::mutex> lock(cache_mutex);
-
FileContext* file = find_add(hashKey, timeout);
- if (!file) {
+ if (!file)
+ {
+ if (ins)
+ new_node.file = new FileContext(ins);
+ else
+ new_node.file = new FileContext;
+
int ret = fileHash->insert((void*)&hashKey, &new_node);
+ cache_expire = new_node.cache_expire_time.tv_sec;
+
if (ret != HASH_OK)
{
/* There is already a node or couldn't alloc space for key or cache is full.
PacketTracer::log("add:Insert failed in file cache, returning\n");
cache_full = true;
}
- FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, GET_CURRENT_PACKET,
- "add:Insert failed in file cache, returning\n");
+ if (!ins)
+ FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, GET_CURRENT_PACKET,
+ "add:Insert failed in file cache, returning\n");
file_counts.cache_add_fails++;
delete new_node.file;
return nullptr;
}
+
return new_node.file;
}
else
{
- FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, GET_CURRENT_PACKET,
- "add:file already found in file cache, returning\n");
- delete new_node.file;
+ if (!ins)
+ FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_CRITICAL_LEVEL, GET_CURRENT_PACKET,
+ "add:file already found in file cache, returning\n");
return file;
}
}
-FileContext* FileCache::find(const FileHashKey& hashKey, int64_t timeout)
+FileContext* FileCache::find(const FileHashKey& hashKey, int64_t timeout, int64_t& cache_expire)
{
std::lock_guard<std::mutex> lock(cache_mutex);
struct timeval now;
packet_gettimeofday(&now);
-
if ( timercmp(&node->cache_expire_time, &now, <) )
{
fileHash->release_node(hash_node);
if (timercmp(&node->cache_expire_time, &next_expire_time, <))
node->cache_expire_time = next_expire_time;
+ cache_expire = node->cache_expire_time.tv_sec;
return node->file;
}
FileContext* FileCache::get_file(Flow* flow, uint64_t file_id, bool to_create,
- int64_t timeout, bool using_cache_entry, bool &cache_full)
+ int64_t timeout, bool using_cache_entry, bool &cache_full, int64_t& cache_expire)
{
FileHashKey hashKey;
hashKey.dip = flow->client_ip;
FileContext* file = nullptr;
if (using_cache_entry)
- file = find(hashKey, DEFAULT_FILE_LOOKUP_TIMEOUT_CACHED_ITEM);
+ file = find(hashKey, DEFAULT_FILE_LOOKUP_TIMEOUT_CACHED_ITEM, cache_expire);
else
- file = find(hashKey, timeout);
-
+ file = find(hashKey, timeout, cache_expire);
+
if (to_create and !file)
- file = add(hashKey, timeout, cache_full);
+ file = add(hashKey, timeout, cache_full, cache_expire);
return file;
}
FileContext* FileCache::get_file(Flow* flow, uint64_t file_id, bool to_create, bool using_cache_entry)
{
bool cache_full = false;
- return get_file(flow, file_id, to_create, lookup_timeout, using_cache_entry, cache_full);
+ int64_t cache_expire = 0;
+ return get_file(flow, file_id, to_create, lookup_timeout, using_cache_entry, cache_full, cache_expire);
}
FileVerdict FileCache::check_verdict(Packet* p, FileInfo* file,
return verdict;
}
+void FileCache::publish_file_cache_event(Flow* flow, FileInfo* file, int64_t timeout)
+{
+ if (SnortConfig::get_conf()->mp_dbus)
+ {
+ FileHashKey hashkey;
+ hashkey.dip = flow->client_ip;
+ hashkey.sip = flow->server_ip;
+ hashkey.dgroup = flow->client_group;
+ hashkey.sgroup = flow->server_group;
+ hashkey.file_id = file->get_file_id();
+ hashkey.asid = flow->key->addressSpaceId;
+ hashkey.padding[0] = hashkey.padding[1] = hashkey.padding[2] = 0;
+
+
+ std::shared_ptr<FileMPEvent> fe = std::make_shared<FileMPEvent>(hashkey, timeout, *file);
+ unsigned file_pub_id = MPDataBus::get_id(file_pub_key);
+ MPDataBus::publish(file_pub_id, FileMPEvents::FILE_SHARE_SYNC, fe);
+
+ FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
+ "File Cache Sharing: Publish event with file_id %lu\n", hashkey.file_id);
+ }
+}
+
int FileCache::store_verdict(Flow* flow, FileInfo* file, int64_t timeout, bool &cache_full)
{
assert(file);
uint64_t file_id = file->get_file_id();
+ int64_t cache_expire = 0;
if (!file_id)
{
return 0;
}
- FileContext* file_got = get_file(flow, file_id, true, timeout, false, cache_full);
+ FileContext* file_got = get_file(flow, file_id, true, timeout, false, cache_full, cache_expire);
if (file_got)
{
+ publish_file_cache_event(flow, file, cache_expire);
*((FileInfo*)(file_got)) = *file;
if (FILE_VERDICT_PENDING == file->verdict and file != file_got)
class ExpectedFileCache;
-class FileCache
-{
-public:
-
PADDING_GUARD_BEGIN
struct FileHashKey
{
};
PADDING_GUARD_END
+class FileCache
+{
+public:
+
struct FileNode
{
struct timeval cache_expire_time = {0, 0};
void set_block_timeout(int64_t);
void set_lookup_timeout(int64_t);
void set_max_files(int64_t);
-
+ snort::FileContext* add(const FileHashKey&, int64_t timeout, bool &cache_full, int64_t& cache_expire, FileInspect* ins = nullptr);
snort::FileContext* get_file(snort::Flow*, uint64_t file_id, bool to_create, bool using_cache_entry);
FileVerdict cached_verdict_lookup(snort::Packet*, snort::FileInfo*,
snort::FilePolicyBase*,const uint8_t* current_data, uint32_t current_data_len);
bool apply_verdict(snort::Packet*, snort::FileContext*, FileVerdict, bool resume,
snort::FilePolicyBase*);
+
-private:
- snort::FileContext* add(const FileHashKey&, int64_t timeout, bool &cache_full);
- snort::FileContext* find(const FileHashKey&, int64_t);
+private:
+ snort::FileContext* find(const FileHashKey&, int64_t, int64_t& cache_expire);
snort::FileContext* find_add(const FileHashKey&, int64_t);
snort::FileContext* get_file(snort::Flow*, uint64_t file_id, bool to_create,
- int64_t timeout, bool using_cache_entry, bool &cache_full);
+ int64_t timeout, bool using_cache_entry, bool &cache_full, int64_t& cache_expire);
FileVerdict check_verdict(snort::Packet*, snort::FileInfo*, snort::FilePolicyBase*,const uint8_t* current_data, uint32_t current_data_len);
int store_verdict(snort::Flow*, snort::FileInfo*, int64_t timeout, bool &cache_full);
+ void publish_file_cache_event(snort::Flow* flow, snort::FileInfo* file, int64_t timeout);
/* The hash table of expected files */
ExpectedFileCache* fileHash = nullptr;
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2025 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// file_cache_share.cc author Shilpa Nagpal <shinagpa@cisco.com>
+
+
+#include "config.h"
+
+#include "file_cache_share.h"
+#include "file_service.h"
+#include "log/messages.h"
+
+using namespace snort;
+
+void FileCacheShare::handle(DataEvent& de, Flow*)
+{
+ FileMPEvent& fe = static_cast<FileMPEvent&>(de);
+ int64_t timeout = fe.get_timeout();
+ FileHashKey key = fe.get_hashkey();
+ FileInfo file = fe.get_file_ctx();
+
+ LogMessage("File Cache Sharing: Received event with file_id %lu\n", key.file_id);
+
+ FileCache* file_cache = FileService::get_file_cache();
+ if (file_cache)
+ {
+ bool cache_full = false;
+ int64_t cache_expire = 0;
+ FileContext* file_got = file_cache->add(key, timeout, cache_full, cache_expire, ins);
+ if (file_got)
+ {
+ *((FileInfo*)(file_got)) = file;
+ }
+ }
+}
+
+bool serialize_file_event(snort::DataEvent* event, char*& buffer, uint16_t* len)
+{
+ if (!event)
+ return false;
+
+ snort::FileMPEvent* file_event = static_cast<snort::FileMPEvent*>(event);
+ uint16_t event_buffer_len = file_event->get_data_len();
+ if (event_buffer_len == 0)
+ return false;
+
+ buffer = new char[event_buffer_len];
+ if (!buffer)
+ return false;
+
+ file_event->serialize(buffer, len);
+ return true;
+}
+
+bool deserialize_file_event(const char* buffer, uint16_t len, snort::DataEvent*& event)
+{
+ if (!buffer || len == 0)
+ return false;
+
+ snort::FileMPEvent* file_event = new snort::FileMPEvent();
+ if (!file_event)
+ return false;
+
+ file_event->deserialize(buffer, len);
+ event = file_event;
+ return true;
+}
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2025 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// file_cache.h author Shilpa Nagpal <shinagpa@cisco.com>
+
+#ifndef FILE_CACHE_SHARE_H
+#define FILE_CACHE_SHARE_H
+
+#include "framework/mp_data_bus.h"
+#include "pub_sub/file_events.h"
+
+class FileCacheShare : public snort::DataHandler
+{
+public:
+ FileCacheShare(FileInspect* fi) : DataHandler(FILE_ID_NAME) { ins = fi; }
+ void handle(snort::DataEvent&, snort::Flow*) override;
+private:
+ FileInspect* ins;
+};
+
+bool serialize_file_event(snort::DataEvent* event, char*& buffer, uint16_t* len);
+bool deserialize_file_event(const char* buffer, uint16_t len, snort::DataEvent*& event);
+
+#endif
+
#include "file_flows.h"
#include "file_module.h"
#include "file_service.h"
+#include "file_cache_share.h"
using namespace snort;
FileService::set_max_file_depth(sc);
+ if(sc->mp_dbus)
+ {
+ MPSerializeFunc serialize_func = serialize_file_event;
+ MPDeserializeFunc deserialize_func = deserialize_file_event;
+
+ MPDataBus::register_event_helpers(file_pub_key, FileMPEvents::FILE_SHARE_SYNC, serialize_func, deserialize_func);
+ MPDataBus::subscribe(file_pub_key, FileMPEvents::FILE_SHARE_SYNC, new FileCacheShare(this));
+ }
return true;
}
#include "protocols/packet.h"
#include "pub_sub/intrinsic_event_ids.h"
#include "utils/util.h"
-
#ifdef UNIT_TEST
#include "catch/snort_catch.h"
#endif
}
}
+void FileInfo::serialize(char* buffer, uint16_t* len)
+{
+ int offset = *len;
+
+ auto write_bool = [&](bool val) {
+ memcpy(buffer + offset, &val, sizeof(val));
+ offset += sizeof(val);
+ };
+
+ auto write_string = [&](const std::string& str, bool is_set) {
+ write_bool(is_set);
+ if (is_set)
+ {
+ uint32_t len = static_cast<uint32_t>(str.length());
+ memcpy(buffer + offset, &len, sizeof(len));
+ offset += sizeof(len);
+ memcpy(buffer + offset, str.data(), len);
+ offset += len;
+ }
+ };
+
+ memcpy(buffer + offset,(uint16_t *) sha256, SHA256_HASH_SIZE);
+ offset += SHA256_HASH_SIZE;
+ memcpy(buffer + offset, &verdict, sizeof(verdict));
+ offset += sizeof(verdict);
+ memcpy(buffer + offset, &file_size, sizeof(file_size));
+ offset += sizeof(file_size);
+ memcpy(buffer + offset, &direction, sizeof(direction));
+ offset += sizeof(direction);
+ memcpy(buffer + offset, &file_id, sizeof(file_id));
+ offset += sizeof(file_id);
+ memcpy(buffer + offset, &file_type_id, sizeof(file_type_id));
+ offset += sizeof(file_type_id);
+ memcpy(buffer + offset, &file_state.capture_state, sizeof(file_state.capture_state));
+ offset += sizeof(file_state.capture_state);
+ memcpy(buffer + offset, &file_state.sig_state, sizeof(file_state.sig_state));
+ offset += sizeof(file_state.sig_state);
+ memcpy(buffer + offset, &policy_id, sizeof(policy_id));
+ offset += sizeof(policy_id);
+ write_string(file_name, file_name_set);
+ write_string(url, url_set);
+ write_string(host_name, host_set);
+ write_bool(file_type_enabled);
+ write_bool(file_signature_enabled);
+ write_bool(file_capture_enabled);
+ write_bool(is_partial);
+
+ *len = offset;
+}
+
+void FileInfo::deserialize(const char* buffer, uint16_t& offset)
+{
+ auto read_bool = [&](bool& val) {
+ memcpy(&val, buffer + offset, sizeof(val));
+ offset += sizeof(val);
+ };
+
+ auto read_string = [&](std::string& str, bool& is_set) {
+ read_bool(is_set);
+ if (is_set)
+ {
+ uint32_t len = 0;
+ memcpy(&len, buffer + offset, sizeof(len));
+ offset += sizeof(len);
+ str.assign(buffer + offset, len);
+ offset += len;
+ }
+ };
+
+ if (!sha256)
+ sha256 = new uint8_t[SHA256_HASH_SIZE];
+ memcpy(sha256, (const uint8_t *)(buffer + offset), SHA256_HASH_SIZE);
+ offset += SHA256_HASH_SIZE;
+ memcpy(&verdict, buffer + offset, sizeof(verdict));
+ offset += sizeof(verdict);
+ memcpy(&file_size, buffer + offset, sizeof(file_size));
+ offset += sizeof(file_size);
+ memcpy(&direction, buffer + offset, sizeof(direction));
+ offset += sizeof(direction);
+ memcpy(&file_id, buffer + offset, sizeof(file_id));
+ offset += sizeof(file_id);
+ memcpy(&file_type_id, buffer + offset, sizeof(file_type_id));
+ offset += sizeof(file_type_id);
+ memcpy(&file_state.capture_state, buffer + offset, sizeof(file_state.capture_state));
+ offset += sizeof(file_state.capture_state);
+ memcpy(&file_state.sig_state, buffer + offset, sizeof(file_state.sig_state));
+ offset += sizeof(file_state.sig_state);
+ memcpy(&policy_id, buffer + offset, sizeof(policy_id));
+ offset += sizeof(policy_id);
+ read_string(file_name, file_name_set);
+ read_string(url, url_set);
+ read_string(host_name, host_set);
+ read_bool(file_type_enabled);
+ read_bool(file_signature_enabled);
+ read_bool(file_capture_enabled);
+ read_bool(is_partial);
+}
+
FileInfo::FileInfo(const FileInfo& other)
{
copy(other);
return user_file_data;
}
+FileContext::FileContext (FileInspect* ins)
+{
+ file_type_context = nullptr;
+ file_signature_context = nullptr;
+ file_capture = nullptr;
+ file_segments = nullptr;
+ inspector = ins;
+ ins->add_global_ref();
+ config = ins->config;
+}
+
FileContext::FileContext ()
{
file_type_context = nullptr;
void set_partial_flag(bool partial);
bool is_partial_download() const;
+ void serialize(char* buffer, uint16_t* offset);
+ void deserialize(const char* buffer, uint16_t& offset);
+
protected:
std::string file_name;
bool file_name_set = false;
{
public:
FileContext();
+ FileContext (FileInspect* ins);
~FileContext() override;
void check_policy(Flow*, FileDirection, FilePolicyBase*);
ssh_events.h
ssl_events.h
dns_events.h
+ file_events.h
+ file_events_ids.h
)
add_library( pub_sub OBJECT
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2022-2025 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// http_event_ids.h author Shilpa Nagpal <shinagpa@cisco.com>
+
+// File events published by File Service for MP snort support.
+
+#ifndef FILE_MP_EVENTS_H
+#define FILE_MP_EVENTS_H
+
+#include "framework/mp_data_bus.h"
+#include "file_events_ids.h"
+#include "file_api/file_cache.h"
+#include "hash/hashes.h"
+
+namespace snort
+{
+
+class SO_PUBLIC FileMPEvent : public snort::DataEvent
+{
+ public:
+
+ FileMPEvent(const FileHashKey& key, int64_t tm, FileInfo& file) : timeout(tm), hashkey(key), file_ctx(file)
+ {
+ len = sizeof(timeout) + sizeof(hashkey.sip) + sizeof(hashkey.sgroup) +
+ sizeof(hashkey.dip) + sizeof(hashkey.dgroup) +
+ sizeof(hashkey.file_id) + sizeof(hashkey.asid) + sizeof(hashkey.padding) +
+ sizeof(file) + SHA256_HASH_SIZE;
+ }
+
+ FileMPEvent() : hashkey()
+ {
+ timeout = 0;
+ len = 0;
+ }
+
+ int64_t get_timeout()
+ {
+ return timeout;
+ }
+
+ FileInfo get_file_ctx()
+ {
+ return file_ctx;
+ }
+
+ FileHashKey get_hashkey()
+ {
+ return hashkey;
+ }
+
+ uint16_t get_data_len()
+ {
+ return len;
+ }
+
+ void deserialize(const char* d, uint16_t len)
+ {
+ uint16_t offset = 0;
+ memcpy(&timeout, d, sizeof(timeout));
+ offset += sizeof(timeout);
+ memcpy(&hashkey.sip, d + offset, sizeof(hashkey.sip));
+ offset += sizeof(hashkey.sip);
+ memcpy(&hashkey.sgroup, d + offset, sizeof(hashkey.sgroup));
+ offset += sizeof(hashkey.sgroup);
+ memcpy(&hashkey.dip, d + offset, sizeof(hashkey.dip));
+ offset += sizeof(hashkey.dip);
+ memcpy(&hashkey.dgroup, d + offset, sizeof(hashkey.dgroup));
+ offset += sizeof(hashkey.dgroup);
+ memcpy(&hashkey.file_id, d + offset, sizeof(hashkey.file_id));
+ offset += sizeof(hashkey.file_id);
+ memcpy(&hashkey.asid, d + offset, sizeof(hashkey.asid));
+ offset += sizeof(hashkey.asid);
+ memcpy(&hashkey.padding, d + offset, sizeof(hashkey.padding));
+ offset += sizeof(hashkey.padding);
+ file_ctx.deserialize(d, offset);
+ this->len = len;
+ }
+
+ void serialize(char* buffer, uint16_t* len)
+ {
+ uint16_t offset = 0;
+ memcpy(buffer, &timeout, sizeof(timeout));
+ offset += sizeof(timeout);
+ memcpy(buffer + offset, &hashkey.sip, sizeof(hashkey.sip));
+ offset += sizeof(hashkey.sip);
+ memcpy(buffer + offset, &hashkey.sgroup, sizeof(hashkey.sgroup));
+ offset += sizeof(hashkey.sgroup);
+ memcpy(buffer + offset, &hashkey.dip, sizeof(hashkey.dip));
+ offset += sizeof(hashkey.dip);
+ memcpy(buffer + offset, &hashkey.dgroup, sizeof(hashkey.dgroup));
+ offset += sizeof(hashkey.dgroup);
+ memcpy(buffer + offset, &hashkey.file_id, sizeof(hashkey.file_id));
+ offset += sizeof(hashkey.file_id);
+ memcpy(buffer + offset, &hashkey.asid, sizeof(hashkey.asid));
+ offset += sizeof(hashkey.asid);
+ memcpy(buffer + offset, &hashkey.padding, sizeof(hashkey.padding));
+ offset += sizeof(hashkey.padding);
+ file_ctx.serialize(buffer, &offset);
+ *len = offset;
+ }
+
+ private:
+ int64_t timeout;
+ FileHashKey hashkey;
+ FileInfo file_ctx;
+ uint16_t len;
+};
+
+}
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2022-2025 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// http_event_ids.h author Shilpa Nagpal <shinagpa@cisco.com>
+
+// File events published by File Service for MP snort support.
+
+#ifndef FILE_MP_EVENTS_IDS_H
+#define FILE_MP_EVENTS_IDS_H
+
+#include "framework/mp_data_bus.h"
+
+namespace snort
+{
+
+struct FileMPEvents
+{ enum : unsigned {
+
+ FILE_SHARE = 0,
+ FILE_SHARE_SYNC,
+ num_ids
+}; };
+
+const PubKey file_pub_key { "file_mp_events", FileMPEvents::num_ids };
+
+}
+#endif
+