Example #1
0
int
addr_btos(uint16_t bits, struct sockaddr *sa)
{
	union sockunion *so = (union sockunion *)sa;

#ifdef HAVE_SOCKADDR_IN6
	if (bits > IP_ADDR_BITS && bits <= IP6_ADDR_BITS) {
		memset(&so->sin6, 0, sizeof(so->sin6));
#ifdef HAVE_SOCKADDR_SA_LEN
		so->sin6.sin6_len = IP6_ADDR_LEN + (bits / 8) + (bits % 8);
#endif
		so->sin6.sin6_family = AF_INET6;
		return (addr_btom(bits, &so->sin6.sin6_addr, IP6_ADDR_LEN));
	} else
#endif
	if (bits <= IP_ADDR_BITS) {
		memset(&so->sin, 0, sizeof(so->sin));
#ifdef HAVE_SOCKADDR_SA_LEN
		so->sin.sin_len = IP_ADDR_LEN + (bits / 8) + (bits % 8);
#endif
		so->sin.sin_family = AF_INET;
		return (addr_btom(bits, &so->sin.sin_addr, IP_ADDR_LEN));
	}
	errno = EINVAL;
	return (-1);
}
Example #2
0
static void
fr_to_fwc(const struct fw_rule *fr, struct ip_fwchange *fwc)
{
	memset(fwc, 0, sizeof(*fwc));

	strlcpy(fwc->fwc_rule.ipfw.fw_vianame, fr->fw_device, IFNAMSIZ);
	
	if (fr->fw_op == FW_OP_ALLOW)
		strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_ACCEPT, 
		    sizeof(fwc->fwc_rule.label));
	else
		strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_BLOCK,
		    sizeof(fwc->fwc_rule.label));

	if (fr->fw_dir == FW_DIR_IN)
		strlcpy(fwc->fwc_label, IP_FW_LABEL_INPUT,
		    sizeof(fwc->fwc_label));
	else
		strlcpy(fwc->fwc_label, IP_FW_LABEL_OUTPUT,
		    sizeof(fwc->fwc_label));
	
	fwc->fwc_rule.ipfw.fw_proto = fr->fw_proto;
	fwc->fwc_rule.ipfw.fw_src.s_addr = fr->fw_src.addr_ip;
	fwc->fwc_rule.ipfw.fw_dst.s_addr = fr->fw_dst.addr_ip;
	addr_btom(fr->fw_src.addr_bits, &fwc->fwc_rule.ipfw.fw_smsk.s_addr,
	    IP_ADDR_LEN);
	addr_btom(fr->fw_dst.addr_bits, &fwc->fwc_rule.ipfw.fw_dmsk.s_addr,
	    IP_ADDR_LEN);

	/* XXX - ICMP? */
	fwc->fwc_rule.ipfw.fw_spts[0] = fr->fw_sport[0];
	fwc->fwc_rule.ipfw.fw_spts[1] = fr->fw_sport[1];
	fwc->fwc_rule.ipfw.fw_dpts[0] = fr->fw_dport[0];
	fwc->fwc_rule.ipfw.fw_dpts[1] = fr->fw_dport[1];
}
int
route_get(route_t *route, struct route_entry *entry)
{
	MIB_IPFORWARDROW ipfrow;
	DWORD mask;

	if (entry->route_dst.addr_type != ADDR_TYPE_IP ||
	    GetBestRoute(entry->route_dst.addr_ip,
	    IP_ADDR_ANY, &ipfrow) != NO_ERROR)
		return (-1);

	if (ipfrow.dwForwardProto == 2 &&	/* XXX - MIB_IPPROTO_LOCAL */
	    (ipfrow.dwForwardNextHop|IP_CLASSA_NET) !=
	    (IP_ADDR_LOOPBACK|IP_CLASSA_NET) &&
	    !IP_LOCAL_GROUP(ipfrow.dwForwardNextHop)) { 
		errno = ENXIO;
		SetLastError(ERROR_NO_DATA);
		return (-1);
	}
	addr_btom(entry->route_dst.addr_bits, &mask, IP_ADDR_LEN);
	
	entry->route_gw.addr_type = ADDR_TYPE_IP;
	entry->route_gw.addr_bits = IP_ADDR_BITS;
	entry->route_gw.addr_ip = ipfrow.dwForwardNextHop;
	
	return (0);
}
int
route_add(route_t *route, const struct route_entry *entry)
{
	MIB_IPFORWARDROW ipfrow;
	struct addr net;

	memset(&ipfrow, 0, sizeof(ipfrow));

	if (GetBestInterface(entry->route_gw.addr_ip,
	    &ipfrow.dwForwardIfIndex) != NO_ERROR)
		return (-1);

	if (addr_net(&entry->route_dst, &net) < 0 ||
	    net.addr_type != ADDR_TYPE_IP)
		return (-1);
	
	ipfrow.dwForwardDest = net.addr_ip;
	addr_btom(entry->route_dst.addr_bits,
	    &ipfrow.dwForwardMask, IP_ADDR_LEN);
	ipfrow.dwForwardNextHop = entry->route_gw.addr_ip;
	ipfrow.dwForwardType = 4;	/* XXX - next hop != final dest */
	ipfrow.dwForwardProto = 3;	/* XXX - MIB_PROTO_NETMGMT */
	
	if (CreateIpForwardEntry(&ipfrow) != NO_ERROR)
		return (-1);
	
	return (0);
}
Example #5
0
int
intf_set(intf_t *intf, const struct intf_entry *entry)
{
	/*
	 * XXX - could set interface up/down via SetIfEntry(),
	 * but what about the rest of the configuration? :-(
	 * {Add,Delete}IPAddress for 2000/XP only
	 */
#if 0
	/* Set interface address. XXX - 2000/XP only? */
	if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
		ULONG ctx = 0, inst = 0;
		UINT ip, mask;

		memcpy(&ip, &entry->intf_addr.addr_ip, IP_ADDR_LEN);
		addr_btom(entry->intf_addr.addr_bits, &mask, IP_ADDR_LEN);
		
		if (AddIPAddress(ip, mask,
			_find_ifindex(intf, entry->intf_name),
			&ctx, &inst) != NO_ERROR) {
			return (-1);
		}
		return (0);
	}
#endif
	errno = ENOSYS;
	SetLastError(ERROR_NOT_SUPPORTED);
	return (-1);
}
Example #6
0
static void
fr_to_pr(const struct fw_rule *fr, struct pf_rule *pr)
{
	memset(pr, 0, sizeof(*pr));
	
	strlcpy(pr->ifname, fr->fw_device, sizeof(pr->ifname));
	
	pr->action = (fr->fw_op == FW_OP_ALLOW) ? PF_PASS : PF_DROP;
	pr->direction = (fr->fw_dir == FW_DIR_IN) ? PF_IN : PF_OUT;
	pr->proto = fr->fw_proto;

	pr->af = AF_INET;
	PFRA_ADDR(&pr->src) = fr->fw_src.addr_ip;
	addr_btom(fr->fw_src.addr_bits, &(PFRA_MASK(&pr->src)), IP_ADDR_LEN);
	
	PFRA_ADDR(&pr->dst) = fr->fw_dst.addr_ip;
	addr_btom(fr->fw_dst.addr_bits, &(PFRA_MASK(&pr->dst)), IP_ADDR_LEN);
	
	switch (fr->fw_proto) {
	case IP_PROTO_ICMP:
		if (fr->fw_sport[1])
			pr->type = (u_char)(fr->fw_sport[0] &
			    fr->fw_sport[1]) + 1;
		if (fr->fw_dport[1])
			pr->code = (u_char)(fr->fw_dport[0] &
			    fr->fw_dport[1]) + 1;
		break;
	case IP_PROTO_TCP:
	case IP_PROTO_UDP:
		pr->src.port[0] = htons(fr->fw_sport[0]);
		pr->src.port[1] = htons(fr->fw_sport[1]);
		if (pr->src.port[0] == pr->src.port[1]) {
			pr->src.port_op = PF_OP_EQ;
		} else
			pr->src.port_op = PF_OP_IRG;

		pr->dst.port[0] = htons(fr->fw_dport[0]);
		pr->dst.port[1] = htons(fr->fw_dport[1]);
		if (pr->dst.port[0] == pr->dst.port[1]) {
			pr->dst.port_op = PF_OP_EQ;
		} else
			pr->dst.port_op = PF_OP_IRG;
		break;
	}
}
Example #7
0
int
addr_net(const struct addr *a, struct addr *b)
{
	uint32_t mask;
	int i, j;

	if (a->addr_type == ADDR_TYPE_IP) {
		addr_btom(a->addr_bits, &mask, IP_ADDR_LEN);
		b->addr_type = ADDR_TYPE_IP;
		b->addr_bits = IP_ADDR_BITS;
		b->addr_ip = a->addr_ip & mask;
	} else if (a->addr_type == ADDR_TYPE_ETH) {
		memcpy(b, a, sizeof(*b));
		if (a->addr_data8[0] & 0x1)
			memset(b->addr_data8 + 3, 0, 3);
		b->addr_bits = ETH_ADDR_BITS;
	} else if (a->addr_type == ADDR_TYPE_IP6) {
		b->addr_type = ADDR_TYPE_IP6;
		b->addr_bits = IP6_ADDR_BITS;
		memset(&b->addr_ip6, 0, IP6_ADDR_LEN);
		
		switch ((i = a->addr_bits / 32)) {
		case 4: b->addr_data32[3] = a->addr_data32[3];
		case 3: b->addr_data32[2] = a->addr_data32[2];
		case 2: b->addr_data32[1] = a->addr_data32[1];
		case 1: b->addr_data32[0] = a->addr_data32[0];
		}
		if ((j = a->addr_bits % 32) > 0) {
			addr_btom(j, &mask, sizeof(mask));
			b->addr_data32[i] = a->addr_data32[i] & mask;
		}
	} else
		return (-1);
	
	return (0);
}
Example #8
0
int
parse_host_range(const char *range, uint32_t *start, uint32_t *end)
{
	struct addr addr, bcast;
	uint32_t val, mask;
	u_int u[4];
	char *p, *s;
	int ret = -1;

	if ((p = strdup(range)) == NULL)
		return (ret);
	
	if (addr_aton(p, &addr) == 0 && addr.addr_type == ADDR_TYPE_IP) {
		if (addr.addr_bits != IP_ADDR_BITS) {
			*start = htonl(ntohl(addr.addr_ip) + 1);
			addr_bcast(&addr, &bcast);
			*end = htonl(ntohl(bcast.addr_ip) - 1);
		} else
			*start = *end = addr.addr_ip;
		ret = 0;
	} else if ((s = strchr(p, '-')) != NULL) {
		*s = '\0';
		if (ip_aton(p, start) == 0) {
			if (ip_aton(s + 1, end) == 0) {
				ret = 0;
			} else if ((val = atoi(s + 1)) > 0 && val <= 0xff) {
				*end = (*start & IP_CLASSC_NET) | htonl(val);
				ret = 0;
			}
		}
	} else if ((s = strchr(p, '/')) != NULL) {
		*s = '\0';
		memset(u, 0, sizeof(u));
		if (sscanf(p, "%d.%d.%d.%d", &u[0], &u[1], &u[2], &u[3]) > 0 &&
		    addr_btom(atoi(s + 1), &mask, IP_ADDR_LEN) == 0) {
			val = ((u[0]<<24) | (u[1]<<16) | (u[2]<<8) | u[3]) &
			    ntohl(mask);
			*start = htonl(val + 1);
			*end = htonl((val | ~(ntohl(mask))) - 1);
			ret = 0;
		}
	}
	free(p);
	return (ret);
}
Example #9
0
static int
_arp_set_dev(const struct intf_entry *entry, void *arg)
{
	struct arpreq *ar = (struct arpreq *)arg;
	struct addr dst;
	uint32_t mask;

	if (entry->intf_type == INTF_TYPE_ETH &&
	    entry->intf_addr.addr_type == ADDR_TYPE_IP) {
		addr_btom(entry->intf_addr.addr_bits, &mask, IP_ADDR_LEN);
		addr_ston((struct sockaddr *)&ar->arp_pa, &dst);
	
		if ((entry->intf_addr.addr_ip & mask) ==
		    (dst.addr_ip & mask)) {
			strlcpy(ar->arp_dev, entry->intf_name,
			    sizeof(ar->arp_dev));
			return (1);
		}
	}
	return (0);
}
Example #10
0
int
addr_bcast(const struct addr *a, struct addr *b)
{
	struct addr mask;
	
	if (a->addr_type == ADDR_TYPE_IP) {
		addr_btom(a->addr_bits, &mask.addr_ip, IP_ADDR_LEN);
		b->addr_type = ADDR_TYPE_IP;
		b->addr_bits = IP_ADDR_BITS;
		b->addr_ip = (a->addr_ip & mask.addr_ip) |
		    (~0L & ~mask.addr_ip);
	} else if (a->addr_type == ADDR_TYPE_ETH) {
		b->addr_type = ADDR_TYPE_ETH;
		b->addr_bits = ETH_ADDR_BITS;
		memcpy(&b->addr_eth, ETH_ADDR_BROADCAST, ETH_ADDR_LEN);
	} else {
		/* XXX - no broadcast addresses in IPv6 */
		errno = EINVAL;
		return (-1);
	}
	return (0);
}
Example #11
0
int
route_delete(route_t *route, const struct route_entry *entry)
{
	MIB_IPFORWARDROW ipfrow;
	DWORD mask;
	
	if (entry->route_dst.addr_type != ADDR_TYPE_IP ||
	    GetBestRoute(entry->route_dst.addr_ip,
	    IP_ADDR_ANY, &ipfrow) != NO_ERROR)
		return (-1);

	addr_btom(entry->route_dst.addr_bits, &mask, IP_ADDR_LEN);
	
	if (ipfrow.dwForwardDest != entry->route_dst.addr_ip ||
	    ipfrow.dwForwardMask != mask) {
		errno = ENXIO;
		SetLastError(ERROR_NO_DATA);
		return (-1);
	}
	if (DeleteIpForwardEntry(&ipfrow) != NO_ERROR)
		return (-1);
	
	return (0);
}