📄 ftfil.c
字号:
/* * function: eval_match_ip_dst_addr_r * * Evalute ip_dst_addr as hash * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_ip_dst_addr_r(struct ftfil_lookup_ip_prefix *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftfil_lookup_ip_prefix_rec *ftflipprr; struct radix_node_head *rhead; struct radix_sockaddr_in sock1; int match; sock1.sin_addr.s_addr = *((u_int32*)(rec+fo->dstaddr)); sock1.sin_len = sizeof sock1; sock1.sin_family = AF_INET; match = 0; rhead = lookup->rhead; if ((ftflipprr = (struct ftfil_lookup_ip_prefix_rec*)rhead->rnh_matchaddr( &sock1, rhead))) match = 1; /* if there was a match, then return that mode */ if (match) return ftflipprr->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_ip_dst_addr_r *//* * function: eval_match_ip_exporter_addr_l * * Evalute ip_exporter_addr as list * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_ip_exporter_addr_l(struct ftfil_lookup_ip_mask *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftfil_lookup_ip_mask_rec *ftflipmr; u_int32 *ip_exporter_addr; int match; ip_exporter_addr = ((u_int32*)(rec+fo->exaddr)); match = 0; FT_STAILQ_FOREACH(ftflipmr, &lookup->list, chain) { /* match? */ if ((*ip_exporter_addr & ftflipmr->mask) == ftflipmr->ip) { match = 1; break; } } /* ftflipmr */ /* if there was a match, then return that mode */ if (match) return ftflipmr->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_ip_exporter_addr_l *//* * function: eval_match_ip_exporter_addr_h * * Evalute ip_exporter_addr as hash * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_ip_exporter_addr_h(struct ftfil_lookup_ip_address *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftchash_rec_fil_c32 *ftch_recfc32p; u_int32 *ip_exporter_addr, hash; int match; ip_exporter_addr = ((u_int32*)(rec+fo->exaddr)); match = 0; hash = (*ip_exporter_addr>>16) ^ (*ip_exporter_addr & 0xFFFF); hash = ((hash >>8) ^ (hash & 0x0FFF)); if ((ftch_recfc32p = ftchash_lookup(lookup->ftch, ip_exporter_addr, hash))) match = 1; /* if there was a match, then return that mode */ if (match) return ftch_recfc32p->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_ip_exporter_addr_h *//* * function: eval_match_ip_exporter_addr_r * * Evalute ip_exporter_addr as hash * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_ip_exporter_addr_r(struct ftfil_lookup_ip_prefix *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftfil_lookup_ip_prefix_rec *ftflipprr; struct radix_node_head *rhead; struct radix_sockaddr_in sock1; int match; sock1.sin_addr.s_addr = *((u_int32*)(rec+fo->exaddr)); sock1.sin_len = sizeof sock1; sock1.sin_family = AF_INET; match = 0; rhead = lookup->rhead; if ((ftflipprr = (struct ftfil_lookup_ip_prefix_rec*)rhead->rnh_matchaddr( &sock1, rhead))) match = 1; /* if there was a match, then return that mode */ if (match) return ftflipprr->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_ip_exporter_addr_r *//* * function: eval_match_bps * * Evalute Bits Per Second * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_bps(struct ftfil_lookup_double *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftfil_lookup_double_rec *ftfldr; double bps; u_int32 dOctets, Last, First, duration; int t, match; dOctets = *((u_int32*)(rec+fo->dOctets)); Last = *((u_int32*)(rec+fo->Last)); First = *((u_int32*)(rec+fo->First)); duration = Last - First; if (duration) bps = (double)dOctets*8 / ((double)duration / 1000.0); else bps = 0; match = 0; FT_STAILQ_FOREACH(ftfldr, &lookup->list, chain) { switch (ftfldr->op) { case FT_FIL_OP_LT: t = (bps < ftfldr->val); break; case FT_FIL_OP_GT: t = (bps > ftfldr->val); break; case FT_FIL_OP_EQ: t = (bps == ftfldr->val); break; case FT_FIL_OP_NE: t = (bps != ftfldr->val); break; case FT_FIL_OP_GE: t = (bps >= ftfldr->val); break; case FT_FIL_OP_LE: t = (bps <= ftfldr->val); break; default: fterr_warnx("eval_match_flows: internal error"); return -1; break; } /* switch */ /* did this line match? */ if (t) { match = 1; break; } } /* ftflcr */ /* if there was a match, then return that mode */ if (match) return ftfldr->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_bps *//* * function: eval_match_pps * * Evalute Packets Per Second * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_pps(struct ftfil_lookup_double *lookup, char *rec, struct fts3rec_offsets *fo){ struct ftfil_lookup_double_rec *ftfldr; double pps; u_int32 dPkts, Last, First, duration; int t, match; dPkts = *((u_int32*)(rec+fo->dPkts)); Last = *((u_int32*)(rec+fo->Last)); First = *((u_int32*)(rec+fo->First)); duration = Last - First; if (duration) pps = (double)dPkts / ((double)duration / 1000.0); else pps = 0; match = 0; FT_STAILQ_FOREACH(ftfldr, &lookup->list, chain) { switch (ftfldr->op) { case FT_FIL_OP_LT: t = (pps < ftfldr->val); break; case FT_FIL_OP_GT: t = (pps > ftfldr->val); break; case FT_FIL_OP_EQ: t = (pps == ftfldr->val); break; case FT_FIL_OP_NE: t = (pps != ftfldr->val); break; case FT_FIL_OP_GE: t = (pps >= ftfldr->val); break; case FT_FIL_OP_LE: t = (pps <= ftfldr->val); break; default: fterr_warnx("eval_match_flows: internal error"); return -1; break; } /* switch */ /* did this line match? */ if (t) { match = 1; break; } } /* ftflcr */ /* if there was a match, then return that mode */ if (match) return ftfldr->mode; /* else return the default */ return lookup->default_mode;} /* eval_match_pps *//* * function: eval_match_random_sample * * Evalute random_sample * * returns: FT_FIL_MODE_PERMIT * FT_FIL_MODE_DENY */inline int eval_match_random_sample(struct ftfil_lookup_rate *lookup, char *rec, struct fts3rec_offsets *fo){ int val; /* val is a random number from 0..lookup->rate-1 */ val = rand() % lookup->rate; /* pick 0 as the "pass" value -- could have picked any number in the range */ if (!val) return (lookup->mode == FT_FIL_MODE_PERMIT) ? FT_FIL_MODE_PERMIT : FT_FIL_MODE_DENY; else return (lookup->mode == FT_FIL_MODE_PERMIT) ? FT_FIL_MODE_DENY : FT_FIL_MODE_PERMIT;} /* eval_match_random_sample *//* ************************************************************************* public ftfil_* ************************************************************************* *//* * function: ftfil_load * * Process fname into ftfil. * * returns: 0 ok * <0 fail */int ftfil_load(struct ftfil *ftfil, char *fname){ struct stat sb; struct jump *jmp; struct line_parser lp; int fd, ret, found; char *buf, *buf2, *c; ret = -1; buf = (char*)0L; bzero(&lp, sizeof lp); bzero(ftfil, sizeof *ftfil); FT_SLIST_INIT(&ftfil->defs); FT_SLIST_INIT(&ftfil->primitives); lp.sym_ip_prot = ftsym_new(FT_PATH_SYM_IP_PROT); lp.sym_ip_tcp_port = ftsym_new(FT_PATH_SYM_TCP_PORT); lp.sym_asn = ftsym_new(FT_PATH_SYM_ASN); lp.sym_tag = ftsym_new(FT_PATH_SYM_TAG); lp.fname = fname; if ((fd = open(fname, O_RDONLY, 0)) < 0) { fterr_warn("open(%s)", fname); goto load_fil_out; } if (fstat(fd, &sb) < 0) { fterr_warn("stat(%s)", fname); goto load_fil_out; } /* allocate storage for file */ if (!(buf = malloc(sb.st_size+1))) { fterr_warn("malloc()"); goto load_fil_out; } /* read in file */ if (read(fd, buf, sb.st_size) != sb.st_size) { fterr_warnx("read(%s): short", fname); goto load_fil_out; } /* null terminate file */ buf[sb.st_size] = 0; buf2 = buf; for (;;) { /* rip a line */ for (;;) { c = strsep(&buf2, "\n"); ++lp.lineno; if ((c && *c != 0) || (!c)) break; } /* no more lines */ if (!c) { goto load_fil_done; } lp.buf = c; /* first word */ NEXT_WORD(&lp.buf, c); /* whitespace only line */ if (!c) { continue; } /* comment line */ if (c && *c == '#') continue; for (jmp = pjump; jmp->name; ++jmp) { found = 0; if (((!jmp->state) || (jmp->state & lp.state)) && (!strcasecmp(c, jmp->name))) { found = 1; if (jmp->func(&lp, ftfil)) goto load_fil_out; NEXT_WORD(&lp.buf, c); if (c) { fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c); goto load_fil_out;; } break; } } /* test each word */ if (!found) { fterr_warnx("%s line %d: Unexpected \"%s\".", lp.fname, lp.lineno, c); goto load_fil_out; } } /* more lines */load_fil_done: if (resolve_primitives(ftfil)) { fterr_warnx("resolve_primitives(): failed"); goto load_fil_out; } ret = 0;load_fil_out: if (fd != -1) close(fd); if (buf) free(buf); if (ret == -1) ftfil_free(ftfil); if (lp.sym_ip_prot) ftsym_free(lp.sym_ip_prot); if (lp.sym_ip_tcp_port) ftsym_free(lp.sym_ip_tcp_port); if (lp.sym_asn) ftsym_free(lp.sym_asn); if (lp.sym_tag) ftsym_free(lp.sym_tag); return ret;} /* ftfil_load */void ftfil_free(struct ftfil *ftfil){ struct ftfil_primitive *ftfp; struct ftfil_lookup_ip_address *ftflipa; struct ftfil_lookup_ip_prefix *ftflippr; struct ftfil_lookup_ip_mask *ftflipm; struct ftfil_lookup_counter *ftflc; struct ftfil_lookup_counter_rec *ftflcr; struct ftfil_lookup_tag *ftflt; struct ftfil_lookup_tag_mask *ftfltm; struct ftfil_lookup_tag_mask_rec *ftfltmr; struct ftfil_lookup_ip_mask_rec *ftflipmr; struct ftfil_def *ftfd; struct ftfil_match *ftm; struct ftfil_match_item *ftmi; struct ftfil_lookup_time *ftfltme; struct ftfil_lookup_time_rec *ftfltmer; struct ftfil_lookup_double *ftfld; struct ftfil_lookup_double_rec *ftfldr; /* * walk the primitive list, free each entry */ while (!FT_SLIST_EMPTY(&ftfil->primitives)) { ftfp = FT_SLIST_FIRST(&ftfil->primitives); switch (ftfp->type) { case FT_FIL_PRIMITIVE_TYPE_IP_PREFIX: ftflippr = ftfp->lookup; if (ftflippr->init) { rhead = ftflippr->rhead; rhead->rnh_walktree(rhead, walk_free, 0); } break; case FT_FIL_PRIMITIVE_TYPE_IP_ADDRESS: ftflipa = ftfp->lookup; if (ftflipa->init) ftchash_free(ftflipa->ftch); break; case FT_FIL_PRIMITIVE_TYPE_IP_MASK: ftflipm = ftfp->lookup; while (!FT_STAILQ_EMPTY(&ftflipm->list)) { ftflipmr = FT_STAILQ_FIRST(&ftflipm->list); FT_STAILQ_REMOVE_HEAD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -