static int
settunnel(prop_dictionary_t env, prop_dictionary_t oenv)
{
	const struct paddr_prefix *srcpfx, *dstpfx;
	struct if_laddrreq req;
	prop_data_t srcdata, dstdata;

	srcdata = (prop_data_t)prop_dictionary_get(env, "tunsrc");
	dstdata = (prop_data_t)prop_dictionary_get(env, "tundst");

	if (srcdata == NULL || dstdata == NULL) {
		warnx("%s.%d", __func__, __LINE__);
		errno = ENOENT;
		return -1;
	}

	srcpfx = prop_data_data_nocopy(srcdata);
	dstpfx = prop_data_data_nocopy(dstdata);

	if (srcpfx->pfx_addr.sa_family != dstpfx->pfx_addr.sa_family)
		errx(EXIT_FAILURE,
		    "source and destination address families do not match");

	memset(&req, 0, sizeof(req));
	memcpy(&req.addr, &srcpfx->pfx_addr,
	    MIN(sizeof(req.addr), srcpfx->pfx_addr.sa_len));
	memcpy(&req.dstaddr, &dstpfx->pfx_addr,
	    MIN(sizeof(req.dstaddr), dstpfx->pfx_addr.sa_len));

#ifdef INET6
	if (req.addr.ss_family == AF_INET6) {
		struct sockaddr_in6 *s6, *d;

		s6 = (struct sockaddr_in6 *)&req.addr;
		d = (struct sockaddr_in6 *)&req.dstaddr;
		if (s6->sin6_scope_id != d->sin6_scope_id) {
			errx(EXIT_FAILURE, "scope mismatch");
			/* NOTREACHED */
		}
		if (IN6_IS_ADDR_MULTICAST(&d->sin6_addr) ||
		    IN6_IS_ADDR_MULTICAST(&s6->sin6_addr))
			errx(EXIT_FAILURE, "tunnel src/dst is multicast");
		/* embed scopeid */
		inet6_putscopeid(s6, INET6_IS_ADDR_LINKLOCAL);
		inet6_putscopeid(d, INET6_IS_ADDR_LINKLOCAL);
	}
#endif /* INET6 */

	if (direct_ioctl(env, SIOCSLIFPHYADDR, &req) == -1)
		warn("SIOCSLIFPHYADDR");
	return 0;
}
Example #2
0
/*
 * Display an individual neighbor cache entry
 */
static void
get(char *host)
{
	struct sockaddr_in6 *mysin = &sin_m;
	struct addrinfo hints, *res;
	int gai_error;

	sin_m = blank_sin;
	(void)memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai_error = getaddrinfo(host, NULL, &hints, &res);
	if (gai_error) {
		warnx("%s: %s\n", host, gai_strerror(gai_error));
		return;
	}
	mysin->sin6_addr = ((struct sockaddr_in6 *)(void *)res->ai_addr)->sin6_addr;
	inet6_putscopeid(mysin, INET6_IS_ADDR_LINKLOCAL);
	dump(&mysin->sin6_addr, 0);
	if (found_entry == 0) {
		(void)getnameinfo((struct sockaddr *)(void *)mysin,
		    (socklen_t)mysin->sin6_len,
		    host_buf, sizeof(host_buf), NULL ,0,
		    (nflag ? NI_NUMERICHOST : 0));
		errx(1, "%s (%s) -- no entry", host, host_buf);
	}
}
Example #3
0
File: ndp.c Project: ryo/netbsd-src
static void
makeaddr(struct sockaddr_in6 *mysin, const void *resp)
{
	const struct sockaddr_in6 *res = resp;
	mysin->sin6_addr = res->sin6_addr;
	mysin->sin6_scope_id = res->sin6_scope_id;
	inet6_putscopeid(mysin, INET6_IS_ADDR_LINKLOCAL);
}
Example #4
0
/*
 * Set an individual neighbor cache entry
 */
static int
set(int argc, char **argv)
{
	register struct sockaddr_in6 *mysin = &sin_m;
	register struct sockaddr_dl *sdl;
	register struct rt_msghdr *rtm = &(m_rtmsg.m_rtm);
	struct addrinfo hints, *res;
	int gai_error;
	u_char *ea;
	char *host = argv[0], *eaddr = argv[1];

	getsocket();
	argc -= 2;
	argv += 2;
	sdl_m = blank_sdl;
	sin_m = blank_sin;

	(void)memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET6;
	gai_error = getaddrinfo(host, NULL, &hints, &res);
	if (gai_error) {
		warnx("%s: %s\n", host, gai_strerror(gai_error));
		return 1;
	}
	mysin->sin6_addr = ((struct sockaddr_in6 *)(void *)res->ai_addr)->sin6_addr;
	inet6_putscopeid(mysin, INET6_IS_ADDR_LINKLOCAL);
	ea = (u_char *)LLADDR(&sdl_m);
	if (ndp_ether_aton(eaddr, ea) == 0)
		sdl_m.sdl_alen = 6;
	flags = expire_time = 0;
	while (argc-- > 0) {
		if (strncmp(argv[0], "temp", 4) == 0) {
			struct timeval tim;

			(void)gettimeofday(&tim, 0);
			expire_time = tim.tv_sec + 20 * 60;
		} else if (strncmp(argv[0], "proxy", 5) == 0)
			flags |= RTF_ANNOUNCE;
		argv++;
	}
	if (rtmsg(RTM_GET) < 0) {
		errx(1, "RTM_GET(%s) failed", host);
		/* NOTREACHED */
	}
	mysin = (struct sockaddr_in6 *)(void *)(rtm + 1);
	sdl = (struct sockaddr_dl *)(void *)(RT_ROUNDUP(mysin->sin6_len) + (char *)(void *)mysin);
	if (IN6_ARE_ADDR_EQUAL(&mysin->sin6_addr, &sin_m.sin6_addr)) {
		if (sdl->sdl_family == AF_LINK &&
		    (rtm->rtm_flags & RTF_LLINFO) &&
		    !(rtm->rtm_flags & RTF_GATEWAY)) {
			switch (sdl->sdl_type) {
			case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023:
			case IFT_ISO88024: case IFT_ISO88025:
				goto overwrite;
			}
		}
		/*
		 * IPv4 arp command retries with sin_other = SIN_PROXY here.
		 */
		(void)fprintf(stderr, "set: cannot configure a new entry\n");
		return 1;
	}

overwrite:
	if (sdl->sdl_family != AF_LINK) {
		warnx("cannot intuit interface index and type for %s", host);
		return (1);
	}
	sdl_m.sdl_type = sdl->sdl_type;
	sdl_m.sdl_index = sdl->sdl_index;
	return (rtmsg(RTM_ADD));
}