/* add_filter_rule() * */ static int add_filter_rule(int proto, const char * rhost, const char * iaddr, unsigned short iport) { int r = 0; struct ipt_entry * e; struct ipt_entry * tmp; struct ipt_entry_match *match = NULL; struct ipt_entry_target *target = NULL; e = calloc(1, sizeof(struct ipt_entry)); if(!e) { syslog(LOG_ERR, "%s: calloc(%d) error", "add_filter_rule", (int)sizeof(struct ipt_entry)); return -1; } e->ip.proto = proto; if(proto == IPPROTO_TCP) { match = get_tcp_match(iport,0); } else { match = get_udp_match(iport,0); } 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; tmp = realloc(e, sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size); if(!tmp) { syslog(LOG_ERR, "%s: realloc(%d) error", "add_filter_rule", (int)(sizeof(struct ipt_entry) + match->u.match_size + target->u.target_size)); free(e); free(match); free(target); return -1; } e = tmp; 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; /* remote host */ if(rhost && (rhost[0] != '\0') && (0 != strcmp(rhost, "*"))) { e->ip.src.s_addr = inet_addr(rhost); e->ip.smsk.s_addr = INADDR_NONE; } r = iptc_init_verify_and_append("filter", miniupnpd_forward_chain, e, "add_filter_rule()"); free(target); free(match); free(e); return r; }
/* ip6tables -I %s %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j ACCEPT ip6tables -I %s %d -p %s -i %s --sport %hu -d %s --dport %hu -j ACCEPT miniupnpd_forward_chain, line_number, proto, ext_if_name, raddr, rport, iaddr, iport ip6tables -t raw -I PREROUTING %d -p %s -i %s -s %s --sport %hu -d %s --dport %hu -j TRACE ip6tables -t raw -I PREROUTING %d -p %s -i %s --sport %hu -d %s --dport %hu -j TRACE */ int add_pinhole(const char * ifname, const char * rem_host, unsigned short rem_port, const char * int_client, unsigned short int_port, int proto, unsigned int timestamp) { int uid; struct ip6t_entry * e; struct ip6t_entry_match *match = NULL; struct ip6t_entry_target *target = NULL; e = calloc(1, sizeof(struct ip6t_entry)); e->ipv6.proto = proto; if(ifname) strncpy(e->ipv6.iniface, ifname, IFNAMSIZ); if(rem_host) { inet_pton(AF_INET6, rem_host, &e->ipv6.src); memset(&e->ipv6.smsk, 0xff, sizeof(e->ipv6.smsk)); } inet_pton(AF_INET6, int_client, &e->ipv6.dst); memset(&e->ipv6.dmsk, 0xff, sizeof(e->ipv6.dmsk)); /*e->nfcache = NFC_IP_DST_PT;*/ /*e->nfcache |= NFC_UNKNOWN;*/ match = new_match(proto, rem_port, int_port); target = get_accept_target(); e = realloc(e, sizeof(struct ip6t_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 ip6t_entry) + match->u.match_size; e->next_offset = sizeof(struct ip6t_entry) + match->u.match_size + target->u.target_size; free(match); free(target); if(ip6tc_init_verify_append("filter", miniupnpd_v6_filter_chain, e) < 0) { free(e); return -1; } uid = add_to_pinhole_list(&e->ipv6.src, rem_port, &e->ipv6.dst, int_port, proto, timestamp); free(e); return uid; }
/* add_filter_rule() * */ int add_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; }