📄 sftarget_reader.c
字号:
/*** Copyright (C) 2006-2007 Sourcefire, Inc.**** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* * Author: Steven Sturges * sftarget_reader.c */#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef TARGET_BASED#include <stdio.h>#include "mstring.h"#include "util.h"#include "parser.h"#include "sftarget_reader.h"#include "sftarget_protocol_reference.h"#include "sfutil/sfrt.h"#include "sfutil/sfxhash.h"#include "sfutil/util_net.h"#include "sftarget_hostentry.h"#include <signal.h>#include <sys/types.h>#include <stdlib.h>#include <errno.h>#include <pthread.h>#include <unistd.h>#include <time.h>#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#include "snort.h"#include "debug.h"static table_t *attribute_lookup_table = NULL;static SFXHASH *attribute_map_table = NULL;static table_t *attribute_lookup_table_tmp = NULL;static SFXHASH *attribute_map_table_tmp = NULL;static table_t *attribute_lookup_table_old = NULL;static SFXHASH *attribute_map_table_old = NULL;static HostAttributeEntry *current_host = NULL;static ApplicationEntry *current_app = NULL;//static MapData *current_map_entry = NULL;ServiceClient sfat_client_or_service;extern char sfat_error_message[STD_BUF];extern char sfat_grammar_error_printed;int ParseTargetMap(char *filename);/*****TODO: cleanup to use config directive *******/#define ATTRIBUTE_MAP_MAX_ROWS 1024u_int32_t SFAT_NumberOfHosts(){ if (attribute_lookup_table) { return sfrt_num_entries(attribute_lookup_table); } return 0;}int SFAT_AddMapEntry(MapEntry *entry){ if (!attribute_map_table_tmp) { /* Attribute Table node includes memory for each entry, * as defined by sizeof(MapEntry). */ attribute_map_table_tmp = sfxhash_new(ATTRIBUTE_MAP_MAX_ROWS, sizeof(int), sizeof(MapEntry), 0, 1, NULL, NULL, 1); if (!attribute_map_table_tmp) FatalError("Failed to allocate attribute map table\n"); } /* Memcopy MapEntry to newly allocated one and store in * a hash table based on entry->id for easy lookup. */ DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "Adding Map Entry: %d %s\n", entry->l_mapid, entry->s_mapvalue);); /* Data from entry will be copied into new node */ sfxhash_add(attribute_map_table_tmp, &entry->l_mapid, entry); return SFAT_OK;}char *SFAT_LookupAttributeNameById(int id){ MapEntry *entry; if (!attribute_map_table_tmp) return NULL; entry = sfxhash_find(attribute_map_table_tmp, &id); if (entry) { DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "Found Attribute Name %s for Id %d\n", entry->s_mapvalue, id);); return entry->s_mapvalue; } DEBUG_WRAP( DebugMessage(DEBUG_ATTRIBUTE, "No Attribute Name for Id %d\n", id);); return NULL;}void FreeApplicationEntry(ApplicationEntry *app){ DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "Freeing ApplicationEntry: 0x%x\n", app);); free(app);}ApplicationEntry * SFAT_CreateApplicationEntry(){ if (current_app) { /* Something went wrong */ FreeApplicationEntry(current_app); current_app = NULL; } current_app = SnortAlloc(sizeof(ApplicationEntry)); return current_app;}HostAttributeEntry * SFAT_CreateHostEntry(){ if (current_host) { /* Something went wrong */ FreeHostEntry(current_host); current_host = NULL; } current_host = SnortAlloc(sizeof(HostAttributeEntry)); return current_host;}void FreeHostEntry(HostAttributeEntry *host){ ApplicationEntry *app = NULL, *tmp_app; if (!host) return; DEBUG_WRAP(DebugMessage(DEBUG_ATTRIBUTE, "Freeing HostEntry: 0x%x\n", host);); /* Free the service list */ if (host->services) { do { tmp_app = host->services; app = tmp_app->next; FreeApplicationEntry(tmp_app); host->services = app; } while (app); } /* Free the client list */ if (host->clients) { do { tmp_app = host->clients; app = tmp_app->next; FreeApplicationEntry(tmp_app); host->clients = app; } while (app); } free(host);}void PrintAttributeData(char *prefix, AttributeData *data){#ifdef DEBUG DebugMessage(DEBUG_ATTRIBUTE, "AttributeData for %s\n", prefix); if (data->type == ATTRIBUTE_NAME) { DebugMessage(DEBUG_ATTRIBUTE, "\ttype: %s\tname: %s\t confidence %d\n", "Name", data->value.s_value, data->confidence); } else { DebugMessage(DEBUG_ATTRIBUTE, "\ttype: %s\tid: %s\t confidence %d", "Id", data->value.l_value, data->confidence); }#endif}int SFAT_SetHostIp4(char *ip){ static HostAttributeEntry *tmp_host = NULL; struct in_addr ip4_inAddr; u_int32_t ipAddr = 0; u_int8_t bits = 32; char *ipMask; char *hasMask; SFAT_CHECKHOST; ipMask = strdup(ip); /* Don't use SnortStrdup, can't FatalError here */ if (!ipMask) { return SFAT_ERROR; } hasMask = strchr(ipMask, '/'); if (hasMask) { *hasMask = '\0'; hasMask++; bits = (char)strtoul(hasMask, NULL, 10); } /* No mask, implicit 32 bits */ /* this is terminated at end of * IP part if mask included */ if (inet_aton(ipMask, &ip4_inAddr) == 0) { free(ipMask); return SFAT_ERROR; } ipAddr = ntohl(ip4_inAddr.s_addr); /*** : Lookup and set current_host via IP addr */ tmp_host = sfrt_lookup(&ipAddr, attribute_lookup_table_tmp); /*** If found, free current_host and set current_host to the one found */ if (tmp_host && (tmp_host->ipAddr == ipAddr) && (tmp_host->bits == bits)) { /* Exact match. */ FreeHostEntry(current_host); current_host = tmp_host; } else { /* New entry for this host/CIDR */ current_host->ipAddr = ipAddr; current_host->bits = bits; } free(ipMask); return SFAT_OK;}int SFAT_SetOSPolicy(char *policy_name, int attribute){ SFAT_CHECKHOST; switch (attribute) { case HOST_INFO_FRAG_POLICY: SnortStrncpy(current_host->hostInfo.fragPolicyName, policy_name, STD_BUF); break; case HOST_INFO_STREAM_POLICY: SnortStrncpy(current_host->hostInfo.streamPolicyName, policy_name, STD_BUF); break; } return SFAT_OK;}int SFAT_SetOSAttribute(AttributeData *data, int attribute){ SFAT_CHECKHOST; switch (attribute) { case HOST_INFO_OS: memcpy(¤t_host->hostInfo.operatingSystem, data, sizeof(AttributeData)); break; case HOST_INFO_VENDOR: memcpy(¤t_host->hostInfo.vendor, data, sizeof(AttributeData)); break; case HOST_INFO_VERSION: memcpy(¤t_host->hostInfo.version, data, sizeof(AttributeData)); break; } return SFAT_OK;}static void AppendApplicationData(ApplicationList **list){ if (!list) return; if (*list) { current_app->next = *list; } *list = current_app; current_app = NULL;}int SFAT_AddApplicationData(){ u_int8_t required_fields; SFAT_CHECKAPP; SFAT_CHECKHOST; if (sfat_client_or_service == ATTRIBUTE_SERVICE) { required_fields = (APPLICATION_ENTRY_PORT | APPLICATION_ENTRY_IPPROTO | APPLICATION_ENTRY_PROTO); if ((current_app->fields & required_fields) != required_fields) { struct in_addr host_addr; host_addr.s_addr = current_host->ipAddr; FatalError("%s(%d) ERROR: Missing required field in Service attribute table for host %s\n", file_name, file_line, inet_ntoa(host_addr)); } AppendApplicationData(¤t_host->services); } else { required_fields = (APPLICATION_ENTRY_PROTO); /* Currently, client data only includes PROTO, not IPPROTO */ if ((current_app->fields & required_fields) != required_fields) { struct in_addr host_addr; host_addr.s_addr = current_host->ipAddr; FatalError("%s(%d) ERROR: Missing required field in Client attribute table for host %s\n", file_name, file_line, inet_ntoa(host_addr)); } AppendApplicationData(¤t_host->clients); } return SFAT_OK;}int SFAT_SetApplicationAttribute(AttributeData *data, int attribute){ SFAT_CHECKAPP; switch(attribute) { case APPLICATION_ENTRY_PORT: /* Convert the port to a integer */ if (data->type == ATTRIBUTE_NAME) { char *endPtr = NULL; unsigned long value = strtoul(data->value.s_value, &endPtr, 10); if ((endPtr == &data->value.s_value[0]) || (errno == ERANGE)) { current_app->port.value.l_value = 0; return SFAT_ERROR; } current_app->port.value.l_value = value; } else { current_app->port.value.l_value = data->value.l_value; } break; case APPLICATION_ENTRY_IPPROTO: memcpy(¤t_app->ipproto, data, sizeof(AttributeData)); /* Add IP Protocol to the reference list */ current_app->ipproto.attributeOrdinal = AddProtocolReference(data->value.s_value); break; case APPLICATION_ENTRY_PROTO: memcpy(¤t_app->protocol, data, sizeof(AttributeData)); /* Add Application Protocol to the reference list */ current_app->protocol.attributeOrdinal = AddProtocolReference(data->value.s_value); break; case APPLICATION_ENTRY_APPLICATION: memcpy(¤t_app->application, data, sizeof(AttributeData)); break; case APPLICATION_ENTRY_VERSION: memcpy(¤t_app->version, data, sizeof(AttributeData)); break; default: attribute = 0; } current_app->fields |= attribute; return SFAT_OK;}#ifdef DEBUGvoid PrintHostAttributeEntry(HostAttributeEntry *host){ ApplicationEntry *app; int i = 0; if (!host) return; DebugMessage(DEBUG_ATTRIBUTE, "Host IP: %s/%d\n", inet_ntoax(ntohl(host->ipAddr)), host->bits); DebugMessage(DEBUG_ATTRIBUTE, "\tOS Information: %s(%d) %s(%d) %s(%d)\n", host->hostInfo.operatingSystem.value.s_value, host->hostInfo.operatingSystem.confidence, host->hostInfo.vendor.value.s_value, host->hostInfo.vendor.confidence, host->hostInfo.version.value.s_value, host->hostInfo.version.confidence); DebugMessage(DEBUG_ATTRIBUTE, "\tPolicy Information: frag:%s stream: %s\n", host->hostInfo.fragPolicyName, host->hostInfo.streamPolicyName); DebugMessage(DEBUG_ATTRIBUTE, "\tServices:\n"); for (i=0, app = host->services; app; app = app->next,i++) { DebugMessage(DEBUG_ATTRIBUTE, "\tService #%d:\n", i); DebugMessage(DEBUG_ATTRIBUTE, "\t\tIPProtocol: %s(%d)\tPort: %s(%d)" "\tProtocol %s(%d)\n", app->ipproto.value.s_value, app->ipproto.confidence, app->port.value.s_value, app->port.confidence, app->protocol.value.s_value, app->protocol.confidence); if (app->fields & APPLICATION_ENTRY_APPLICATION) { DebugMessage(DEBUG_ATTRIBUTE, "\t\tApplication: %s(%d)\n", app->application.value.s_value, app->application.confidence); if (app->fields & APPLICATION_ENTRY_VERSION) DebugMessage(DEBUG_ATTRIBUTE, "\t\tVersion: %s(%d)\n", app->version.value.s_value, app->version.confidence); } } if (i==0) DebugMessage(DEBUG_ATTRIBUTE, "\t\tNone\n"); DebugMessage(DEBUG_ATTRIBUTE, "\tClients:\n"); for (i=0, app = host->clients; app; app = app->next,i++) { DebugMessage(DEBUG_ATTRIBUTE, "\tClient #%d:\n", i); DebugMessage(DEBUG_ATTRIBUTE, "\t\tIPProtocol: %s(%d)\tProtocol %s(%d)\n", app->ipproto.value.s_value, app->ipproto.confidence, app->protocol.value.s_value, app->protocol.confidence); if (app->fields & APPLICATION_ENTRY_PORT) { DebugMessage(DEBUG_ATTRIBUTE, "\t\tPort: %s(%d)\n", app->port.value.s_value, app->port.confidence); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -