Пример #1
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);
}
Пример #2
0
int
route_delete(route_t *r, const struct route_entry *entry)
{
	struct rtentry rt;
	struct addr dst;
	
	memset(&rt, 0, sizeof(rt));
	rt.rt_flags = RTF_UP;

	if (ADDR_ISHOST(&entry->route_dst)) {
		rt.rt_flags |= RTF_HOST;
		memcpy(&dst, &entry->route_dst, sizeof(dst));
	} else
		addr_net(&entry->route_dst, &dst);
	
	if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
	    addr_btos(entry->route_dst.addr_bits, &rt.rt_genmask) < 0)
		return (-1);
	
	return (ioctl(r->fd, SIOCDELRT, &rt));
}
Пример #3
0
static int
route_msg(route_t *r, int type, struct addr *dst, struct addr *gw)
{
	struct addr net;
	struct rt_msghdr *rtm;
	struct sockaddr *sa;
	u_char buf[BUFSIZ];
	pid_t pid;
	int len;

	memset(buf, 0, sizeof(buf));

	rtm = (struct rt_msghdr *)buf;
	rtm->rtm_version = RTM_VERSION;
	if ((rtm->rtm_type = type) != RTM_DELETE)
		rtm->rtm_flags = RTF_UP;
	rtm->rtm_addrs = RTA_DST;
	rtm->rtm_seq = ++r->seq;

	/* Destination */
	sa = (struct sockaddr *)(rtm + 1);
	if (addr_net(dst, &net) < 0 || addr_ntos(&net, sa) < 0)
		return (-1);
	sa = NEXTSA(sa);

	/* Gateway */
	if (gw != NULL && type != RTM_GET) {
		rtm->rtm_flags |= RTF_GATEWAY;
		rtm->rtm_addrs |= RTA_GATEWAY;
		if (addr_ntos(gw, sa) < 0)
			return (-1);
		sa = NEXTSA(sa);
	}
	/* Netmask */
	if (dst->addr_ip == IP_ADDR_ANY || dst->addr_bits < IP_ADDR_BITS) {
		rtm->rtm_addrs |= RTA_NETMASK;
		if (addr_btos(dst->addr_bits, sa) < 0)
			return (-1);
		sa = NEXTSA(sa);
	} else
		rtm->rtm_flags |= RTF_HOST;
	
	rtm->rtm_msglen = (u_char *)sa - buf;
#ifdef DEBUG
	route_msg_print(rtm);
#endif
#ifdef HAVE_STREAMS_ROUTE
	if (ioctl(r->fd, RTSTR_SEND, rtm) < 0)
		return (-1);
#else
	if (write(r->fd, buf, rtm->rtm_msglen) < 0)
		return (-1);

	pid = getpid();
	
	while (type == RTM_GET && (len = read(r->fd, buf, sizeof(buf))) > 0) {
		if (len < (int)sizeof(*rtm)) {
			return (-1);
		}
		if (rtm->rtm_type == type && rtm->rtm_pid == pid &&
		    rtm->rtm_seq == r->seq) {
			if (rtm->rtm_errno) {
				errno = rtm->rtm_errno;
				return (-1);
			}
			break;
		}
	}
#endif
	if (type == RTM_GET && (rtm->rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==
	    (RTA_DST|RTA_GATEWAY)) {
		sa = (struct sockaddr *)(rtm + 1);
		sa = NEXTSA(sa);
		
		if (addr_ston(sa, gw) < 0 || gw->addr_type != ADDR_TYPE_IP) {
			errno = ESRCH;
			return (-1);
		}
	}
	return (0);
}