✨ feat(integration decoders): http and glimpse_detector
compile pass, todo test
This commit is contained in:
415
decoders/glimpse_detector/libprotoident/libprotoident.cc
Normal file
415
decoders/glimpse_detector/libprotoident/libprotoident.cc
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2011-2016 The University of Waikato, Hamilton, New Zealand.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is part of libprotoident.
|
||||
*
|
||||
* This code has been developed by the University of Waikato WAND
|
||||
* research group. For further information please see http://www.wand.net.nz/
|
||||
*
|
||||
* libprotoident is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libprotoident 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
//#include <libtrace.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "libprotoident.h"
|
||||
#include "proto_manager.h"
|
||||
|
||||
bool init_called = false;
|
||||
LPIModuleMap TCP_protocols;
|
||||
LPIModuleMap UDP_protocols;
|
||||
|
||||
lpi_module_t *lpi_icmp = NULL;
|
||||
lpi_module_t *lpi_unsupported = NULL;
|
||||
lpi_module_t *lpi_unknown_tcp = NULL;
|
||||
lpi_module_t *lpi_unknown_udp = NULL;
|
||||
|
||||
static LPINameMap lpi_names;
|
||||
static LPIProtocolMap lpi_protocols;
|
||||
static LPICategoryMap lpi_categories;
|
||||
static LPICategoryProtocolMap lpi_category_protocols;
|
||||
|
||||
int lpi_init_library(int level) {
|
||||
|
||||
if (init_called) {
|
||||
fprintf(stderr, "WARNING: lpi_init_library has already been called\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (register_tcp_protocols(&TCP_protocols) == -1)
|
||||
return -1;
|
||||
|
||||
if (register_udp_protocols(&UDP_protocols) == -1)
|
||||
return -1;
|
||||
|
||||
init_other_protocols(&lpi_names, &lpi_protocols, &lpi_category_protocols);
|
||||
|
||||
register_names(&TCP_protocols, &lpi_names, &lpi_protocols, &lpi_category_protocols);
|
||||
register_names(&UDP_protocols, &lpi_names, &lpi_protocols, &lpi_category_protocols);
|
||||
|
||||
register_category_names(&lpi_categories);
|
||||
|
||||
init_called = true;
|
||||
|
||||
if (TCP_protocols.empty() && UDP_protocols.empty()) {
|
||||
fprintf(stderr, "WARNING: No protocol modules loaded\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void lpi_free_library() {
|
||||
|
||||
free_protocols(&TCP_protocols);
|
||||
free_protocols(&UDP_protocols);
|
||||
|
||||
if (lpi_icmp != NULL) {
|
||||
delete lpi_icmp;
|
||||
lpi_icmp = NULL;
|
||||
}
|
||||
|
||||
if (lpi_unsupported != NULL) {
|
||||
delete lpi_unsupported;
|
||||
lpi_unsupported = NULL;
|
||||
}
|
||||
|
||||
if (lpi_unknown_tcp != NULL) {
|
||||
delete lpi_unknown_tcp;
|
||||
lpi_unknown_tcp = NULL;
|
||||
}
|
||||
|
||||
if (lpi_unknown_udp != NULL) {
|
||||
delete lpi_unknown_udp;
|
||||
lpi_unknown_udp = NULL;
|
||||
}
|
||||
|
||||
init_called = false;
|
||||
}
|
||||
|
||||
void lpi_init_data(lpi_data_t *data) {
|
||||
|
||||
data->payload[0] = 0;
|
||||
data->payload[1] = 0;
|
||||
data->seen_syn[0] = false;
|
||||
data->seen_syn[1] = false;
|
||||
data->seqno[0] = 0;
|
||||
data->seqno[1] = 0;
|
||||
data->observed[0] = 0;
|
||||
data->observed[1] = 0;
|
||||
data->server_port = 0;
|
||||
data->client_port = 0;
|
||||
data->trans_proto = 0;
|
||||
data->payload_len[0] = 0;
|
||||
data->payload_len[1] = 0;
|
||||
data->ips[0] = 0;
|
||||
data->ips[1] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
TRACE_IPPROTO_IP = 0, /**< IP pseudo protocol number */
|
||||
TRACE_IPPROTO_ICMP = 1, /**< Internet Control Message protocol */
|
||||
TRACE_IPPROTO_IGMP = 2, /**< Internet Group Management Protocol */
|
||||
TRACE_IPPROTO_IPIP = 4, /**< IP encapsulated in IP */
|
||||
TRACE_IPPROTO_TCP = 6, /**< Transmission Control Protocol */
|
||||
TRACE_IPPROTO_UDP = 17, /**< User Datagram Protocol */
|
||||
TRACE_IPPROTO_IPV6 = 41, /**< IPv6 over IPv4 */
|
||||
TRACE_IPPROTO_ROUTING = 43, /**< IPv6 Routing header */
|
||||
TRACE_IPPROTO_FRAGMENT = 44, /**< IPv6 Fragmentation header */
|
||||
TRACE_IPPROTO_RSVP = 46, /**< Resource Reservation Protocol */
|
||||
TRACE_IPPROTO_GRE = 47, /**< General Routing Encapsulation */
|
||||
TRACE_IPPROTO_ESP = 50, /**< Encapsulated Security Payload [RFC2406] */
|
||||
TRACE_IPPROTO_AH = 51, /**< Authentication Header [RFC2402] */
|
||||
TRACE_IPPROTO_ICMPV6 = 58, /**< ICMPv6 */
|
||||
TRACE_IPPROTO_NONE = 59, /**< IPv6 no next header */
|
||||
TRACE_IPPROTO_DSTOPTS = 60, /**< IPv6 destination options */
|
||||
TRACE_IPPROTO_OSPF = 89, /**< Open Shortest Path First routing protocol */
|
||||
TRACE_IPPROTO_PIM = 103, /**< Protocol Independant Multicast */
|
||||
TRACE_IPPROTO_SCTP = 132 /**< Stream Control Transmission Protocol */
|
||||
} libtrace_ipproto_t;
|
||||
|
||||
|
||||
static lpi_module_t *test_protocol_list(LPIModuleList *ml, lpi_data_t *data) {
|
||||
|
||||
LPIModuleList::iterator l_it;
|
||||
|
||||
/* Turns out naively looping through the modules is quicker
|
||||
* than trying to do intelligent stuff with threads. Most
|
||||
* callbacks complete very quickly so threading overhead is a
|
||||
* major problem */
|
||||
for (l_it = ml->begin(); l_it != ml->end(); ++ l_it) {
|
||||
lpi_module_t *module = *l_it;
|
||||
|
||||
/* To save time, I'm going to break on the first successful
|
||||
* match. A threaded version would wait for all the modules
|
||||
* to run, storing all successful results in a list of some
|
||||
* sort and selecting an appropriate result from there.
|
||||
*/
|
||||
|
||||
if (module->lpi_callback(data, module))
|
||||
return module;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
static lpi_module_t *guess_protocol(LPIModuleMap *modmap, lpi_data_t *data) {
|
||||
|
||||
lpi_module_t *proto = NULL;
|
||||
|
||||
LPIModuleMap::iterator m_it;
|
||||
|
||||
/* Deal with each priority in turn - want to match higher priority
|
||||
* rules first.
|
||||
*/
|
||||
|
||||
for (m_it = modmap->begin(); m_it != modmap->end(); ++ m_it) {
|
||||
LPIModuleList *ml = m_it->second;
|
||||
|
||||
proto = test_protocol_list(ml, data);
|
||||
|
||||
if (proto != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
return proto;
|
||||
|
||||
}
|
||||
|
||||
lpi_module_t *lpi_guess_protocol(lpi_data_t *data) {
|
||||
|
||||
lpi_module_t *p = NULL;
|
||||
|
||||
if (!init_called) {
|
||||
fprintf(stderr, "lpi_init_library was never called - cannot guess the protocol\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(data->trans_proto) {
|
||||
case TRACE_IPPROTO_ICMP:
|
||||
return lpi_icmp;
|
||||
case TRACE_IPPROTO_TCP:
|
||||
p = guess_protocol(&TCP_protocols, data);
|
||||
if (p == NULL)
|
||||
p = lpi_unknown_tcp;
|
||||
return p;
|
||||
|
||||
case TRACE_IPPROTO_UDP:
|
||||
p = guess_protocol(&UDP_protocols, data);
|
||||
if (p == NULL)
|
||||
p = lpi_unknown_udp;
|
||||
return p;
|
||||
default:
|
||||
return lpi_unsupported;
|
||||
}
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
lpi_category_t lpi_categorise(lpi_module_t *module) {
|
||||
|
||||
if (module == NULL)
|
||||
return LPI_CATEGORY_NO_CATEGORY;
|
||||
|
||||
return module->category;
|
||||
|
||||
}
|
||||
|
||||
const char *lpi_print_category(lpi_category_t category) {
|
||||
|
||||
switch(category) {
|
||||
case LPI_CATEGORY_WEB:
|
||||
return "Web";
|
||||
case LPI_CATEGORY_MAIL:
|
||||
return "Mail";
|
||||
case LPI_CATEGORY_CHAT:
|
||||
return "Chat";
|
||||
case LPI_CATEGORY_P2P:
|
||||
return "P2P";
|
||||
case LPI_CATEGORY_P2P_STRUCTURE:
|
||||
return "P2P_Structure";
|
||||
case LPI_CATEGORY_KEY_EXCHANGE:
|
||||
return "Key_Exchange";
|
||||
case LPI_CATEGORY_ECOMMERCE:
|
||||
return "ECommerce";
|
||||
case LPI_CATEGORY_GAMING:
|
||||
return "Gaming";
|
||||
case LPI_CATEGORY_ENCRYPT:
|
||||
return "Encryption";
|
||||
case LPI_CATEGORY_MONITORING:
|
||||
return "Measurement";
|
||||
case LPI_CATEGORY_NEWS:
|
||||
return "News";
|
||||
case LPI_CATEGORY_MALWARE:
|
||||
return "Malware";
|
||||
case LPI_CATEGORY_SECURITY:
|
||||
return "Security";
|
||||
case LPI_CATEGORY_ANTISPAM:
|
||||
return "Antispam";
|
||||
case LPI_CATEGORY_VOIP:
|
||||
return "VOIP";
|
||||
case LPI_CATEGORY_TUNNELLING:
|
||||
return "Tunnelling";
|
||||
case LPI_CATEGORY_NAT:
|
||||
return "NAT_Traversal";
|
||||
case LPI_CATEGORY_STREAMING:
|
||||
return "Streaming";
|
||||
case LPI_CATEGORY_SERVICES:
|
||||
return "Services";
|
||||
case LPI_CATEGORY_DATABASES:
|
||||
return "Databases";
|
||||
case LPI_CATEGORY_FILES:
|
||||
return "File_Transfer";
|
||||
case LPI_CATEGORY_REMOTE:
|
||||
return "Remote_Access";
|
||||
case LPI_CATEGORY_TELCO:
|
||||
return "Telco_Services";
|
||||
case LPI_CATEGORY_P2PTV:
|
||||
return "P2PTV";
|
||||
case LPI_CATEGORY_RCS:
|
||||
return "Revision_Control";
|
||||
case LPI_CATEGORY_LOGGING:
|
||||
return "Logging";
|
||||
case LPI_CATEGORY_PRINTING:
|
||||
return "Printing";
|
||||
case LPI_CATEGORY_TRANSLATION:
|
||||
return "Translation";
|
||||
case LPI_CATEGORY_CDN:
|
||||
return "CDN";
|
||||
case LPI_CATEGORY_CLOUD:
|
||||
return "Cloud";
|
||||
case LPI_CATEGORY_NOTIFICATION:
|
||||
return "Notification";
|
||||
case LPI_CATEGORY_SERIALISATION:
|
||||
return "Serialisation";
|
||||
case LPI_CATEGORY_BROADCAST:
|
||||
return "Broadcast";
|
||||
case LPI_CATEGORY_LOCATION:
|
||||
return "Location";
|
||||
case LPI_CATEGORY_CACHING:
|
||||
return "Caching";
|
||||
case LPI_CATEGORY_ICS:
|
||||
return "ICS";
|
||||
case LPI_CATEGORY_MOBILE_APP:
|
||||
return "Mobile App";
|
||||
case LPI_CATEGORY_IPCAMERAS:
|
||||
return "IP Cameras";
|
||||
case LPI_CATEGORY_EDUCATIONAL:
|
||||
return "Educational";
|
||||
case LPI_CATEGORY_MESSAGE_QUEUE:
|
||||
return "Message_Queuing";
|
||||
case LPI_CATEGORY_ICMP:
|
||||
return "ICMP";
|
||||
case LPI_CATEGORY_MIXED:
|
||||
return "Mixed";
|
||||
case LPI_CATEGORY_NOPAYLOAD:
|
||||
return "No_Payload";
|
||||
case LPI_CATEGORY_UNKNOWN:
|
||||
return "Unknown";
|
||||
case LPI_CATEGORY_UNSUPPORTED:
|
||||
return "Unsupported";
|
||||
case LPI_CATEGORY_NO_CATEGORY:
|
||||
return "Uncategorised";
|
||||
case LPI_CATEGORY_LAST:
|
||||
return "Invalid_Category";
|
||||
}
|
||||
|
||||
return "Invalid_Category";
|
||||
|
||||
}
|
||||
|
||||
const char *lpi_print(lpi_protocol_t proto) {
|
||||
|
||||
LPINameMap::iterator it;
|
||||
|
||||
it = lpi_names.find(proto);
|
||||
|
||||
if (it == lpi_names.end()) {
|
||||
return "NULL";
|
||||
}
|
||||
return (it->second);
|
||||
|
||||
}
|
||||
|
||||
lpi_protocol_t lpi_get_protocol_by_name(char *name) {
|
||||
|
||||
LPIProtocolMap::iterator it;
|
||||
|
||||
it = lpi_protocols.find(name);
|
||||
|
||||
if (it == lpi_protocols.end()) {
|
||||
return LPI_PROTO_UNKNOWN;
|
||||
}
|
||||
|
||||
return (it->second);
|
||||
}
|
||||
|
||||
lpi_category_t lpi_get_category_by_name(char *name) {
|
||||
|
||||
LPICategoryMap::iterator it;
|
||||
|
||||
it = lpi_categories.find(name);
|
||||
|
||||
if (it == lpi_categories.end()) {
|
||||
return LPI_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
return (it->second);
|
||||
}
|
||||
|
||||
lpi_category_t lpi_get_category_by_protocol(lpi_protocol_t protocol) {
|
||||
|
||||
LPICategoryProtocolMap::iterator it;
|
||||
|
||||
it = lpi_category_protocols.find(protocol);
|
||||
|
||||
if (it == lpi_category_protocols.end()) {
|
||||
return LPI_CATEGORY_UNKNOWN;
|
||||
}
|
||||
|
||||
return (it->second);
|
||||
}
|
||||
|
||||
bool lpi_is_protocol_inactive(lpi_protocol_t proto) {
|
||||
|
||||
LPINameMap::iterator it;
|
||||
|
||||
it = lpi_names.find(proto);
|
||||
|
||||
if (it == lpi_names.end()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user