/* --- */ int add_redirect_rule2( const char * ifname, const char * rhost, unsigned short eport, const char * iaddr, unsigned short iport, int proto, const char * desc, unsigned int timestamp) { struct ip_fw rule; int r; if (ipfw_validate_protocol(proto) < 0) return -1; if (ipfw_validate_ifname(ifname) < 0) return -1; memset(&rule, 0, sizeof(struct ip_fw)); rule.version = IP_FW_CURRENT_API_VERSION; #if 0 rule.fw_number = 1000; /* rule number */ rule.context = (void *)desc; /* The description is kept in a separate list */ #endif rule.fw_prot = proto; /* protocol */ rule.fw_flg |= IP_FW_F_IIFACE; /* interfaces to check */ rule.fw_flg |= IP_FW_F_IIFNAME; /* interfaces to check by name */ rule.fw_flg |= (IP_FW_F_IN | IP_FW_F_OUT); /* packet direction */ rule.fw_flg |= IP_FW_F_FWD; /* forward action */ #ifdef USE_IFNAME_IN_RULES if (ifname != NULL) { strlcpy(rule.fw_in_if.fu_via_if.name, ifname, IFNAMSIZ); /* src interface */ rule.fw_in_if.fu_via_if.unit = -1; } #endif if (inet_aton(iaddr, &rule.fw_out_if.fu_via_ip) == 0) { syslog(LOG_ERR, "inet_aton(): %m"); return -1; } memcpy(&rule.fw_dst, &rule.fw_out_if.fu_via_ip, sizeof(struct in_addr)); memcpy(&rule.fw_fwd_ip.sin_addr, &rule.fw_out_if.fu_via_ip, sizeof(struct in_addr)); rule.fw_dmsk.s_addr = INADDR_BROADCAST; /* TODO check this */ IP_FW_SETNDSTP(&rule, 1); /* number of external ports */ rule.fw_uar.fw_pts[0] = eport; /* external port */ rule.fw_fwd_ip.sin_port = iport; /* internal port */ if (rhost && rhost[0] != '\0') { inet_aton(rhost, &rule.fw_src); rule.fw_smsk.s_addr = htonl(INADDR_NONE); } r = ipfw_exec(IP_FW_ADD, &rule, sizeof(rule)); if(r >= 0) add_desc_time(eport, proto, desc, timestamp); return r; }
int scamper_firewall_ipfw_add(int n,int af,int p,void *s,void *d,int sp,int dp) { struct ip_fw fw; struct ip6_fw fw6; int level, optname; void *optval; socklen_t optlen; int i, fd; if(af == AF_INET) { memset(&fw, 0, sizeof(fw)); fw.fw_number = n; fw.fw_flg = IP_FW_F_DENY | IP_FW_F_IN; fw.fw_prot = p; memcpy(&fw.fw_src, s, 4); fw.fw_smsk.s_addr = ~0; memcpy(&fw.fw_dst, d, 4); fw.fw_dmsk.s_addr = ~0; fw.fw_uar.fw_pts[0] = sp; IP_FW_SETNSRCP(&fw, 1); fw.fw_uar.fw_pts[1] = dp; IP_FW_SETNDSTP(&fw, 1); #ifdef __APPLE__ fw.version = IP_FW_CURRENT_API_VERSION; #endif level = IPPROTO_IP; optname = IP_FW_ADD; optval = &fw; optlen = sizeof(fw); fd = fw4s; } else if(af == AF_INET6) { memset(&fw6, 0, sizeof(fw6)); fw6.fw_number = n; fw6.fw_flg = IPV6_FW_F_DENY | IPV6_FW_F_IN; fw6.fw_prot = p; memcpy(&fw6.fw_src, s, 16); for(i=0; i<4; i++) fw6.fw_smsk.s6_addr32[i] = ~0; memcpy(&fw6.fw_dst, d, 16); for(i=0; i<4; i++) fw6.fw_dmsk.s6_addr32[i] = ~0; fw6.fw_pts[0] = sp; IPV6_FW_SETNSRCP(&fw6, 1); fw6.fw_pts[1] = dp; IPV6_FW_SETNDSTP(&fw6, 1); #ifdef __APPLE__ fw6.version = IPV6_FW_CURRENT_API_VERSION; #endif level = IPPROTO_IPV6; optname = IPV6_FW_ADD; optval = &fw6; optlen = sizeof(fw6); fd = fw6s; } else return -1; if(setsockopt(fd, level, optname, optval, optlen) != 0) { printerror(errno, strerror, __func__, "could not add fw rule"); return -1; } return 0; }