📄 iptcrdr.c
字号:
r = 0; break; } } } iptc_free(&h); if(r == 0) { syslog(LOG_INFO, "Trying to delete rules at index %u", index); /* Now delete both rules */ h = iptc_init("nat"); if(h) { r = delete_rule_and_commit(index, &h, "delete_redirect_rule"); } h = iptc_init("filter"); if(h && (r == 0)) { r = delete_rule_and_commit(index, &h, "delete_filter_rule"); } } del_redirect_desc(eport, proto); return r;}/* ==================================== *//* TODO : add the -m state --state NEW,ESTABLISHED,RELATED * only for the filter rule */static struct ipt_entry_match *get_tcp_match(unsigned short dport){ struct ipt_entry_match *match; struct ipt_tcp * tcpinfo; size_t size; size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + IPT_ALIGN(sizeof(struct ipt_tcp)); match = calloc(1, size); match->u.match_size = size; strncpy(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN); tcpinfo = (struct ipt_tcp *)match->data; tcpinfo->spts[0] = 0; /* all source ports */ tcpinfo->spts[1] = 0xFFFF; tcpinfo->dpts[0] = dport; /* specified destination port */ tcpinfo->dpts[1] = dport; return match;}static struct ipt_entry_match *get_udp_match(unsigned short dport){ struct ipt_entry_match *match; struct ipt_udp * udpinfo; size_t size; size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + IPT_ALIGN(sizeof(struct ipt_udp)); match = calloc(1, size); match->u.match_size = size; strncpy(match->u.user.name, "udp", IPT_FUNCTION_MAXNAMELEN); udpinfo = (struct ipt_udp *)match->data; udpinfo->spts[0] = 0; /* all source ports */ udpinfo->spts[1] = 0xFFFF; udpinfo->dpts[0] = dport; /* specified destination port */ udpinfo->dpts[1] = dport; return match;}static struct ipt_entry_target *get_dnat_target(const char * daddr, unsigned short dport){ struct ipt_entry_target * target; struct ip_nat_multi_range * mr; struct ip_nat_range * range; size_t size; size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(struct ip_nat_multi_range)); target = calloc(1, size); target->u.target_size = size; strncpy(target->u.user.name, "DNAT", IPT_FUNCTION_MAXNAMELEN); /* one ip_nat_range already included in ip_nat_multi_range */ mr = (struct ip_nat_multi_range *)&target->data[0]; mr->rangesize = 1; range = &mr->range[0]; range->min_ip = range->max_ip = inet_addr(daddr); range->flags |= IP_NAT_RANGE_MAP_IPS; range->min.all = range->max.all = htons(dport); range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; return target;}/* iptc_init_verify_and_append() * return 0 on success, -1 on failure */static intiptc_init_verify_and_append(const char * table, struct ipt_entry * e, const char * logcaller){ iptc_handle_t h; h = iptc_init(table); if(!h) { syslog(LOG_ERR, "%s : iptc_init() error : %s\n", logcaller, iptc_strerror(errno)); return -1; } if(!iptc_is_chain(miniupnpd_chain, h)) { syslog(LOG_ERR, "%s : iptc_is_chain() error : %s\n", logcaller, iptc_strerror(errno)); return -1; } if(!iptc_append_entry(miniupnpd_chain, e, &h)) { syslog(LOG_ERR, "%s : iptc_append_entry() error : %s\n", logcaller, iptc_strerror(errno)); return -1; } if(!iptc_commit(&h)) { syslog(LOG_ERR, "%s : iptc_commit() error : %s\n", logcaller, iptc_strerror(errno)); return -1; } return 0;}/* add nat rule * iptables -t nat -A MINIUPNPD -p proto --dport eport -j DNAT --to iaddr:iport * */intaddnatrule(int proto, unsigned short eport, const char * iaddr, unsigned short iport){ int r = 0; struct ipt_entry * e; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); e->ip.proto = proto; if(proto == IPPROTO_TCP) { match = get_tcp_match(eport); } else { match = get_udp_match(eport); } e->nfcache = NFC_IP_DST_PT; target = get_dnat_target(iaddr, iport); e->nfcache |= NFC_UNKNOWN; e = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) + match->u.match_size; e->next_offset = sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size; r = iptc_init_verify_and_append("nat", e, "addnatrule()"); free(target); free(match); free(e); return r;}/* ================================= */static struct ipt_entry_target *get_accept_target(void){ struct ipt_entry_target * target = NULL; size_t size; size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int)); target = calloc(1, size); target->u.user.target_size = size; strncpy(target->u.user.name, "ACCEPT", IPT_FUNCTION_MAXNAMELEN); return target;}/* add_filter_rule() * */intadd_filter_rule(int proto, const char * iaddr, unsigned short iport){ int r = 0; struct ipt_entry * e; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); e->ip.proto = proto; if(proto == IPPROTO_TCP) { match = get_tcp_match(iport); } else { match = get_udp_match(iport); } e->nfcache = NFC_IP_DST_PT; e->ip.dst.s_addr = inet_addr(iaddr); e->ip.dmsk.s_addr = INADDR_NONE; target = get_accept_target(); e->nfcache |= NFC_UNKNOWN; e = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); memcpy(e->elems, match, match->u.match_size); memcpy(e->elems + match->u.match_size, target, target->u.target_size); e->target_offset = sizeof(struct ipt_entry) + match->u.match_size; e->next_offset = sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size; r = iptc_init_verify_and_append("filter", e, "add_filter_rule()"); free(target); free(match); free(e); return r;}/* ================================ */static intprint_match(const struct ipt_entry_match *match){ printf("match %s\n", match->u.user.name); if(0 == strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN)) { struct ipt_tcp * tcpinfo; tcpinfo = (struct ipt_tcp *)match->data; printf("srcport = %hu:%hu dstport = %hu:%hu\n", tcpinfo->spts[0], tcpinfo->spts[1], tcpinfo->dpts[0], tcpinfo->dpts[1]); } else if(0 == strncmp(match->u.user.name, "udp", IPT_FUNCTION_MAXNAMELEN)) { struct ipt_udp * udpinfo; udpinfo = (struct ipt_udp *)match->data; printf("srcport = %hu:%hu dstport = %hu:%hu\n", udpinfo->spts[0], udpinfo->spts[1], udpinfo->dpts[0], udpinfo->dpts[1]); } return 0;}static voidprint_iface(const char * iface, const unsigned char * mask, int invert){ unsigned i; if(mask[0] == 0) return; if(invert) printf("! "); for(i=0; i<IFNAMSIZ; i++) { if(mask[i]) { if(iface[i]) putchar(iface[i]); } else { if(iface[i-1]) putchar('+'); break; } }}static voidprintip(uint32_t ip){ printf("%u.%u.%u.%u", ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);}/* for debug *//* read the "filter" and "nat" tables */intlist_redirect_rule(const char * ifname){ iptc_handle_t h; const struct ipt_entry * e; const struct ipt_entry_target * target; const struct ip_nat_multi_range * mr; const char * target_str; h = iptc_init("nat"); if(!h) { printf("iptc_init() error : %s\n", iptc_strerror(errno)); return -1; } if(!iptc_is_chain(miniupnpd_chain, h)) { printf("chain %s not found\n", miniupnpd_chain); return -1; } for(e = iptc_first_rule(miniupnpd_chain, &h); e; e = iptc_next_rule(e, &h)) { target_str = iptc_get_target(e, &h); printf("===\n"); printf("src = %s%s/%s\n", (e->ip.invflags & IPT_INV_SRCIP)?"! ":"", inet_ntoa(e->ip.src), inet_ntoa(e->ip.smsk)); printf("dst = %s%s/%s\n", (e->ip.invflags & IPT_INV_DSTIP)?"! ":"", inet_ntoa(e->ip.dst), inet_ntoa(e->ip.dmsk)); /*printf("in_if = %s out_if = %s\n", e->ip.iniface, e->ip.outiface);*/ printf("in_if = "); print_iface(e->ip.iniface, e->ip.iniface_mask, e->ip.invflags & IPT_INV_VIA_IN); printf(" out_if = "); print_iface(e->ip.outiface, e->ip.outiface_mask, e->ip.invflags & IPT_INV_VIA_OUT); printf("\n"); printf("ip.proto = %s%d\n", (e->ip.invflags & IPT_INV_PROTO)?"! ":"", e->ip.proto); /* display matches stuff */ if(e->target_offset) { IPT_MATCH_ITERATE(e, print_match); /*printf("\n");*/ } printf("target = %s\n", target_str); target = (void *)e + e->target_offset; mr = (const struct ip_nat_multi_range *)&target->data[0]; printf("ips "); printip(ntohl(mr->range[0].min_ip)); printf(" "); printip(ntohl(mr->range[0].max_ip)); printf("\nports %hu %hu\n", ntohs(mr->range[0].min.all), ntohs(mr->range[0].max.all)); printf("flags = %x\n", mr->range[0].flags); } iptc_free(&h); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -