📄 classifiernetfilter.cc
字号:
maskaddr = ntohl(mask->s_addr); if (maskaddr == 0xFFFFFFFFL) /* we don't want to see "/32" */ return ""; i = 32; bits = 0xFFFFFFFEL; while (--i >= 0 && maskaddr != bits) bits < <= 1; if (i >= 0) sprintf(buf, "/%d", i); else /* mask was not a decent combination of 1's and 0's */ sprintf(buf, "/%s", addr_to_dotted(mask)); return buf;}/*static*/ char *addr_to_anyname(const struct in_addr *addr){ char *name; if ((name = addr_to_host(addr)) != NULL || (name = addr_to_network(addr)) != NULL) return name; return addr_to_dotted(addr);}#endif/*static*/ char *proto_to_name(u_int8_t proto, int nolookup){ unsigned int i; if (proto && !nolookup) { struct protoent *pent = getprotobynumber(proto); if (pent) return pent->p_name; } for (i = 0; i < sizeof(chain_protos)/sizeof(struct pprot); i++) if (chain_protos[i].num == proto) return chain_protos[i].name; return NULL;}/*static*/ u_int16_t parse_protocol(const char *s){ unsigned int proto; if (string_to_number(s, 0, 255, &proto) == -1) { struct protoent *pent; if ((pent = getprotobyname(s))) proto = pent->p_proto; else { unsigned int i; for (i = 0; i < sizeof(chain_protos)/sizeof(struct pprot); i++) { if (strcmp(s, chain_protos[i].name) == 0) { proto = chain_protos[i].num; break; } } if (i == sizeof(chain_protos)/sizeof(struct pprot)) exit_error(PARAMETER_PROBLEM, "unknown protocol `%s' specified", s); } } return (u_int16_t)proto;} /*static*/ struct in_addr *parse_hostnetwork(const char *name, unsigned int *naddrs){ struct in_addr *addrp, *addrptmp; if ((addrptmp = dotted_to_addr(name)) != NULL || (addrptmp = network_to_addr(name)) != NULL) { addrp = (struct in_addr *) fw_malloc(sizeof(struct in_addr)); inaddrcpy(addrp, addrptmp); *naddrs = 1; return addrp; } if ((addrp = host_to_addr(name, naddrs)) != NULL) return addrp; exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name);}/*static*/ struct in_addr *parse_mask(char *mask){ static struct in_addr maskaddr; struct in_addr *addrp; unsigned int bits; if (mask == NULL) { /* no mask at all defaults to 32 bits */ maskaddr.s_addr = 0xFFFFFFFF; return &maskaddr; } if ((addrp = dotted_to_addr(mask)) != NULL) /* dotted_to_addr already returns a network byte order addr */ return addrp; if (string_to_number(mask, 0, 32, &bits) == -1) exit_error(PARAMETER_PROBLEM, "invalid mask `%s' specified", mask); if (bits != 0) { maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); return &maskaddr; } maskaddr.s_addr = 0L; return &maskaddr;} /*static*/ void parse_hostnetworkmask(const char *name, struct in_addr **addrpp, struct in_addr *maskp, unsigned int *naddrs){ struct in_addr *addrp; char buf[256]; char *p; int i, j, k, n; strncpy(buf, name, sizeof(buf) - 1); if ((p = strrchr(buf, '/')) != NULL) { *p = '\0'; addrp = parse_mask(p + 1); } else addrp = parse_mask(NULL); inaddrcpy(maskp, addrp); /* if a null mask is given, the name is ignored, like in "any/0" */ if (maskp->s_addr == 0L) strcpy(buf, "0.0.0.0"); addrp = *addrpp = parse_hostnetwork(buf, naddrs); n = *naddrs; for (i = 0, j = 0; i < n; i++) { addrp[j++].s_addr & = maskp->s_addr; for (k = 0; k < j - 1; k++) { if (addrp[k].s_addr == addrp[j - 1].s_addr) { (*naddrs)--; j--; break; } } }}/*static*/ const char *parse_target(const char *targetname){ const char *ptr; if (strlen(targetname) < 1) exit_error(PARAMETER_PROBLEM, "Invalid target name (too short)"); if (strlen(targetname)+1 > sizeof(ipt_chainlabel)) exit_error(PARAMETER_PROBLEM, "Invalid target name `%s' (%i chars max)", targetname, sizeof(ipt_chainlabel)-1); for (ptr = targetname; *ptr; ptr++) if (isspace(*ptr)) exit_error(PARAMETER_PROBLEM,"Invalid target name `%s'", targetname); return targetname;}/*static*/ void parse_interface(const char *arg, char *vianame, unsigned char *mask){ int vialen = strlen(arg); unsigned int i; memset(mask, 0, IFNAMSIZ); memset(vianame, 0, IFNAMSIZ); if (vialen + 1 > IFNAMSIZ) exit_error(PARAMETER_PROBLEM, "interface name `%s' must be shorter than IFNAMSIZ" " (%i)", arg, IFNAMSIZ-1); strcpy(vianame, arg); if (vialen == 0) memset(mask, 0, IFNAMSIZ); else if (vianame[vialen - 1] == '+') { memset(mask, 0xFF, vialen - 1); memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); /* Remove `+' */ vianame[vialen - 1] = '\0'; } else { /* Include nul-terminator in match */ memset(mask, 0xFF, vialen + 1); memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); } for (i = 0; vianame[i]; i++) { if (!isalnum(vianame[i])) { printf("Warning: wierd character in interface" " `%s' (No aliases, :, !or *).\n", vianame); break; } }}/*static*/ struct iptables_match *find_match(const char *name, enum ipt_tryload tryload){ struct iptables_match *ptr; for (ptr = iptables_matches; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) break; } if (!ptr && tryload != DONT_LOAD) { char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so") + strlen(name)]; sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name); if (dlopen(path, RTLD_NOW)) { /* Found library. If it didn't register itself, maybe they specified target as match. */ ptr = find_match(name, DONT_LOAD); if (!ptr) exit_error(PARAMETER_PROBLEM, "Couldn't load match `%s'\n", name); } else if (tryload == LOAD_MUST_SUCCEED) exit_error(PARAMETER_PROBLEM, "Couldn't load match `%s':%s\n", name, dlerror()); } if (ptr) ptr->used = 1; return ptr;}/*static*/ struct iptables_match *find_proto(const char *pname, enum ipt_tryload tryload, int nolookup){ unsigned int proto; if (string_to_number(pname, 0, 255, &proto) != -1) return find_match(proto_to_name(proto, nolookup), tryload); return find_match(pname, tryload);} /*static*/ struct iptables_target *find_target(const char *name, enum ipt_tryload tryload){ struct iptables_target *ptr; /* Standard target? */ if (strcmp(name, "") == 0 || strcmp(name, IPTC_LABEL_ACCEPT) == 0 || strcmp(name, IPTC_LABEL_DROP) == 0 || strcmp(name, IPTC_LABEL_QUEUE) == 0 || strcmp(name, IPTC_LABEL_RETURN) == 0) name = "standard"; for (ptr = iptables_targets; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) break; } if (!ptr && tryload != DONT_LOAD) { char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so") + strlen(name)]; sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name); if (dlopen(path, RTLD_NOW)) { /* Found library. If it didn't register itself, maybe they specified match as a target. */ ptr = find_target(name, DONT_LOAD); if (!ptr) exit_error(PARAMETER_PROBLEM, "Couldn't load target `%s'\n", name); } else if (tryload == LOAD_MUST_SUCCEED) exit_error(PARAMETER_PROBLEM, "Couldn't load target `%s':%s\n", name, dlerror()); } if (ptr) ptr->used = 1; return ptr;}/*static*/ struct ipt_entry *generate_entry(const struct ipt_entry *fw, struct iptables_match *matches, struct ipt_entry_target *target){ unsigned int size; struct iptables_match *m; struct ipt_entry *e; size = sizeof(struct ipt_entry); for (m = matches; m; m = m->next) { if (m->used) { size += m->m->u.match_size; } } e = (struct ipt_entry *) fw_malloc(size + target->u.target_size); *e = *fw; e->target_offset = size; e->next_offset = size + target->u.target_size; size = 0; for (m = matches; m; m = m->next) { if (m->used) { memcpy(e->elems + size, m->m, m->m->u.match_size); size += m->m->u.match_size; } } memcpy(e->elems + size, target, target->u.target_size); return e;}/*static*/ char *get_modprobe(void){ int procfile; char *ret; procfile = open(PROC_SYS_MODPROBE, O_RDONLY); if (procfile < 0) return NULL; ret = (char *) fw_malloc(1024); if (ret) { switch (read(procfile, ret, 1024)) { case -1: goto fail; case 1024: goto fail; /* Partial read. Wierd */ } return ret; } fail: free(ret); close(procfile); return NULL;}/*static*/ int iptables_insmod(const char *modname, const char *modprobe){ char *buf = NULL; char *argv[3]; /* If they don't explicitly set it, read out of kernel */ if (!modprobe) { buf = get_modprobe(); if (!buf) return -1; modprobe = buf; } switch (fork()) { case 0: argv[0] = (char *)modprobe; argv[1] = (char *)modname; argv[2] = NULL; execv(argv[0], argv); /* not usually reached */ exit(0); case -1: return -1; default: /* parent */ wait(NULL); } free(buf); return 0;}#ifdef CLASS_DEBUG/*static*/ void print_num(u_int64_t number, unsigned int format){ if (format & FMT_KILOMEGAGIGA) { if (number > 99999) { number = (number + 500) / 1000; if (number > 9999) { number = (number + 500) / 1000; if (number > 9999) { number = (number + 500) / 1000; printf(FMT("%4lluG ","%lluG "),number); } else printf(FMT("%4lluM ","%lluM "), number); } else printf(FMT("%4lluK ","%lluK "), number); } else printf(FMT("%5llu ","%llu "), number); } else printf(FMT("%8llu ","%llu "), number);}/*static*/ int print_match(const struct ipt_entry_match *m, const struct ipt_ip *ip, int numeric){ struct iptables_match *match = find_match(m->u.user.name, TRY_LOAD); if (match) { if (match->print) match->print(ip, m, numeric); else printf("%s ", match->name); } else { if (m->u.user.name[0]) printf("UNKNOWN match `%s' ", m->u.user.name); } /* Don't stop iterating. */ return 0;}/* e is called `fw' here for hysterical raisins *//*static*/ void print_firewall(const struct ipt_entry *fw, const char *targname, unsigned int num, unsigned int format, const iptc_handle_t handle){ struct iptables_target *target = NULL; const struct ipt_entry_target *t; u_int8_t flags; char buf[BUFSIZ]; /* User creates a chain called "REJECT": this overrides the `REJECT' target module. Keep feeding them rope until the revolution... Bwahahahahah */ if (!iptc_is_chain(targname, handle)) { target = find_target(targname, TRY_LOAD); }else target = find_target(IPT_STANDARD_TARGET, LOAD_MUST_SUCCEED); t = ipt_get_target((struct ipt_entry *)fw); flags = fw->ip.flags; if (format & FMT_LINENUMBERS) printf(FMT("%-4u ", "%u "), num+1); if (!(format & FMT_NOCOUNTS)) { print_num(fw->counters.pcnt, format); print_num(fw->counters.bcnt, format); } if (!(format & FMT_NOTARGET)) printf(FMT("%-9s ", "%s "), targname); fputc(fw->ip.invflags & IPT_INV_PROTO ? '!' : ' ', stdout); { char *pname = proto_to_name(fw->ip.proto, format&FMT_NUMERIC); if (pname) printf(FMT("%-5s", "%s "), pname); else printf(FMT("%-5hu", "%hu "), fw->ip.proto); } if (format & FMT_OPTIONS) { if (format & FMT_NOTABLE) fputs("opt ", stdout); fputc(fw->ip.invflags & IPT_INV_FRAG ? '!' : '-', stdout); fputc(flags & IPT_F_FRAG ? 'f' : '-', stdout); fputc(' ', stdout); } if (format & FMT_VIA) { char iface[IFNAMSIZ+2]; if (fw->ip.invflags & IPT_INV_VIA_IN) { iface[0] = '!'; iface[1] = '\0'; } else iface[0] = '\0'; if (fw->ip.iniface[0] != '\0') { strcat(iface, fw->ip.iniface); /* If it doesn't compare the nul-term, it's a wildcard. */ if (fw->ip.iniface_mask[strlen(fw->ip.iniface)] == 0) strcat(iface, "+"); } else if (format & FMT_NUMERIC) strcat(iface, "*"); else strcat(iface, "any"); printf(FMT(" %-6s ","in %s "), iface); if (fw->ip.invflags & IPT_INV_VIA_OUT) { iface[0] = '!';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -