⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftfil.c

📁 netflow,抓包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 2001 Mark Fullmer and The Ohio State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *      $Id: ftfil.c,v 1.18 2003/04/02 16:07:12 maf Exp $ */#include "ftconfig.h"#include "ftlib.h"#include <sys/time.h>#include <sys/types.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/resource.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/stat.h>#include <ctype.h>#include <syslog.h>#include <dirent.h>#include <limits.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <fcntl.h>#include <zlib.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H  #include <string.h>#endif#if !HAVE_STRSEP  char    *strsep (char **, const char *);#endif#define PARSE_PRIMITIVE_TYPE_INIT(A)\  if (!(A = malloc (sizeof *A))) {\    fterr_warn("malloc()");\    return -1;\  }\  bzero(A, sizeof *A);\  A->init = 1;\  A->default_mode = FT_FIL_MODE_DENY;\  lp->cur_primitive->lookup = A;\#define RADIX_TRIE_INIT\  if (!rn_init_called) {\    max_keylen = sizeof(struct radix_sockaddr_in);\    rn_init();\    rn_init_called = 1;\  }\extern int max_keylen;extern u_int32 mask_lookup[];static int rn_init_called;static struct radix_node_head *rhead;enum ftfil_op { FT_FIL_OP_UNSET, FT_FIL_OP_LT, FT_FIL_OP_GT,                   FT_FIL_OP_EQ, FT_FIL_OP_NE, FT_FIL_OP_GE,                   FT_FIL_OP_LE };    enum ftfil_parse_state { PARSE_STATE_UNSET, PARSE_STATE_PRIMITIVE,                          PARSE_STATE_DEFINITION };    enum ftfil_def_match { FT_FIL_DEFINITION_MATCH_UNSET,                               FT_FIL_DEFINITION_MATCH_SRC_AS,                               FT_FIL_DEFINITION_MATCH_DST_AS,                               FT_FIL_DEFINITION_MATCH_IP_SRC_ADDR,                               FT_FIL_DEFINITION_MATCH_IP_DST_ADDR,                               FT_FIL_DEFINITION_MATCH_IP_EXPORTER_ADDR,                               FT_FIL_DEFINITION_MATCH_IP_NEXT_HOP_ADDR,                               FT_FIL_DEFINITION_MATCH_IP_SC_ADDR,                               FT_FIL_DEFINITION_MATCH_IP_PROTOCOL,                               FT_FIL_DEFINITION_MATCH_IP_SRC_PREFIX_LEN,                               FT_FIL_DEFINITION_MATCH_IP_DST_PREFIX_LEN,                               FT_FIL_DEFINITION_MATCH_IP_TOS,                               FT_FIL_DEFINITION_MATCH_IP_MARKED_TOS,                               FT_FIL_DEFINITION_MATCH_IP_TCP_FLAGS,                               FT_FIL_DEFINITION_MATCH_IP_SRC_PORT,                               FT_FIL_DEFINITION_MATCH_IP_DST_PORT,                               FT_FIL_DEFINITION_MATCH_INPUT_IF,                               FT_FIL_DEFINITION_MATCH_OUTPUT_IF,                               FT_FIL_DEFINITION_MATCH_START_TIME,                               FT_FIL_DEFINITION_MATCH_END_TIME,                               FT_FIL_DEFINITION_MATCH_FLOWS,                               FT_FIL_DEFINITION_MATCH_OCTETS,                               FT_FIL_DEFINITION_MATCH_PACKETS,                               FT_FIL_DEFINITION_MATCH_XTRA_PACKETS,                               FT_FIL_DEFINITION_MATCH_DURATION,                               FT_FIL_DEFINITION_MATCH_ENGINE_ID,                               FT_FIL_DEFINITION_MATCH_ENGINE_TYPE,                               FT_FIL_DEFINITION_MATCH_SRC_TAG,                               FT_FIL_DEFINITION_MATCH_DST_TAG,                               FT_FIL_DEFINITION_MATCH_PPS,                               FT_FIL_DEFINITION_MATCH_BPS,                               FT_FIL_DEFINITION_MATCH_RANDOM_SAMPLE };char *op_name_lookup[] = {"Unset", "lt", "gt", "eq", "ne", "ge", "le"};char *mode_name_lookup[] = {"Unset", "permit", "deny"};struct line_parser {  enum ftfil_parse_state state;  enum ftfil_primitive_type type;  enum ftfil_mode mode;  struct ftfil_primitive *cur_primitive;  struct ftfil_def *cur_def;  struct ftfil_match *cur_def_match;  struct ftsym *sym_ip_prot;  struct ftsym *sym_ip_tcp_port;  struct ftsym *sym_asn;  struct ftsym *sym_tag;  struct ftsym *sym_cur;  int lineno;  char *buf, *fname, *word;  };struct ftfil_lookup_ip_address {  struct ftchash *ftch;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_mask {  FT_STAILQ_HEAD(filipmhead, ftfil_lookup_ip_mask_rec) list;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_mask_rec {  FT_STAILQ_ENTRY(ftfil_lookup_ip_mask_rec) chain;  u_int32 ip, mask;  int mode; /* FT_FIL_MODE_PERMIT/DENY */};struct ftfil_lookup_ip_prefix_rec {  struct radix_node rt_nodes[2]; /* radix tree glue */  struct radix_sockaddr_in addr;  u_int8 masklen;  int mode; /* FT_FIL_MODE_PERMIT/DENY */};struct ftfil_lookup_ip_prefix {  struct radix_node_head *rhead;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_as {  u_int8 mode[65536];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_prot {  u_int8 mode[256];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_port {  u_int8 mode[65536];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_tos {  u_int8 mask;  u_int8 mode[256];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_tcp_flags {  u_int8 mask;  u_int8 mode[256];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_if_index {  u_int8 mode[65536];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_engine {  u_int8 mode[256];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_ip_prefix_len {  u_int8 mode[33];  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_counter_rec {  FT_STAILQ_ENTRY(ftfil_lookup_counter_rec) chain;  u_int32 val;  enum ftfil_op op; /* FT_FIL_OP */  int mode;};struct ftfil_lookup_counter {  FT_STAILQ_HEAD(fillchead, ftfil_lookup_counter_rec) list;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_double_rec {  FT_STAILQ_ENTRY(ftfil_lookup_double_rec) chain;  double val;  enum ftfil_op op; /* FT_FIL_OP */  int mode;};struct ftfil_lookup_double {  FT_STAILQ_HEAD(filldhead, ftfil_lookup_double_rec) list;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_tag {  struct ftchash *ftch;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_tag_mask_rec {  FT_STAILQ_ENTRY(ftfil_lookup_tag_mask_rec) chain;  u_int32 tag, mask;  int mode; /* FT_FIL_MODE_PERMIT/DENY */};struct ftfil_lookup_tag_mask {  FT_STAILQ_HEAD(filtmhead, ftfil_lookup_tag_mask_rec) list;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_time_rec {  FT_STAILQ_ENTRY(ftfil_lookup_time_rec) chain;  int hour, min, sec;  enum ftfil_op op; /* FT_FIL_OP */  int mode;};struct ftfil_lookup_time {  FT_STAILQ_HEAD(filltmehead, ftfil_lookup_time_rec) list;  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_lookup_rate {  int rate;  enum ftfil_mode mode; /* FT_FIL_MODE_PERMIT/DENY */  enum ftfil_mode default_mode; /* FT_FIL_MODE_PERMIT/DENY */  int init; /* initialized? */};struct ftfil_match_item_cache {  FT_SLIST_ENTRY(ftfil_match_item_cache) chain;  u_int32 time; /* cache time -- only valid for flow == curflow+1 */  void *flow; /* address of flow evaluating -- used to invalidate cache */  enum ftfil_mode mode; /* result FT_FIL_MODE_* */  void *lookup; /* data for evaluator */  int (*eval)(void *lookup, void *rec, struct fts3rec_offsets *fo);};static int walk_free(struct radix_node *rn, struct walkarg *UNUSED);static int ftfil_load_lookup(struct line_parser *lp, char *s, int size,  char *list, int mode);static int parse_definition(struct line_parser *lp,  struct ftfil *ftfil);static int parse_definition_match(struct line_parser *lp,  struct ftfil *ftfil);static int parse_definition_or(struct line_parser *lp,  struct ftfil *ftfil);static int parse_definition_invert(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive(struct line_parser *lp, struct ftfil *ftfil);static int parse_primitive_type(struct line_parser *lp, struct ftfil *ftfil);static int parse_primitive_deny(struct line_parser *lp, struct ftfil *ftfil);static int parse_primitive_permit(struct line_parser *lp, struct ftfil *ftfil);static int parse2_primitive_permitdeny(struct line_parser *lp,  struct ftfil *ftfil, int flag);static int parse_primitive_default(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_mask(struct line_parser *lp, struct ftfil *ftfil);static int parse_primitive_type_asn(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_prot(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_port(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_prefix_len(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_if_index(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_tos(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_tcp_flags(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_engine(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_ip_address(struct line_parser *lp,  struct ftfil *ftfil);int parse_primitive_type_ip_mask(struct line_parser *lp,  struct ftfil *ftfil);int parse_primitive_type_ip_prefix(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_tag(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_tag_mask(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_counter(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_time_date(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_time(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_double(struct line_parser *lp,  struct ftfil *ftfil);static int parse_primitive_type_rate(struct line_parser *lp,  struct ftfil *ftfil);inline int eval_match_src_as(struct ftfil_lookup_as *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_dst_as(struct ftfil_lookup_as *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_engine_type(struct ftfil_lookup_engine *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_engine_id(struct ftfil_lookup_engine *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_dst_if_index(struct ftfil_lookup_if_index *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_src_if_index(struct ftfil_lookup_if_index *lookup,  char *rec, struct fts3rec_offsets *fo); inline int eval_match_ip_dst_port(struct ftfil_lookup_ip_port *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_src_port(struct ftfil_lookup_ip_port *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_tcp_flags(struct ftfil_lookup_ip_tcp_flags *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_marked_tos(struct ftfil_lookup_ip_tos *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_tos(struct ftfil_lookup_ip_tos *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_dst_prefix_len(struct ftfil_lookup_ip_prefix_len  *lookup, char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_src_prefix_len(struct ftfil_lookup_ip_prefix_len  *lookup, char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_prot(struct ftfil_lookup_ip_prot *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_flows(struct ftfil_lookup_counter *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_octets(struct ftfil_lookup_counter *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_packets(struct ftfil_lookup_counter *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_xtra_packets(struct ftfil_lookup_counter *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_duration(struct ftfil_lookup_counter *lookup, char *rec,  struct fts3rec_offsets *fo);inline int eval_match_start_time_date(struct ftfil_lookup_counter *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_end_time_date(struct ftfil_lookup_counter *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_start_time(struct ftfil_lookup_time *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_end_time(struct ftfil_lookup_time *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_src_tag_l(struct ftfil_lookup_tag_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_src_tag_h(struct ftfil_lookup_tag *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_dst_tag_l(struct ftfil_lookup_tag_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_dst_tag_h(struct ftfil_lookup_tag *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_sc_addr_l(struct ftfil_lookup_ip_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_sc_addr_h(struct ftfil_lookup_ip_address *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_sc_addr_r(struct ftfil_lookup_ip_prefix *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_nexthop_addr_l(struct ftfil_lookup_ip_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_nexthop_addr_h(struct ftfil_lookup_ip_address *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_nexthop_addr_r(struct ftfil_lookup_ip_prefix *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_src_addr_l(struct ftfil_lookup_ip_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_src_addr_h(struct ftfil_lookup_ip_address *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_src_addr_r(struct ftfil_lookup_ip_prefix *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_dst_addr_l(struct ftfil_lookup_ip_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_dst_addr_h(struct ftfil_lookup_ip_address *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_dst_addr_r(struct ftfil_lookup_ip_prefix *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_exporter_addr_l(struct ftfil_lookup_ip_mask *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_exporter_addr_h(struct ftfil_lookup_ip_address *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_ip_exporter_addr_r(struct ftfil_lookup_ip_prefix *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_pps(struct ftfil_lookup_double *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_bps(struct ftfil_lookup_double *lookup,  char *rec, struct fts3rec_offsets *fo);inline int eval_match_random_sample(struct ftfil_lookup_rate *lookup,  char *rec, struct fts3rec_offsets *fo);static int resolve_primitives(struct ftfil *ftfil);#define NEXT_WORD(A,B)\  for (;;) {\    B = strsep(A, " \t");\    if ((B && *B != 0) || (!B))\      break;\  }\ struct jump {  char *name;  enum ftfil_parse_state state;  int (*func)(struct line_parser *lp, struct ftfil *ftfil);};static struct jump pjump[] = {          {"filter-primitive", 0, parse_primitive},          {"type", PARSE_STATE_PRIMITIVE, parse_primitive_type},          {"permit", PARSE_STATE_PRIMITIVE, parse_primitive_permit},          {"deny", PARSE_STATE_PRIMITIVE, parse_primitive_deny},          {"default", PARSE_STATE_PRIMITIVE, parse_primitive_default},          {"mask", PARSE_STATE_PRIMITIVE, parse_primitive_mask},          {"filter-definition", 0, parse_definition},          {"match", PARSE_STATE_DEFINITION, parse_definition_match},          {"or", PARSE_STATE_DEFINITION, parse_definition_or},          {"invert", PARSE_STATE_DEFINITION, parse_definition_invert},          {0, 0, 0},          };/* * data structures: * * Each primitive is stored in a linked list of struct ftfil_primitive.  The * head is ftfil.primitives.  Each primitive has a lookup entry which  * points to a struct ftfil_lookup_* based on the enum ftfil_primitive_type * stored as type.  Some lookup entries allocate further storage (ie * a hash, radix tree, or linked list for the linear lookups). * * Each definition is stored in a linked list of struct ftfil_def. * The head is ftfil.defs.  Each definition has a list of * ftfil_match matches.  The matches have a list of ftfil_match_items. * For a match to be satisfied each each item in the match must evaluate * true (AND).  For a definition to be satisfied (permitted) one of the * entries in the match list must be satisfied (OR). * * Each primitive (enum ftfil_primitive_type) has an associated * parse_primitive_type_xxx(). * * Each match type (enum ftfil_def_match) has an associated * eval_match_xxx(). * * ftfil_eval() walks the matches and the match items for the definition * passed to it looking for a match.  If every match item in a match * evaluated to permit (enum ftfil_mode) a permit is returned, else * a deny. * * The current evaluator code does not cache results.  For example * * match src-ip-addr test1 * match ip-protocol test2 * or * match src-ip-addr test1 * match ip-port test3 * * If the first two matches fail the result from "match src-ip-addr test1" * will need to be calculated a second time.  In practice this doesn't * seem to be a problem -- the performance impact is minimal for real * world definitions.  Adding a cache would most likely reduce performance * for most cases due to overhead of the cache test/update code. *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -