📄 classifiernetfilter.cc
字号:
iface[1] = '\0'; } else iface[0] = '\0'; if (fw->ip.outiface[0] != '\0') { strcat(iface, fw->ip.outiface); /* If it doesn't compare the nul-term, it's a wildcard. */ if (fw->ip.outiface_mask[strlen(fw->ip.outiface)] == 0) strcat(iface, "+"); } else if (format & FMT_NUMERIC) strcat(iface, "*"); else strcat(iface, "any"); printf(FMT("%-6s ","out %s "), iface); } fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout); if (fw->ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC)) printf(FMT("%-19s ","%s "), "anywhere"); else { if (format & FMT_NUMERIC) sprintf(buf, "%s", addr_to_dotted(&(fw->ip.src))); else sprintf(buf, "%s", addr_to_anyname(&(fw->ip.src))); strcat(buf, mask_to_dotted(&(fw->ip.smsk))); printf(FMT("%-19s ","%s "), buf); } fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout); if (fw->ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC)) printf(FMT("%-19s","->%s"), "anywhere"); else { if (format & FMT_NUMERIC) sprintf(buf, "%s", addr_to_dotted(&(fw->ip.dst))); else sprintf(buf, "%s", addr_to_anyname(&(fw->ip.dst))); strcat(buf, mask_to_dotted(&(fw->ip.dmsk))); printf(FMT("%-19s","->%s"), buf); } if (format & FMT_NOTABLE) fputs(" ", stdout); IPT_MATCH_ITERATE(fw, print_match, &fw->ip, format & FMT_NUMERIC); if (target) { if (target->print) /* Print the target information. */ target->print(&fw->ip, t, format & FMT_NUMERIC); } else if (t->u.target_size != sizeof(*t)) printf("[%u bytes of unknown target data] ", t->u.target_size - sizeof(*t)); if (!(format & FMT_NONEWLINE)) fputc('\n', stdout);}/*static*/ void print_firewall_line(const struct ipt_entry *fw, const iptc_handle_t h){ struct ipt_entry_target *t; t = ipt_get_target((struct ipt_entry *)fw); print_firewall(fw, t->u.user.name, 0, FMT_PRINT_RULE, h);}#endif/*static*/ unsigned char *make_delete_mask(struct ipt_entry *fw){ /* Establish mask for comparison */ unsigned int size; struct iptables_match *m; unsigned char *mask, *mptr; size = sizeof(struct ipt_entry); for (m = iptables_matches; m; m = m->next) { if (m->used) { size += IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size; } } mask = (unsigned char *) fw_calloc(1, size + IPT_ALIGN(sizeof(struct ipt_entry_target)) + iptables_targets->size); memset(mask, 0xFF, sizeof(struct ipt_entry)); mptr = mask + sizeof(struct ipt_entry); for (m = iptables_matches; m; m = m->next) { if (m->used) { memset(mptr, 0xFF, IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->userspacesize); mptr += IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size; } } memset(mptr, 0xFF, IPT_ALIGN(sizeof(struct ipt_entry_target)) + iptables_targets->userspacesize); return mask;}/*static*/ void set_inverse(unsigned int param, u_int8_t *invflg, int invert){ if (invert) { if (!inverse_for_params[param]) exit_error(PARAMETER_PROBLEM, "cannot have !before %s", param_names[param]); *invflg | = inverse_for_params[param]; }}/* ------------------------- libiptc wrappers ---------------------------- */static int append_entry(const ipt_chainlabel chain, struct ipt_entry *fw, unsigned int nsaddrs, const struct in_addr saddrs[], unsigned int ndaddrs,const struct in_addr daddrs[], int verbose, iptc_handle_t *handle){ unsigned int i, j; int ret = 1; for (i = 0; i < nsaddrs; i++) { fw->ip.src.s_addr = saddrs[i].s_addr; for (j = 0; j < ndaddrs; j++) { fw->ip.dst.s_addr = daddrs[j].s_addr;#ifdef CLASS_DEBUG fprintf(stdout, "append: "); print_firewall_line(fw, *handle);#endif ret & = iptc_append_entry(chain, fw, handle); } } return ret;}static int delete_entry(const ipt_chainlabel chain, struct ipt_entry *fw, unsigned int nsaddrs, const struct in_addr saddrs[], unsigned int ndaddrs, const struct in_addr daddrs[], int verbose, iptc_handle_t *handle){ unsigned int i, j; int ret = 1; unsigned char *mask; mask = (unsigned char *) make_delete_mask(fw); for (i = 0; i < nsaddrs; i++) { fw->ip.src.s_addr = saddrs[i].s_addr; for (j = 0; j < ndaddrs; j++) { fw->ip.dst.s_addr = daddrs[j].s_addr;#ifdef CLASS_DEBUG fprintf(stdout, "delete: "); print_firewall_line(fw, *handle);#endif ret & = iptc_delete_entry(chain, fw, mask, handle); } } return ret;}int flush_entries(const ipt_chainlabel chain, int verbose, iptc_handle_t *handle){ #ifdef CLASS_DEBUG fprintf(stdout, "Flushing chain `%s'\n", chain);#endif return iptc_flush_entries(chain, handle);}/* ------------------------- ClassifierNetfilter ------------------------- */ClassifierNetfilter::ClassifierNetfilter(ConfigManager *cnf, int threaded ) : Classifier(cnf,"ClassifierNetfilter",threaded){ log(CREATE1 ); // construct classifier, i.e. init internal structures // allocate a receive buffer buf = (unsigned char *) new unsigned char[MYBUFSIZ]; // allocate libiptc handle iptc_h = new iptc_handle_t; memset(&stats, 0, sizeof(stats)); memset(iptc_h, 0, sizeof(iptc_handle_t)); // initialize the parameters table = strdup(cnf->getValue("NetfilterTable", "CLASSIFIER").c_str()); if (strlen(table) == 0) { table = new char[strlen(def_tablename)+1]; strcpy(table, def_tablename); } chain = strdup(cnf->getValue("NetfilterChain", "CLASSIFIER").c_str()); if (strlen(chain) == 0) { chain = new char[strlen(def_chainname)+1]; strcpy(chain, def_chainname); } if (strlen(cnf->getValue("NetfilterGroup", "CLASSIFIER").c_str()) > 0) { nlgroup = atoi(cnf->getValue("NetfilterGroup", "CLASSIFIER").c_str()); } else { nlgroup = def_nlgroup; } if (strlen(conf->getValue("NetfilterCPRange", "CLASSIFIER").c_str()) > 0) { cprange = atoi(conf->getValue("NetfilterCPRange", "CLASSIFIER").c_str()); } else { cprange = def_cprange; } if (strlen(conf->getValue("NetfilterQThres", "CLASSIFIER").c_str()) > 0) { qthres = atoi(conf->getValue("NetfilterQThres", "CLASSIFIER").c_str()); } else { qthres = def_nonrtqt; }#ifdef DEBUG2 fprintf(stderr, "Class_NF is using the following defaults: \n"); fprintf(stderr, " Table: %s\n", table); fprintf(stderr, " Chain: %s\n", chain); fprintf(stderr, " NLGroup: %d\n", nlgroup); fprintf(stderr, " CPRange: %d\n", cprange); fprintf(stderr, " QThres: %d\n", qthres);#endif log(CREATE2);}/* ------------------------- ~ClassifierNetfilter ------------------------- */ClassifierNetfilter::~ClassifierNetfilter(){ int ret = 1; log(SHUTDOWN ); // flush meter chain ret = flush_entries(chain, 0, iptc_h); if (ret) { ret = iptc_commit(iptc_h); } stop(); // destroy buffer saveDelete(buf; saveDelete(chain;}/* ------------------------- go ------------------------- */void ClassifierNetfilter::run(){ if (!running) { // create libiptc handle *iptc_h = iptc_init(table); if (!*iptc_h) { // try to insmod the module if iptc_init failed iptables_insmod("ip_tables", def_modprobe); *iptc_h = iptc_init(table); throw MyErr("cant initialize libiptc: %s", iptc_strerror(errno)); } // create ipulog handle h = ipulog_create_handle(ipulog_group2gmask(nlgroup)); if (!h) { throw MyErr("cant initialize libipulog: %s : %s", ""/*ipulog_strerror()*/, strerror(errno)); } MeterComponent::run(); }}/* ------------------------- stop ------------------------- */void ClassifierNetfilter::stop(){ if (running) { ipulog_destroy_handle(h); // destroy handle saveDelete(iptc_h; iptc_h = NULL; MeterComponent::stop(); } }/* ------------------------- main ------------------------- */void ClassifierNetfilter::main(){ // unsigned short pkt_len; // static metaData_t meta; // this function will be run as a single thread inside the classifier log("thread started" );#ifndef LOOPFULL for (; ; ) { try { len = ipulog_read(h, buf, MYBUFSIZ, 1); //printf("len %d\n", len); if (len < 0) { throw MyErr("ipulog_read: short read: %s : %s", ""/*ipulog_strerror()*/, strerror(errno)); } while ((upkt = ipulog_get_packet(h, buf, len)) != NULL) { myCore()->getPacketProcessor()->processPacket(atoi(upkt->prefix), (char *) upkt->payload, (metaData_t *) upkt); stats.packets++; stats.bytes += upkt->data_len; } } catch (MyErr &e ) { cerr << e << endl; } }#else // LOOPFULL { char buf[100]; metaData_t meta; int i = 1; // FIXME: enter better dummy values into struct meta.data_len = 100; meta.tv_sec = 0; meta.tv_usec = 0; // wait until a first task has been added while (maxid == 0 ) sleep(1); while (1) { myCore()->getPacketProcessor()->processPacket(i,buf,&meta); i++; if (i>maxid ) i = 1; } }#endif // LOOPFULL}struct netfilter_rule_entry *ClassifierNetfilter::alloc_rule_entry(struct ipt_entry *e, unsigned int nsaddrs, struct in_addr *saddrs, unsigned int ndaddrs, struct in_addr *daddrs){ struct netfilter_rule_entry *nfre; nfre = new struct netfilter_rule_entry; nfre->e = (struct ipt_entry *) new char[e->next_offset]; memcpy(nfre->e, e, e->next_offset); // FIXME: support only 1 src and 1 dst IP nfre->saddrs = *saddrs; nfre->daddrs = *daddrs; nfre->nsaddrs = 1; nfre->ndaddrs = 1; return nfre;} void ClassifierNetfilter::delete_rule_entry(struct netfilter_rule_entry *nfre){ // FIXME: support only 1 src and 1 dst IP saveDelete(nfre->e; saveDelete(nfre;} int ClassifierNetfilter::check_for_invert(char *param_in, char **param_out){ int i = 0; // assume leading WS have been stripped if (param_in && !strncmp(param_in, "!", 1)) { // jump over to param following !ignoring leading WS param_in = ¶m_in[1]; while (isspace(param_in[i])) i++; *param_out = ¶m_in[i]; return 1; } else { *param_out = param_in; return 0; }}/* ------------------------- addRule ------------------------- */// wrapper for handling bidir matches// FIXME integrate both add methodsvoid ClassifierNetfilter::addRule( RuleInfo &rinfo, int test ){ int rule_id, nAttributes, i; char **attributes, **params; int bidir = 0; // 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" ); for (i = 0; i<nAttributes; i++) { if (!strcmp(attributes[i], param_names[defp_bidir]) ) { // bidir flow match bidir = 1; } }#ifdef CLASS_DEBUG fprintf(stderr, "Adding forward rule\n");#endif // add forward this->_addRule(rinfo, test); // add backward if bidir match if (bidir) {#ifdef CLASS_DEBUG fprintf(stderr, "Bidirectional match: Adding backward rule\n");#endif for (i = 0; i<nAttributes; i++) { // exchange src with dst ip, exchange iiface with oiface if (!strcmp(attributes[i], param_names[defp_srcipmask]) ) { free(attributes[i]); attributes[i] = strdup(param_names[defp_dstipmask]); } else if (!strcmp(attributes[i], param_names[defp_dstipmask]) ) { free(attributes[i]); attributes[i] = strdup(param_names[defp_srcipmask]); } else if (!strcmp(attributes[i], param_names[defp_iniface]) ) { free(attributes[i]); attributes[i] = strdup(param_names[defp_outiface]); } else if (!strcmp(attributes[i], param_names[defp_outiface]) ) { free(attributes[i]); attributes[i] = strdup(param_names[defp_iniface]); } // exchange src with dst port // FIXME this is clumsy using parameter names directly else if ((!strcmp(attributes[i], "srcport")) || (!strcmp(attributes[i], "sport")) ) { free(attributes[i]); attributes[i] = strdup("dport"); } else if ((!strcmp(attributes[i], "dstport")) || (!strcmp(attributes[i], "dport")) ) { free(attributes[i]); attributes[i] = strdup("sport"); } } this->_addRule(rinfo, test); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -