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

📄 classifiernetfilter.cc

📁 网络流量采集及分析软件
💻 CC
📖 第 1 页 / 共 4 页
字号:
void ClassifierNetfilter::_addRule( RuleInfo &rinfo, int test ){    int  rule_id, nAttributes, i, argc = 0;    char **attributes, **params, *param;    struct ipt_entry fw, *e = NULL;    int invert = 0;    unsigned int nsaddrs = 0, ndaddrs = 0;    struct in_addr *saddrs = NULL, *daddrs = NULL;    int c, valid;    const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;    unsigned int options = 0;    int ret = 1;    struct iptables_match *m = NULL;    struct iptables_target *target = NULL;    const char *jumpto = "";    char *protocol = NULL;    char **argv;    struct netfilter_rule_entry *nfre;#ifdef LOOPFULL    maxid++;    return;#endif       // extract filter rule information from RuleInfo object    rule_id = rinfo.getId();    //    MLOG( "ClassifierNetfilter : adding Rule #%d", rule_id );    attributes = rinfo.getFilter()->getNames( &nAttributes);    params = rinfo.getFilter()->getValues( &nAttributes );    if (rule_id<0 || nAttributes<0 || attributes == NULL || params == NULL )	throw MyErr( "invalid filter rule description" );	#ifdef CLASS_DEBUG    cout << *(rinfo.getFilter()) << "\n"; // dump filter spec#endif    // emulate getopt    // allocate some space for optarg, argv    //if (optarg) //seems to be dangerous assumption    //  free(optarg);    optarg = new char[256];    argv = new char*[nAttributes*2];    optind = 1;    for (i = 0; i<nAttributes; i++) {	invert = check_for_invert(params[i], &param);	if (invert) {	    argv[argc] = new char[strlen(inv_symbol)+1];	    strcpy(argv[argc++], inv_symbol);	}	if (param != NULL) {	    argv[argc] = new char[strlen(param)+1];	    strcpy(argv[argc++], param);	}    }    /* Suppress error messages: we may add new options if we       demand-load a protocol. */    opterr = 0;    // initialize data structures    memset(&fw, 0, sizeof(fw));    shostnetworkmask = "0.0.0.0/0"; 	    dhostnetworkmask = "0.0.0.0/0";    // reset used flag for matches, used = 1 means used by current rule    for (m = iptables_matches; m; m = m->next) {	m->used = 0;    }    // target is _always_ ULOG ->load it    jumpto = parse_target(def_targetname);    if ((target = find_target(jumpto, DONT_LOAD))) {	// initialize data and flags	target->tflags = 0;	memset(target->t->data, 0, target->size);	target->init(target->t, &fw.nfcache);	target->used = 1;    } else {	if ((target = find_target(jumpto, LOAD_MUST_SUCCEED))) {	    size_t size;#ifdef CLASS_DEBUG	    fprintf(stderr, "%s loaded\n", jumpto);#endif	  	    size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + target->size;	    target->t = (struct ipt_entry_target *) fw_calloc(1, size);	    target->t->u.target_size = size;	    strcpy(target->t->u.user.name, jumpto);	    // call init function	    target->init(target->t, &fw.nfcache);	    target->used = 1;	}	else	    throw MyErr("cant load %s target", def_targetname);    }	  #ifdef CLASS_DEBUG    fprintf(stderr, "rule target initialized\n");#endif    // configure target, set nlgroup    c = translate_option((char *)param_names[defp_nlgroup], target->option_offset);    if (c<0)	throw MyErr("Unknown arg `%s'", param_names[defp_nlgroup]);    sprintf(optarg, "%d", nlgroup);#ifdef CLASS_DEBUG    fprintf(stderr, "nlgroup option resolved to %d, arg is %s\n", c, optarg);#endif    if (!(target->parse(c - target->option_offset, argv, invert,			&target->tflags, &fw, &target->t))) {	throw MyErr("Unknown arg `%s'", param_names[defp_nlgroup]);    }    // set rule id    c = translate_option((char *)param_names[defp_prefix], target->option_offset);    if (c<0)	throw MyErr("Unknown arg `%s'", param_names[defp_prefix]);    sprintf(optarg, "%d", rule_id);#ifdef CLASS_DEBUG    fprintf(stderr, "prefix option resolved to %d, arg is %s\n", c, optarg);#endif    if (!(target->parse(c - target->option_offset, argv, invert,			&target->tflags, &fw, &target->t))) {	throw MyErr("Unknown arg `%s'", param_names[defp_prefix]);    }    // default cprange    c = translate_option((char *)param_names[defp_cprange], target->option_offset);    if (c<0)	throw MyErr("Unknown arg `%s'", param_names[defp_cprange]);    sprintf(optarg, "%d", cprange);#ifdef CLASS_DEBUG    fprintf(stderr, "cprange option resolved to %d, arg is %s\n", c, optarg);#endif    if (!(target->parse(c - target->option_offset, argv, invert,			&target->tflags, &fw, &target->t))) {	throw MyErr("Unknown arg `%s'", param_names[defp_cprange]);    }    // default qthreshold    c = translate_option((char *)param_names[defp_qthreshold], target->option_offset);    if (c<0)	throw MyErr("Unknown arg `%s'", param_names[defp_qthreshold]);    sprintf(optarg, "%d", qthres);#ifdef CLASS_DEBUG    fprintf(stderr, "qthreshold option resolved to %d, arg is %s\n", c, optarg);#endif    if (!(target->parse(c - target->option_offset, argv, invert,			&target->tflags, &fw, &target->t))) {	throw MyErr("Unknown arg `%s'", param_names[defp_qthreshold]);    }    // reset target (ulog) flags to allow cprange and qthreshold config by    // rule    target->tflags = 0;    // check the given attributes + parse and check the parameter values    for (i = 0; i<nAttributes; i++ ) {	invert = check_for_invert(params[i], &param);	if (invert)	    optind++;	if (!strcmp( attributes[i], "nofilter" ) ) {	    // ignore 'nofilter'	}	else if (!strcmp( attributes[i], param_names[defp_bidir] ) ) {	    // ignore at this point	}	else if (!strcmp( attributes[i], param_names[defp_srcipmask] ) ) {	    set_inverse(defp_srcipmask, &fw.ip.invflags, invert);	    shostnetworkmask = param;	    fw.nfcache | = NFC_IP_DST;	}	else if (!strcmp( attributes[i], param_names[defp_dstipmask] ) ) {	    set_inverse(defp_dstipmask, &fw.ip.invflags, invert);	    dhostnetworkmask = param;	    fw.nfcache | = NFC_IP_DST;	}	else if (!strcmp( attributes[i], param_names[defp_iniface] ) ) {	    set_inverse(defp_iniface, &fw.ip.invflags, invert);	    parse_interface(param, fw.ip.iniface, fw.ip.iniface_mask);	    fw.nfcache | = NFC_IP_IF_IN;	}	else if (!strcmp( attributes[i], param_names[defp_outiface] ) ) {	    set_inverse(defp_outiface, &fw.ip.invflags, invert);	    parse_interface(param, fw.ip.outiface, fw.ip.outiface_mask);	    fw.nfcache | = NFC_IP_IF_OUT;	}	else if (!strcmp( attributes[i], param_names[defp_match] ) ) {	    size_t size;	    if (invert)		exit_error(PARAMETER_PROBLEM, "unexpected !flag before %s", 			   param_names[defp_match]);	    if ((m = find_match(param, DONT_LOAD))) {		// initialize data and flags		m->mflags = 0;		memset(m->m->data, 0, m->size);		m->init(m->m, &fw.nfcache);		m->used = 1;	    } else {		if ((m = find_match(param, LOAD_MUST_SUCCEED))) {		    size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;		    m->m = (struct ipt_entry_match *) fw_calloc(1, size);		    m->m->u.match_size = size;		    strcpy(m->m->u.user.name, m->name);		    // call init function		    m->init(m->m, &fw.nfcache);		    m->used = 1;		}	    }	}	else if (!strcmp( attributes[i], param_names[defp_prot] ) ) {	    set_inverse(defp_prot, &fw.ip.invflags, invert);	    /* Canonicalize into lower case */	    for (protocol = param; *protocol; protocol++)		*protocol = tolower(*protocol);			    protocol = param;	    fw.ip.proto = parse_protocol(protocol);	    if ((fw.ip.proto == 0) && (fw.ip.invflags & IPT_INV_PROTO))		exit_error(PARAMETER_PROBLEM, "rule would never match protocol");	    fw.nfcache | = NFC_IP_PROTO;	}	else {	    // must be a module specific option or ULOG option	     	    // set matches according to protocol	    if (m == NULL && protocol) {		if ((m = find_proto(protocol, DONT_LOAD, options & 0x01))) {		    // initialize data and flags		    m->mflags = 0;		    memset(m->m->data, 0, m->size);		    m->init(m->m, &fw.nfcache);		    m->used = 1;		} else {		    if ((m = find_proto(protocol, TRY_LOAD, options & 0x01))) {			size_t size;#ifdef CLASS_DEBUG			fprintf(stderr, "loading %s module\n", protocol);#endif						size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size;			m->m = (struct ipt_entry_match *) fw_calloc(1, size);			m->m->u.match_size = size;			strcpy(m->m->u.user.name, m->name);			m->init(m->m, &fw.nfcache);			m->used = 1;		    } else {			exit_error(PARAMETER_PROBLEM, "Error loading %s module", 				   protocol);		    }		}	  	    }	    valid = 0;#ifdef CLASS_DEBUG 	    fprintf(stderr, "Parsing %s option\n", attributes[i]);#endif	    for (m = iptables_matches; m; m = m->next) {		if (m->used) {		    c = translate_option(attributes[i], m->option_offset);		    if (c > 0) {			strcpy(optarg, param);    			// if protocol is inverse options for this protocol makes no sense			if (fw.ip.invflags & IPT_INV_PROTO) {			    exit_error(PARAMETER_PROBLEM, 				       "Option specified for negative protocol match '%s'",				       protocol);			}							if (m->parse(c - m->option_offset,				     argv, invert, &m->mflags, &fw, &fw.nfcache, &m->m)) {				  			    valid = 1;			    break;			}		    }		}	    }		  	    // following target parameters: qthreshold, cprange	    if (!valid) {		c = translate_option(attributes[i], target->option_offset);		if (c > 0) {		    strcpy(optarg, param);		    if (target->parse(c - target->option_offset, argv, invert,				      &target->tflags, &fw, &target->t)) {			valid = 1;		    }		}	    }		  	    if (!valid)		exit_error(PARAMETER_PROBLEM, "Unknown arg `%s'", attributes[i]);	}	  	optind++;    }    // final check for all modules used    for (m = iptables_matches; m; m = m->next) {	if (m->used) {	    m->final_check(m->mflags);	}    }    if (target)	target->final_check(target->tflags);    // parse source and destination address+mask    if (shostnetworkmask)	parse_hostnetworkmask(shostnetworkmask, &saddrs,			      &(fw.ip.smsk), &nsaddrs);    if (dhostnetworkmask)	parse_hostnetworkmask(dhostnetworkmask, &daddrs,			      &(fw.ip.dmsk), &ndaddrs);#ifdef CLASS_DEBUG    fprintf(stderr, "all parameters parsed\n");#endif    // FIXME: dont support this right now    /* if ((nsaddrs > 1 || ndaddrs > 1) &&       (fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))       exit_error(PARAMETER_PROBLEM, "!not allowed with multiple"       " source or destination IP addresses"); */    // check for valid interface specs according to target chain    if (strcmp(chain, "PREROUTING") == 0 || strcmp(chain, "INPUT") == 0 ||	strcmp(chain, "PROMISCUOUS") ) {	if (fw.nfcache & NFC_IP_IF_OUT)	    exit_error(PARAMETER_PROBLEM, "Can't use %s with %s\n",		       param_names[defp_outiface], chain);    }    if (strcmp(chain, "POSTROUTING") == 0 || strcmp(chain, "OUTPUT") == 0 ||	strcmp(chain, "PROMISCUOUS") ) {	if (fw.nfcache & NFC_IP_IF_IN)	    exit_error(PARAMETER_PROBLEM, "Can't use %s with %s\n",		       param_names[defp_iniface], chain);    }	    // do generate because we know that we have a target    e = generate_entry(&fw, iptables_matches, target->t);#ifdef CLASS_DEBUG    fprintf(stderr, "new entry generated\n");#endif    nfre = alloc_rule_entry(e, nsaddrs, saddrs, ndaddrs, daddrs);#ifdef CLASS_DEBUG    fprintf(stderr, "new rule entry allocated\n");#endif    // install NetFilter rule    ret = append_entry(chain, e, nsaddrs, saddrs, ndaddrs, daddrs,		       options, iptc_h);    if (!ret) {	delete_rule_entry(nfre);	exit_error(PARAMETER_PROBLEM, "%s\n", iptc_strerror(errno));    }    ret = iptc_commit(iptc_h);    // respawn handle, thanx rusty    *iptc_h = iptc_init(table);    if (!ret) {	delete_rule_entry(nfre);	exit_error(PARAMETER_PROBLEM, "%s\n", iptc_strerror(errno));    }    // if success ->add filter rule to internal rule list    rule_list.insert(make_pair(rule_id, nfre));    stats.rules++;    // if in test mode immediatly delete the rule    // FIXME: maybe escape earlier because of performance    if (test) {	this->delRule(rule_id);    }	    saveDelete(optarg;    for (i = 0; i<argc; i++) {	saveDelete(argv[i];    }    saveDelete(argv;}/* ------------------------- delRule ------------------------- */void ClassifierNetfilter::delRule( int ruleID ){    int ret = 1;    unsigned int options = 0;    struct netfilter_rule_entry *nfre;    rule_map_itor_t itor;    MLOG( "ClassifierNetfilter : removing Rule #%d", ruleID );    // get rule ipt_entry#ifdef CLASS_DEBUG    fprintf(stderr, "delete rule %d\n", ruleID);#endif#ifdef LOOPFULL    maxid--;    return;#endif    // delete all rules with that ruleID    // there could be 1 rule in case of unidir match or    // 2 rules in case of bidir match    while ((itor = rule_list.find(ruleID)) != rule_list.end()) {	nfre = itor->second;#ifdef CLASS_DEBUG	fprintf(stderr, "rule %d found\n", ruleID);#endif		// delete NetFilter rule	ret = delete_entry(chain, nfre->e, nfre->nsaddrs, &nfre->saddrs,			   nfre->ndaddrs, &nfre->daddrs, options, iptc_h);	  	if (!ret)	    exit_error(PARAMETER_PROBLEM, "%s\n", iptc_strerror(errno));	ret = iptc_commit(iptc_h);	// respawn handle, thanx rusty	*iptc_h = iptc_init(table);	if (!ret)	    exit_error(PARAMETER_PROBLEM, "%s\n", iptc_strerror(errno));	#ifdef CLASS_DEBUG	fprintf(stderr, "rule deleted from netfilter\n");#endif	// delete entry from internal rule_list	delete_rule_entry(nfre);	rule_list.erase(itor);	stats.rules--;#ifdef CLASS_DEBUG	fprintf(stderr, "rule deleted from internal list\n");#endif    }}/* ------------------------- getStats ------------------------- */ClassifierStats *ClassifierNetfilter::getStats(){    // adjust values    return &stats;}/* ------------------------- dump ------------------------- */void ClassifierNetfilter::dump( ostream &os ){    os << "Classifier dump : packets " << stats.packets << endl;    os << "                  bytes " << stats.bytes << endl;    os << "                  rules " << stats.rules << endl;    // write classifier information to os stream}/* ------------------------- operator<< ------------------------- */ostream& operator<< ( ostream &os, ClassifierNetfilter &cl ){    cl.dump(os);    return os;}

⌨️ 快捷键说明

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