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

📄 fttag.c

📁 netflow,抓包
💻 C
📖 第 1 页 / 共 3 页
字号:
      return -1;    }  }  return 0;} /* parse_action_type *//* * function: parse_action_match * * process the 'match/set' line.  The match action depends on the type which * must be configured first.  An AS match is added to a table, a next-hop * is added to a hash (chash_*) and a prefix is added to a radix trie. * * returns: 0  ok *          <0 fail */int parse_action_match(struct line_parser *lp, struct fttag *fttag){  struct radix_sockaddr_in sock1, sock2;  struct fttag_as_look *as_look;  struct fttag_next_hop_look *nh_look, nh_look2;  struct fttag_prefix_look *prefix_look;  struct fttag_port_look *port_look;  struct fttag_tos_look *tos_look;  struct fttag_any_look *any_look;  struct ip_prefix ipp;  struct radix_node_head *rhead;  u_int32 tag, hash, ipaddr;  u_int16 as, port;  u_int8 tos;  int sflag, new;  char *c, *match;  if (!lp->cur_action->type) {    fterr_warnx("%s line %d: Must set type first.", lp->fname, lp->lineno);    return -1;  }  bzero(&sock1, sizeof sock1);  bzero(&sock2, sizeof sock2);  sock1.sin_family = AF_INET;  sock1.sin_len = sizeof (struct radix_sockaddr_in);  sock2.sin_family = AF_INET;  sock2.sin_len = sizeof (struct radix_sockaddr_in);  as_look = lp->cur_action->look;  nh_look = lp->cur_action->look;  prefix_look = lp->cur_action->look;  port_look = lp->cur_action->look;  tos_look = lp->cur_action->look;  any_look = lp->cur_action->look;  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting match data.", lp->fname, lp->lineno);    return -1;  }  match = c;  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting [set|or]-[src|dst].", lp->fname, lp->lineno);    return -1;  }  if (!strcasecmp(c, "set-src"))    sflag = FT_TAG_SET_SRC_TAG;  else if (!strcasecmp(c, "set-dst"))    sflag = FT_TAG_SET_DST_TAG;  else if (!strcasecmp(c, "or-src"))    sflag = FT_TAG_OR_SRC_TAG;  else if (!strcasecmp(c, "or-dst"))    sflag = FT_TAG_OR_DST_TAG;  else {    fterr_warnx("%s line %d: Expecting [set|or]-[src|dst].", lp->fname, lp->lineno);    return -1;  }  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting set data.", lp->fname, lp->lineno);    return -1;  }  tag = strtoul(c, (char **)0L, 0);  if (lp->cur_action->type & FT_TAG_TYPE_MATCH_AS) {    as = atoi(match);    if (as_look->set_flags_lookup[as] & sflag) {      fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);      return -1;    }    as_look->set_flags_lookup[as] |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      as_look->src_tag_lookup[as] = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      as_look->src_tag_lookup[as] |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      as_look->dst_tag_lookup[as] = tag;    if (sflag & FT_TAG_OR_DST_TAG)      as_look->dst_tag_lookup[as] |= tag;  } else if (lp->cur_action->type &    (FT_TAG_TYPE_MATCH_TCP_PORT|FT_TAG_TYPE_MATCH_UDP_PORT)) {    port = atoi(match);    if (port_look->set_flags_lookup[port] & sflag) {      fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);      return -1;    }    port_look->set_flags_lookup[port] |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      port_look->src_tag_lookup[port] = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      port_look->src_tag_lookup[port] |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      port_look->dst_tag_lookup[port] = tag;    if (sflag & FT_TAG_OR_DST_TAG)      port_look->dst_tag_lookup[port] |= tag;  } else if (lp->cur_action->type & FT_TAG_TYPE_MATCH_TOS) {    tos = atoi(match);    if (tos_look->set_flags_lookup[tos] & sflag) {      fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);      return -1;    }    tos_look->set_flags_lookup[tos] |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      tos_look->src_tag_lookup[tos] = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      tos_look->src_tag_lookup[tos] |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      tos_look->dst_tag_lookup[tos] = tag;    if (sflag & FT_TAG_OR_DST_TAG)      tos_look->dst_tag_lookup[tos] |= tag;  } else if (lp->cur_action->type & FT_TAG_TYPE_MATCH_ANY) {    if (strcasecmp(match, "any")) {      fterr_warnx("%s line %d: Match must be any.", lp->fname, lp->lineno);      return -1;    }    if (any_look->set_flags & sflag) {      fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);      return -1;    }    any_look->set_flags |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      any_look->src_tag = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      any_look->src_tag |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      any_look->dst_tag = tag;    if (sflag & FT_TAG_OR_DST_TAG)      any_look->dst_tag |= tag;  } else if (lp->cur_action->type & FT_TAG_TYPE_MATCH_PREFIX) {    ipp = scan_ip_prefix(match);    sock1.sin_addr.s_addr = ipp.addr;    sock2.sin_addr.s_addr = (!ipp.len) ? 0 : mask_lookup[ipp.len];    rhead = lp->cur_action->look;    /* try to retrieve from trie */    prefix_look = (struct fttag_prefix_look*)rhead->rnh_lookup(&sock1,    &sock2, rhead);    new = 1;    /* if it exists, make sure not a duplicate set */    if (prefix_look && (prefix_look->addr.sin_addr.s_addr == ipp.addr) &&        (prefix_look->masklen == ipp.len)) {      /* if the set is invalid fail, else update the record and return */      if (prefix_look->set_flags & sflag) {        fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);        return -1;      } else {        new = 0;      }    }    /* allocate a new prefix lookup */    if (new) {      if (!(prefix_look = (struct fttag_prefix_look*)malloc(sizeof        (struct fttag_prefix_look)))) {        fterr_warn("malloc(prefix_look)");        return -1;      }      bzero(prefix_look, sizeof *prefix_look);      prefix_look->rt_nodes->rn_key = (caddr_t)&prefix_look->addr;      prefix_look->addr.sin_addr.s_addr = ipp.addr;      prefix_look->addr.sin_len = sizeof (struct radix_sockaddr_in);      prefix_look->addr.sin_family = AF_INET;      sock1.sin_addr.s_addr = (!ipp.len) ? 0 : mask_lookup[ipp.len];      prefix_look->masklen = ipp.len;      /* add it to the trie */      if (!rhead->rnh_addaddr(&prefix_look->addr, &sock1, rhead,        prefix_look->rt_nodes)) {        free(prefix_look);        fterr_warnx("rnh_addaddr(): failed for %s",match);        return -1;      }    } /* new */    /* finish filling in */    prefix_look->set_flags |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      prefix_look->src_tag = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      prefix_look->src_tag |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      prefix_look->dst_tag = tag;    if (sflag & FT_TAG_OR_DST_TAG)      prefix_look->dst_tag |= tag;  } else if (lp->cur_action->type & FT_TAG_TYPE_MATCH_NEXTHOP) {    ipaddr = scan_ip(match);    hash = (ipaddr>>16) ^ (ipaddr & 0xFFFF);    hash = (hash>>8) ^ (hash & 0xFF);    nh_look = ftchash_lookup(lp->cur_action->look, &ipaddr, hash);    new = 1;    /* if it exists, make sure not a duplicate set */    if (nh_look) {      /* if the set is invalid fail, else update the record and return */      if (nh_look->set_flags & sflag) {        fterr_warnx("%s line %d: Only one match.", lp->fname, lp->lineno);        return -1;      } else {        new = 0;      }    }    if (new) {      bzero(&nh_look2, sizeof nh_look2);      nh_look2.addr = ipaddr;      if (!(nh_look = ftchash_update(lp->cur_action->look, &nh_look2, hash))) {        fterr_warnx("ftch_update(): failed");        return -1;      }    }    /* finish filling in fields */    nh_look->set_flags |= sflag;    if (sflag & FT_TAG_SET_SRC_TAG)      nh_look->src_tag = tag;    if (sflag & FT_TAG_OR_SRC_TAG)      nh_look->src_tag |= tag;    if (sflag & FT_TAG_SET_DST_TAG)      nh_look->dst_tag = tag;    if (sflag & FT_TAG_OR_DST_TAG)      nh_look->dst_tag |= tag;  }  return 0;} /* parse_action_match *//* * function: parse_def * * process the 'definition' line.  Each definition has a unique name which * is added to the fttag->defs linked list.  The current definition is * updated in lp. * * returns: 0  ok *          <0 fail */int parse_def(struct line_parser *lp, struct fttag *fttag){  char *c;  struct fttag_def *ftd;  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting name.", lp->fname, lp->lineno);    return -1;  }  /* check if it exists */  FT_SLIST_FOREACH(ftd, &fttag->defs, chain) {    if (!strcasecmp(c, ftd->name)) {      fterr_warnx("%s line %d: Name (%s) previously defined.", lp->fname,        lp->lineno, c);      return -1;    }  }  /* no, add a new entry to the list */  if (!(ftd = (struct fttag_def*)malloc(sizeof    (struct fttag_def)))) {    fterr_warn("malloc()");    return -1;  }  bzero(ftd, sizeof *ftd);  FT_STAILQ_INIT(&ftd->terms);  if (!(ftd->name = (char*)malloc(strlen(c)+1))) {    fterr_warn("malloc()");    free(ftd);    return -1;  }  strcpy(ftd->name, c);  FT_SLIST_INSERT_HEAD(&fttag->defs, ftd, chain);  lp->state = PARSE_STATE_DEFINITION;  lp->cur_def = ftd;  return 0;} /* parse_def *//* * function: parse_def_term * * process the term line.  Each definition has a list of terms, the * terms have a common input, output, and exporter IP filter and * may have one or more actions.  Without an action a term has * no purpose. * * returns: 0  ok *          <0 fail */int parse_def_term(struct line_parser *lp, struct fttag *fttag){  struct fttag_def_term *ftdt;  if (!lp->cur_def) {    fterr_warnx("%s line %d: Must set name first.", lp->fname, lp->lineno);    return -1;  }  /* no, add a new term entry to this definition */  if (!(ftdt = (struct fttag_def_term*)malloc(sizeof *ftdt))) {    fterr_warn("malloc()");    return -1;  }  bzero(ftdt, sizeof *ftdt);  FT_STAILQ_INIT(&ftdt->actions);  FT_STAILQ_INSERT_TAIL(&lp->cur_def->terms, ftdt, chain);  lp->cur_def_term = ftdt;  return 0;} /* parse_def_term *//* * function: parse_def_exporter * * process the 'exporter' line. * * returns: 0  ok *          <0 fail */int parse_def_exporter(struct line_parser *lp, struct fttag *fttag){  char *c;  if (!lp->cur_def_term) {    fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);    return -1;  }  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting exporter.", lp->fname, lp->lineno);    return -1;  }  if (lp->cur_def_term->flags & FT_TAG_DEF_FILTER_EXPORTER) {    fterr_warnx("%s line %d: Exporter previously defined.", lp->fname,    lp->lineno);    return -1;  }  lp->cur_def_term->exporter_ip = scan_ip(c);  lp->cur_def_term->flags |= FT_TAG_DEF_FILTER_EXPORTER;  return 0;} /* parse_def_exporter *//* * function: parse_def_input_filter * * process the 'input-filter' line. * * returns: 0  ok *          <0 fail */int parse_def_input_filter(struct line_parser *lp, struct fttag *fttag){  char *c;  if (!lp->cur_def_term) {    fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);    return -1;  }  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting filter list.", lp->fname, lp->lineno);    return -1;  }  if (lp->cur_def_term->flags & FT_TAG_DEF_FILTER_INPUT) {    fterr_warnx("%s line %d: Input filter previously defined.", lp->fname,    lp->lineno);    return -1;  }  if (load_lookup(c, 65536, lp->cur_def_term->in_tbl)) {    fterr_warnx("load_lookup(): failed");    return -1;  }  lp->cur_def_term->flags |= FT_TAG_DEF_FILTER_INPUT;  return 0;} /* parse_def_input_filter *//* * function: parse_def_output_filter * * process the 'output-filter' line. * * returns: 0  ok *          <0 fail */int parse_def_output_filter(struct line_parser *lp, struct fttag *fttag){  char *c;  if (!lp->cur_def_term) {    fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);    return -1;  }  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting filter list.", lp->fname, lp->lineno);    return -1;  }  if (lp->cur_def_term->flags & FT_TAG_DEF_FILTER_OUTPUT) {    fterr_warnx("%s line %d: Output filter previously defined.", lp->fname,    lp->lineno);    return -1;  }  if (load_lookup(c, 65536, lp->cur_def_term->out_tbl)) {    fterr_warnx("load_lookup(): failed");    return -1;  }  lp->cur_def_term->flags |= FT_TAG_DEF_FILTER_OUTPUT;  return 0;} /* parse_def_output_filter *//* * function: parse_def_action * * foreach action listed, add it to a linked list of actions for the * definition.  Note resolve_actions() must be called before the actions * are valid. * * returns: 0  ok *          <0 fail */int parse_def_action(struct line_parser *lp, struct fttag *fttag){  struct fttag_def_term_actions *ftdta;  char *c;  if (!lp->cur_def_term) {    fterr_warnx("%s line %d: Must start term.", lp->fname, lp->lineno);    return -1;  }  NEXT_WORD(&lp->buf, c);  if (!c) {    fterr_warnx("%s line %d: Expecting action.", lp->fname, lp->lineno);    return -1;  }

⌨️ 快捷键说明

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