Esempio n. 1
0
static void
tunnel_status(prop_dictionary_t env, prop_dictionary_t oenv)
{
	char dstserv[sizeof(",65535")];
	char srcserv[sizeof(",65535")];
	char psrcaddr[NI_MAXHOST];
	char pdstaddr[NI_MAXHOST];
	const int niflag = NI_NUMERICHOST|NI_NUMERICSERV;
	struct if_laddrreq req;
	const struct afswtch *afp;

	psrcaddr[0] = pdstaddr[0] = '\0';

	memset(&req, 0, sizeof(req));
	if (direct_ioctl(env, SIOCGLIFPHYADDR, &req) == -1)
		return;
	afp = lookup_af_bynum(req.addr.ss_family);
#ifdef INET6
	if (req.addr.ss_family == AF_INET6)
		in6_fillscopeid((struct sockaddr_in6 *)&req.addr);
#endif /* INET6 */
	getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len,
	    psrcaddr, sizeof(psrcaddr), &srcserv[1], sizeof(srcserv) - 1,
	    niflag);

#ifdef INET6
	if (req.dstaddr.ss_family == AF_INET6)
		in6_fillscopeid((struct sockaddr_in6 *)&req.dstaddr);
#endif
	getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len,
	    pdstaddr, sizeof(pdstaddr), &dstserv[1], sizeof(dstserv) - 1,
	    niflag);

	srcserv[0] = (strcmp(&srcserv[1], "0") == 0) ? '\0' : ',';
	dstserv[0] = (strcmp(&dstserv[1], "0") == 0) ? '\0' : ',';

	printf("\ttunnel %s %s%s --> %s%s\n", afp ? afp->af_name : "???",
	    psrcaddr, srcserv, pdstaddr, dstserv);
}
Esempio n. 2
0
int
phys_status(int s, char *ifname, char *tmp_buf, char *tmp_buf2,
int buf_len, int buf2_len)
{
#ifdef NI_WITHSCOPEID
	const int       niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
#else
	const int       niflag = NI_NUMERICHOST;
#endif
	struct if_laddrreq req;
	int dstport = 0;

	bzero(&req, sizeof(req));
	(void) strlcpy(req.iflr_name, ifname, sizeof(req.iflr_name));
	if (ioctl(s, SIOCGLIFPHYADDR, (caddr_t) &req) < 0)
		return(-1);
	if (req.addr.ss_family == AF_INET6)
		in6_fillscopeid((struct sockaddr_in6 *)&req.addr);
	if (getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len,
	    tmp_buf, buf_len, 0, 0, niflag) != 0) {
		printf("%% phys_status: 0/getnameinfo failure\n");
		return (-1);
	}

	if (req.dstaddr.ss_family == AF_INET) {
		dstport = ((struct sockaddr_in *)&req.dstaddr)->sin_port;
	} else if (req.dstaddr.ss_family == AF_INET6) {
		in6_fillscopeid((struct sockaddr_in6 *) & req.dstaddr);
		dstport = ((struct sockaddr_in6 *)&req.dstaddr)->sin6_port;
	}
	if (getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len,
	    tmp_buf2, buf2_len, 0, 0, niflag) != 0) {
		printf("%% phys_status: 1/getnameinfo failure\n");
		return(-1);
	}
	return(ntohs(dstport));
}
Esempio n. 3
0
File: inet6.c Progetto: OpenKod/src
char *
inet6name(struct in6_addr *in6p)
{
	struct sockaddr_in6 sin6;
	char hbuf[NI_MAXHOST], *cp;
	static char line[50];
	static char domain[MAXHOSTNAMELEN];
	static int first = 1;
	int flags, error;

	if (IN6_IS_ADDR_UNSPECIFIED(in6p)) {
		strcpy(line, "*");
		return (line);
	}
	if (first && !numeric_addr) {
		first = 0;
		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
		    (cp = strchr(domain, '.')))
			(void) strcpy(domain, cp + 1);
		else
			domain[0] = 0;
	}
	memset(&sin6, 0, sizeof(sin6));
	memcpy(&sin6.sin6_addr, in6p, sizeof(*in6p));
	sin6.sin6_family = AF_INET6;
	/* XXX: in6p.s6_addr[2] can contain scopeid. */ 
	in6_fillscopeid(&sin6);
	flags = (numeric_addr) ? NI_NUMERICHOST : 0;
	error = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), hbuf,
	    sizeof(hbuf), NULL, 0, flags);
	if (error == 0) {
		if ((flags & NI_NUMERICHOST) == 0 &&
		    (cp = strchr(hbuf, '.')) &&
		    !strcmp(cp + 1, domain))
			*cp = 0;
		strcpy(line, hbuf);
	} else {
		/* XXX: this should not happen. */
		sprintf(line, "%s",
			inet_ntop(AF_INET6, (void *)&sin6.sin6_addr, ntop_buf,
				sizeof(ntop_buf)));
	}
	return (line);
}
Esempio n. 4
0
static const char *
fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
{
	static char workbuf[128];
	const char *cp;

	if (sa == NULL)
		return ("null");

	switch(sa->sa_family) {
	case AF_INET:
	    {
		struct sockaddr_in *sockin = (struct sockaddr_in *)sa;

		if ((sockin->sin_addr.s_addr == INADDR_ANY) &&
			mask &&
			ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr)
				==0L)
				cp = "default" ;
		else if (flags & RTF_HOST)
			cp = routename(sockin->sin_addr.s_addr);
		else if (mask)
			cp = netname(sockin->sin_addr.s_addr,
				     ntohl(((struct sockaddr_in *)mask)
					   ->sin_addr.s_addr));
		else
			cp = netname(sockin->sin_addr.s_addr, 0L);
		break;
	    }

#ifdef INET6
	case AF_INET6:
	    {
		struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;

		in6_fillscopeid(sa6);

		if (flags & RTF_HOST)
		    cp = routename6(sa6);
		else if (mask)
		    cp = netname6(sa6,
				  &((struct sockaddr_in6 *)mask)->sin6_addr);
		else {
		    cp = netname6(sa6, NULL);
		}
		break;
	    }
#endif /*INET6*/

	case AF_IPX:
	    {
		struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
		if (ipx_nullnet(satoipx_addr(work)))
			cp = "default";
		else
			cp = ipx_print(sa);
		break;
	    }
	case AF_APPLETALK:
	    {
		if (!(flags & RTF_HOST) && mask)
			cp = atalk_print2(sa,mask,9);
		else
			cp = atalk_print(sa,11);
		break;
	    }
	case AF_NETGRAPH:
	    {
		strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data,
		        sizeof(workbuf));
		cp = workbuf;
		break;
	    }

	case AF_LINK:
	    {
		struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;

		if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
		    sdl->sdl_slen == 0) {
			(void) sprintf(workbuf, "link#%d", sdl->sdl_index);
			cp = workbuf;
		} else
			switch (sdl->sdl_type) {

			case IFT_ETHER:
			case IFT_L2VLAN:
			case IFT_BRIDGE:
				if (sdl->sdl_alen == ETHER_ADDR_LEN) {
					cp = ether_ntoa((struct ether_addr *)
					    (sdl->sdl_data + sdl->sdl_nlen));
					break;
				}
				/* FALLTHROUGH */
			default:
				cp = link_ntoa(sdl);
				break;
			}
		break;
	    }

	default:
	    {
		u_char *s = (u_char *)sa->sa_data, *slim;
		char *cq, *cqlim;

		cq = workbuf;
		slim =  sa->sa_len + (u_char *) sa;
		cqlim = cq + sizeof(workbuf) - 6;
		cq += sprintf(cq, "(%d)", sa->sa_family);
		while (s < slim && cq < cqlim) {
			cq += sprintf(cq, " %02x", *s++);
			if (s < slim)
			    cq += sprintf(cq, "%02x", *s++);
		}
		cp = workbuf;
	    }
	}

	return (cp);
}
Esempio n. 5
0
/*
 * Find a server address that can be used by `caller' to contact
 * the local service specified by `serv_uaddr'. If `clnt_uaddr' is
 * non-NULL, it is used instead of `caller' as a hint suggesting
 * the best address (e.g. the `r_addr' field of an rpc, which
 * contains the rpcbind server address that the caller used).
 *
 * Returns the best server address as a malloc'd "universal address"
 * string which should be freed by the caller. On error, returns NULL.
 */
char *
addrmerge(arpc_addr_t *caller, const char *serv_uaddr, const char *clnt_uaddr,
	  const char *netid)
{
	struct ifaddrs *ifap, *ifp = NULL, *bestif;
	arpc_addr_t *serv_nbp = NULL, *hint_nbp = NULL, tbuf;
	struct sockaddr *caller_sa, *hint_sa, *ifsa, *ifmasksa, *serv_sa;
	struct sockaddr_storage ss;
	socklen_t len;
	const char *hint_uaddr = NULL;
	char *caller_uaddr = NULL;
	char *ret = NULL;
	int err;

#ifdef ND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
		    clnt_uaddr == NULL ? "NULL" : clnt_uaddr, netid);
#endif
	caller_sa = (struct sockaddr *)caller->buf;

	err = ar_taddr2uaddr(rpcbind_ioctx, netid, caller, &caller_uaddr);
	if (err != 0) {
		goto freeit;
	}

	/*
	 * Use `clnt_uaddr' as the hint if non-NULL, but ignore it if its
	 * address family is different from that of the caller.
	 */
	hint_sa = NULL;
	if (clnt_uaddr != NULL) {
		hint_uaddr = clnt_uaddr;
		err = ar_uaddr2taddr(rpcbind_ioctx, netid, 
				     clnt_uaddr, &hint_nbp);
		if (err != 0) {
			goto freeit;
		}
		hint_sa = (struct sockaddr *)hint_nbp->buf;
	}
	if (hint_sa == NULL || hint_sa->sa_family != caller_sa->sa_family) {
		hint_uaddr = caller_uaddr;
		hint_sa = (struct sockaddr *)caller->buf;
	}

#ifdef ND_DEBUG
	if (debugging) {
		fprintf(stderr, "addrmerge: hint %s\n", hint_uaddr);
	}
#endif
	/* Local caller, just return the server address. */
	if (strncmp(caller_uaddr, "0.0.0.0.", 8) == 0 ||
	    strncmp(caller_uaddr, "::.", 3) == 0 || caller_uaddr[0] == '/') {
		ret = strdup(serv_uaddr);
		goto freeit;
	}

	if (getifaddrs(&ifp) < 0) {
		goto freeit;
	}

	/*
	 * Loop through all interfaces. For each interface, see if the
	 * network portion of its address is equal to that of the client.
	 * If so, we have found the interface that we want to use.
	 */
	bestif = NULL;
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		ifsa = ifap->ifa_addr;
		ifmasksa = ifap->ifa_netmask;

		if (ifsa == NULL || ifsa->sa_family != hint_sa->sa_family ||
		    !(ifap->ifa_flags & IFF_UP)) {
			continue;
		}

		switch (hint_sa->sa_family) {
		case AF_INET:
			/*
			 * If the hint address matches this interface
			 * address/netmask, then we're done.
			 */
			if (!bitmaskcmp(&SA2SINADDR(ifsa),
			    &SA2SINADDR(hint_sa), &SA2SINADDR(ifmasksa),
			    sizeof(struct in_addr))) {
				bestif = ifap;
				goto found;
			}
			break;
		case AF_INET6:
			/*
			 * For v6 link local addresses, if the caller is on
			 * a link-local address then use the scope id to see
			 * which one.
			 */
			in6_fillscopeid(SA2SIN6(ifsa));
			if (IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(ifsa)) &&
			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(caller_sa)) &&
			    IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(hint_sa))) {
				if (SA2SIN6(ifsa)->sin6_scope_id ==
				    SA2SIN6(caller_sa)->sin6_scope_id) {
					bestif = ifap;
					goto found;
				}
			} else if (!bitmaskcmp(&SA2SIN6ADDR(ifsa),
			    &SA2SIN6ADDR(hint_sa), &SA2SIN6ADDR(ifmasksa),
			    sizeof(struct in6_addr))) {
				bestif = ifap;
				goto found;
			}
			break;
		default:
			continue;
		}

		/*
		 * Remember the first possibly useful interface, preferring
		 * "normal" to point-to-point and loopback ones.
		 */
		if (bestif == NULL ||
		    (!(ifap->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
		     (bestif->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)))) {
			bestif = ifap;
		}
	}
	if (bestif == NULL) {
		goto freeit;
	}

found:
	/*
	 * Construct the new address using the the address from
	 * `bestif', and the port number from `serv_uaddr'.
	 */
	err = ar_uaddr2taddr(rpcbind_ioctx, netid, serv_uaddr, &serv_nbp);
	if (err != 0) {
		goto freeit;
	}
	serv_sa = (struct sockaddr *)serv_nbp->buf;

	switch (ss.ss_family) {
	case AF_INET:
		len = sizeof(struct sockaddr_in);
		memcpy(&ss, bestif->ifa_addr, len);
		SA2SIN(&ss)->sin_port = SA2SIN(serv_sa)->sin_port;
		break;
	case AF_INET6:
		len = sizeof(struct sockaddr_in6);
		memcpy(&ss, bestif->ifa_addr, len);
		SA2SIN6(&ss)->sin6_port = SA2SIN6(serv_sa)->sin6_port;
		break;
	default:
		memset(&ss, 0, sizeof(ss));
		len = 0;
		break;
	}
	tbuf.len = len;
	tbuf.maxlen = sizeof(ss);
	tbuf.buf = (char *)&ss;
	err = ar_taddr2uaddr(rpcbind_ioctx, netid, &tbuf, &ret);
	if (err != 0) {
		ret = NULL;
	}
freeit:
	if (caller_uaddr != NULL) {
		free(caller_uaddr);
	}
	if (hint_nbp != NULL) {
		if (hint_nbp->buf) {
			free(hint_nbp->buf);
		}
		free(hint_nbp);
	}
	if (serv_nbp != NULL) {
		if (serv_nbp->buf) {
			free(serv_nbp->buf);
		}
		free(serv_nbp);
	}
	if (ifp != NULL) {
		freeifaddrs(ifp);
	}

#ifdef ND_DEBUG
	if (debugging) {
		fprintf(stderr, "addrmerge: returning %s\n", ret);
	}
#endif
	return ret;
}
Esempio n. 6
0
static const char *
fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
{
	static char buf[128];
	const char *cp;

	if (sa == NULL)
		return ("null");

	switch(sa->sa_family) {
#ifdef INET6
	case AF_INET6:
		/*
		 * The sa6->sin6_scope_id must be filled here because
		 * this sockaddr is extracted from kmem(4) directly
		 * and has KAME-specific embedded scope id in
		 * sa6->sin6_addr.s6_addr[2].
		 */
		in6_fillscopeid(satosin6(sa));
		/* FALLTHROUGH */
#endif /*INET6*/
	case AF_INET:
		if (flags & RTF_HOST)
			cp = routename(sa, numeric_addr);
		else if (mask)
			cp = netname(sa, mask);
		else
			cp = netname(sa, NULL);
		break;
	case AF_NETGRAPH:
	    {
		strlcpy(buf, ((struct sockaddr_ng *)sa)->sg_data,
		    sizeof(buf));
		cp = buf;
		break;
	    }
	case AF_LINK:
	    {
#if 0
		struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;

		/* Interface route. */
		if (sdl->sdl_nlen)
			cp = sdl->sdl_data;
		else
#endif
			cp = routename(sa, 1);
		break;
	    }
	default:
	    {
		u_char *s = (u_char *)sa->sa_data, *slim;
		char *cq, *cqlim;

		cq = buf;
		slim =  sa->sa_len + (u_char *) sa;
		cqlim = cq + sizeof(buf) - sizeof(" ffff");
		snprintf(cq, sizeof(buf), "(%d)", sa->sa_family);
		cq += strlen(cq);
		while (s < slim && cq < cqlim) {
			snprintf(cq, sizeof(" ff"), " %02x", *s++);
			cq += strlen(cq);
			if (s < slim) {
			    snprintf(cq, sizeof("ff"), "%02x", *s++);
			    cq += strlen(cq);
			}
		}
		cp = buf;
	    }
	}

	return (cp);
}
Esempio n. 7
0
File: conf.c Progetto: sthen/nsh
int conf_ifaddrs(FILE *output, char *ifname, int flags, int af)
{
	struct ifaddrs *ifa, *ifap;
	struct sockaddr_in *sin, *sinmask, *sindest;
	struct sockaddr_in6 *sin6, *sin6mask, *sin6dest;
	struct in6_ifreq ifr6;
	int ippntd = 0;

	if (getifaddrs(&ifap) != 0) {
		printf("%% conf: getifaddrs failed: %s\n",
		strerror(errno));
		return(-1);
	}

	/*
	 * Cycle through getifaddrs for interfaces with our
	 * desired name that sport af or (AF_INET | AF_INET6).
	 * Print the IP and related information.
	 */
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ))
			continue;

		switch (ifa->ifa_addr->sa_family) {
		int s;
		case AF_INET:
			if (af != AF_INET && af != 0)
				continue;
			sin = (struct sockaddr_in *)ifa->ifa_addr;
			if (sin->sin_addr.s_addr == INADDR_ANY)
				continue;
			sinmask = (struct sockaddr_in *)ifa->ifa_netmask;
			if (flags & IFF_POINTOPOINT) {
				sindest = (struct sockaddr_in *)ifa->ifa_dstaddr;
				fprintf(output, " ip %s",
				    routename4(sin->sin_addr.s_addr));
				fprintf(output, " %s", inet_ntoa(sindest->sin_addr));
			} else if (flags & IFF_BROADCAST) {
				sindest = (struct sockaddr_in *)ifa->ifa_broadaddr;
				fprintf(output, " ip %s",
				    netname4(sin->sin_addr.s_addr, sinmask));
				/*
				 * no reason to save the broadcast addr
				 * if it is standard (this should always 
				 * be true unless someone has messed up their
				 * network or they are playing around...)
				 */
				if (ntohl(sindest->sin_addr.s_addr) !=
				    in4_brdaddr(sin->sin_addr.s_addr,
				    sinmask->sin_addr.s_addr))
					fprintf(output, " %s",
					    inet_ntoa(sindest->sin_addr));
			} else {
				fprintf(output, " ip %s",
				    netname4(sin->sin_addr.s_addr, sinmask));
			}
			ippntd = 1;
			break;
		case AF_INET6:
			if (af != AF_INET6 && af != 0)
				continue;
			sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
			sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask;

			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
				continue;
			if (!ipv6ll_db_compare(sin6, sin6mask, ifname))
				continue;
			in6_fillscopeid(sin6);

			/* get address flags */
			memset(&ifr6, 0, sizeof(ifr6));
			strlcpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
			memcpy(&ifr6.ifr_addr, &sin6, sizeof(ifr6.ifr_addr));
			s = socket(PF_INET6, SOCK_DGRAM, 0);
			if (s < 0)
				printf("%% conf_ifaddrs: socket: %s\n",
				    strerror(errno));
			if (ioctl(s, SIOCGIFAFLAG_IN6, (caddr_t)&ifr6) < 0) {
				if (errno != EADDRNOTAVAIL)
					printf("%% conf_ifaddrs: " \
					    "SIOCGIFAFLAG_IN6: %s\n",
					    strerror(errno));
			} else {
				/* skip autoconf addresses */
				if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_AUTOCONF)
					continue;
			}

			if (flags & IFF_POINTOPOINT) {
				fprintf(output, " ip %s", routename6(sin6));
				sin6dest = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
				in6_fillscopeid(sin6dest);
				fprintf(output, " %s", routename6(sin6dest));
			} else {
				fprintf(output, " ip %s",
				    netname6(sin6, sin6mask));
			}
			ippntd = 1;
			break;
		default:
			continue;
		}
		fprintf(output, "\n");
	}
	freeifaddrs(ifap);

	return ippntd;
}
Esempio n. 8
0
int conf_ifaddrs(FILE *output, char *ifname, int flags, int af)
{
	struct ifaddrs *ifa, *ifap;
	struct sockaddr_in *sin, *sinmask, *sindest;
	struct sockaddr_in6 *sin6, *sin6mask, *sin6dest;
	int ippntd = 0;

	if (getifaddrs(&ifap) != 0) {
		printf("%% conf: getifaddrs failed: %s\n",
		strerror(errno));
		return(-1);
	}

	/*
	 * Cycle through getifaddrs for interfaces with our
	 * desired name that sport AF_INET | AF_INET6. Print
	 * the IP and related information.
	 */
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ))
			continue;

		switch (ifa->ifa_addr->sa_family) {
		case AF_INET:
			if (af != AF_INET && af != 0)
				continue;
			sin = (struct sockaddr_in *)ifa->ifa_addr;
			if (sin->sin_addr.s_addr == 0)
				continue;
			sinmask = (struct sockaddr_in *)ifa->ifa_netmask;
			if (flags & IFF_POINTOPOINT) {
				sindest = (struct sockaddr_in *)ifa->ifa_dstaddr;
				fprintf(output, " ip %s",
				    routename4(sin->sin_addr.s_addr));
				fprintf(output, " %s", inet_ntoa(sindest->sin_addr));
			} else if (flags & IFF_BROADCAST) {
				sindest = (struct sockaddr_in *)ifa->ifa_broadaddr;
				fprintf(output, " ip %s",
				    netname4(sin->sin_addr.s_addr, sinmask));
				/*
				 * no reason to save the broadcast addr
				 * if it is standard (this should always 
				 * be true unless someone has messed up their
				 * network or they are playing around...)
				 */
				if (ntohl(sindest->sin_addr.s_addr) !=
				    in4_brdaddr(sin->sin_addr.s_addr,
				    sinmask->sin_addr.s_addr))
					fprintf(output, " %s",
					    inet_ntoa(sindest->sin_addr));
			} else {
				fprintf(output, " ip %s",
				    netname4(sin->sin_addr.s_addr, sinmask));
			}
			ippntd = 1;
			break;
		case AF_INET6:
			if (af != AF_INET6 && af != 0)
				continue;
			sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
			sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
				continue;
			if (!ipv6ll_db_compare(sin6, sin6mask, ifname))
				continue;
			in6_fillscopeid(sin6);
			if (flags & IFF_POINTOPOINT) {
				fprintf(output, " ip %s", routename6(sin6));
				sin6dest = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
				in6_fillscopeid(sin6dest);
				fprintf(output, " %s", routename6(sin6dest));
			} else {
				fprintf(output, " ip %s",
				    netname6(sin6, sin6mask));
			}
			ippntd = 1;
			break;
		default:
			continue;
		}
		fprintf(output, "\n");
	}
	freeifaddrs(ifap);

	return ippntd;
}
Esempio n. 9
0
File: if.c Progetto: yellowman/nsh
int
show_int(int argc, char **argv)
{
	struct ifaddrs *ifap, *ifa;
	struct if_nameindex *ifn_list, *ifnp;
	struct ifreq ifr, ifrdesc;
	struct if_data if_data;
	struct sockaddr_in *sin = NULL, *sinmask = NULL, *sindest;
	struct sockaddr_in6 *sin6 = NULL, *sin6mask = NULL, *sin6dest;
	struct timeval tv;

	short tmp;
	int ifs, br, flags, days, hours, mins, pntd;
	int ippntd = 0;
	int physrt, physttl;
	time_t c;
	char *type, *lladdr, *ifname = NULL;

	char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE];

	if (argc == 3)
		ifname = argv[2];

	/*
	 * Show all interfaces when no ifname specified.
	 */
	if (ifname == NULL) {
		if ((ifn_list = if_nameindex()) == NULL) {
			printf("%% show_int: if_nameindex failed\n");
			return 0;
		}
		for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
			char *args[] = { NULL, NULL, ifnp->if_name };

			show_int(3, args);
		}
		if_freenameindex(ifn_list);
		return(0);
	} else if (!is_valid_ifname(ifname)) {
		printf("%% interface %s not found\n", ifname);
		return(1);
	}

	if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		printf("%% show_int: %s\n", strerror(errno));
		return(1);
	}

	if (!(br = is_bridge(ifs, (char *)ifname)))
		br = 0;

	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

	/*
	 * Show up/down status and last change time
	 */
	flags = get_ifflags(ifname, ifs);

	ifr.ifr_data = (caddr_t)&if_data;
	if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) {
		printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno));
		close(ifs);
		return(1);
	}

	printf("%% %s", ifname);

	/* description */
	memset(&ifrdesc, 0, sizeof(ifrdesc));
	strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name));
	ifrdesc.ifr_data = (caddr_t)&ifdescr;
	if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 &&
	    strlen(ifrdesc.ifr_data))
		printf(" (%s)", ifrdesc.ifr_data);

	putchar('\n');

	printf("  %s is %s", br ? "Bridge" : "Interface",
	    flags & IFF_UP ? "up" : "down");

	if (if_data.ifi_lastchange.tv_sec) {
		gettimeofday(&tv, (struct timezone *)0);
		c = difftime(tv.tv_sec, if_data.ifi_lastchange.tv_sec);
		days = c / (24 * 60 * 60);
		c %= (24 * 60 * 60);
		hours = c / (60 * 60);
		c %= (60 * 60);
		mins = c / 60;
		c %= 60;
		printf(" (last change ");
		if (days)
			printf("%id ", days);
		printf("%02i:%02i:%02i)", hours, mins, (int)c);
	}

	printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down");
	printf("\n");

	type = iftype(if_data.ifi_type);

	printf("  Interface type %s", type);
	if (flags & IFF_BROADCAST)
		printf(" (Broadcast)");
	else if (flags & IFF_POINTOPOINT)
		printf(" (PointToPoint)");

	if ((lladdr = get_hwdaddr(ifname)) != NULL)
		printf(", hardware address %s", lladdr);
	printf("\n");

	show_trunk(ifs, ifname);
	media_status(ifs, ifname, "  Media type ");

	/*
	 * Print interface IP address, and broadcast or
	 * destination if available.  But, don't print broadcast
	 * if it is what we would expect given the ip and netmask!
	 */
	if (getifaddrs(&ifap) != 0) {
		printf("%% show_int: getifaddrs failed: %s\n",
		    strerror(errno));
		return(1);
	}
 
	/*
	 * Cycle through getifaddrs for interfaces with our
	 * desired name that sport AF_INET, print the IP and
	 * related information.
	 */
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ))
			continue;

		switch (ifa->ifa_addr->sa_family) {
		case AF_INET:
			sin = (struct sockaddr_in *)ifa->ifa_addr;
			sinmask = (struct sockaddr_in *)ifa->ifa_netmask;
			if (sin->sin_addr.s_addr == INADDR_ANY)
				continue;
			break;
		case AF_INET6:
			sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
			sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask;
			if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
				continue;
			in6_fillscopeid(sin6);
			break;
		default:
			continue;
		}
		
		if (!ippntd) 
			printf("  Internet address");

		printf("%s %s", ippntd ? "," : "", ifa->ifa_addr->sa_family
		    == AF_INET ? netname4(sin->sin_addr.s_addr, sinmask) :
		    netname6(sin6, sin6mask));

		ippntd = 1;

		switch (ifa->ifa_addr->sa_family) {
		case AF_INET:
			if (flags & IFF_POINTOPOINT) {
				sindest = (struct sockaddr_in *)
				    ifa->ifa_dstaddr;
				printf(" (Destination %s)",
				    routename4(sindest->sin_addr.s_addr));
			} else if (flags & IFF_BROADCAST) {
				sindest = (struct sockaddr_in *)
				    ifa->ifa_broadaddr;
				/*
				 * no reason to show the broadcast addr
				 * if it is standard (this should always
				 * be true unless someone has messed up their
				 * network or they are playing around...)
				 */
				if (ntohl(sindest->sin_addr.s_addr) !=
				    in4_brdaddr(sin->sin_addr.s_addr,
				    sinmask->sin_addr.s_addr) &&
				    ntohl(sindest->sin_addr.s_addr) !=
				    INADDR_ANY)
					printf(" (Broadcast %s)",
					    inet_ntoa(sindest->sin_addr));
			}
			break;
		case AF_INET6:
			if (flags & IFF_POINTOPOINT) {
				sin6dest = (struct sockaddr_in6 *)
				    ifa->ifa_dstaddr;
				in6_fillscopeid(sin6dest);
				printf(" (Destination %s)",
				    routename6(sin6dest));
			}
			break;
		default:
			printf(" unknown");
			break;
		}
	}

	if (ippntd) {
		printf("\n");
	}
	freeifaddrs(ifap);

	if (!br) {
		if (phys_status(ifs, ifname, tmp_str, tmp_str2,
		    sizeof(tmp_str), sizeof(tmp_str2)) > 0) {
			printf("  Tunnel source %s destination %s",
			    tmp_str, tmp_str2);
			if (((physrt = get_physrtable(ifs, ifname)) != 0))
				printf(" destination rdomain %i", physrt);
			if (((physttl = get_physttl(ifs, ifname)) != 0))
				printf(" ttl %i", physttl);
			printf("\n");
		}
		carp_state(ifs, ifname);

		printf(" ");
		show_vnet_parent(ifs, ifname);
		if (ioctl(ifs, SIOCGIFRDOMAIN, (caddr_t)&ifr) != -1)
			printf(" rdomain %d,", ifr.ifr_rdomainid);

		/*
		 * Display MTU, line rate
		 */
		printf(" MTU %u bytes", if_data.ifi_mtu);
		if (ioctl(ifs, SIOCGIFHARDMTU, (caddr_t)&ifr) != -1) {
			if (ifr.ifr_hardmtu)
				printf(" (hardmtu %u)", ifr.ifr_hardmtu);
		}
		if (if_data.ifi_baudrate)
			printf(", Line Rate %qu %s",
			    MBPS(if_data.ifi_baudrate) ?
			    MBPS(if_data.ifi_baudrate) :
			    if_data.ifi_baudrate / 1000,
			    MBPS(if_data.ifi_baudrate) ? "Mbps" : "Kbps");

		printf("\n");
	}

	if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != 0) {
		printf("  SSID %s", tmp_str);
		if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != 0)
			printf(", key %s", tmp_str);
		if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str),
		    POWERSAVE)) != 0)
			printf(", powersaving (%s ms)\n", tmp_str);
		printf("\n");
	}

	/*
	 * Display remaining info from if_data structure
	 */
	printf("  %qu packets input, %qu bytes, %qu errors, %qu drops\n",
	    if_data.ifi_ipackets, if_data.ifi_ibytes, if_data.ifi_ierrors,
	    if_data.ifi_iqdrops);
	printf("  %qu packets output, %qu bytes, %qu errors, %qu unsupported\n",
	    if_data.ifi_opackets, if_data.ifi_obytes, if_data.ifi_oerrors,
	    if_data.ifi_noproto);
	if (if_data.ifi_ibytes && if_data.ifi_ipackets &&
	    (if_data.ifi_ibytes / if_data.ifi_ipackets) >= ETHERMIN) {
		/* < ETHERMIN means byte counter probably rolled over */
		printf("  %qu input", if_data.ifi_ibytes /
		    if_data.ifi_ipackets);
		pntd = 1;
	} else
		pntd = 0;
	if (if_data.ifi_obytes && if_data.ifi_opackets &&
	    (if_data.ifi_obytes / if_data.ifi_opackets) >= ETHERMIN) {
		/* < ETHERMIN means byte counter probably rolled over */
		printf("%s%qu output", pntd ? ", " : "  ",
		    if_data.ifi_obytes / if_data.ifi_opackets);
		pntd = 1;
	}
	if (pntd)
		printf(" (average bytes/packet)\n");

	switch(if_data.ifi_type) {
	/*
	 * These appear to be the only interface types to increase collision
	 * count in the OpenBSD 3.2 kernel.
	 */
	case IFT_ETHER:
	case IFT_SLIP:
	case IFT_PROPVIRTUAL:
	case IFT_IEEE80211:
		printf("  %qu collisions\n", if_data.ifi_collisions);
		break;
	default:
		break;
	}

	if(verbose) {
		if (flags) {
			printf("  Flags:\n    ");
			bprintf(stdout, flags, ifnetflags);
			printf("\n");
		}
		printifhwfeatures(ifs, ifname);
		if (br) {
			if ((tmp = bridge_list(ifs, ifname, "    ", tmp_str,
			    sizeof(tmp_str), SHOW_STPSTATE))) {
				printf("  STP member state%s:\n", tmp > 1 ?
				    "s" : "");
				printf("%s", tmp_str);
			}
			bridge_addrs(ifs, ifname, "  ", "    ");
		}
		media_supported(ifs, ifname, "  ", "    ");
	}

	close(ifs);
	return(0);
}
Esempio n. 10
0
char *
addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
	  char *netid)
{
	struct ifaddrs *ifap, *ifp, *bestif;
#ifdef INET6
	struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6;
	struct sockaddr_in6 *newsin6;
#endif
	struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin;
	struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf;
	struct sockaddr *serv_sa;
	struct sockaddr *clnt_sa;
	struct sockaddr_storage ss;
	struct netconfig *nconf;
	struct sockaddr *clnt = caller->buf;
	char *ret = NULL;

#ifdef INET6
	servsin6 = ifsin6 = newsin6 = NULL;	/* XXXGCC -Wuninitialized */
#endif
	servsin = newsin = NULL;		/* XXXGCC -Wuninitialized */

#ifdef RPCBIND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
		    clnt_uaddr, netid);
#endif
	nconf = getnetconfigent(netid);
	if (nconf == NULL)
		return NULL;

	/*
	 * Local merge, just return a duplicate.
	 */
	if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0)
		return strdup(clnt_uaddr);

	serv_nbp = uaddr2taddr(nconf, serv_uaddr);
	if (serv_nbp == NULL)
		return NULL;

	serv_sa = (struct sockaddr *)serv_nbp->buf;
	if (clnt_uaddr != NULL) {
		clnt_nbp = uaddr2taddr(nconf, clnt_uaddr);
		if (clnt_nbp == NULL) {
			free(serv_nbp);
			return NULL;
		}
		clnt_sa = (struct sockaddr *)clnt_nbp->buf;
		if (clnt_sa->sa_family == AF_LOCAL) {
			free(serv_nbp);
			free(clnt_nbp);
			free(clnt_sa);
			return strdup(serv_uaddr);
		}
	} else {
		clnt_sa = (struct sockaddr *)
		    malloc(sizeof (struct sockaddr_storage));
		memcpy(clnt_sa, clnt, clnt->sa_len);
	}

	if (getifaddrs(&ifp) < 0) {
		free(serv_nbp);
		free(clnt_sa);
		if (clnt_nbp != NULL)
			free(clnt_nbp);
		return 0;
	}

	/*
	 * Loop through all interfaces. For each interface, see if the
	 * network portion of its address is equal to that of the client.
	 * If so, we have found the interface that we want to use.
	 */
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != clnt->sa_family ||
		    !(ifap->ifa_flags & IFF_UP))
			continue;

		switch (clnt->sa_family) {
		case AF_INET:
			/*
			 * realsin: address that recvfrom gave us.
			 * ifsin: address of interface being examined.
			 * clntsin: address that client want us to contact
			 *           it on
			 * servsin: local address of RPC service.
			 * sinmask: netmask of this interface
			 * newsin: initially a copy of clntsin, eventually
			 *         the merged address
			 */
			servsin = (struct sockaddr_in *)serv_sa;
			clntsin = (struct sockaddr_in *)clnt_sa;
			sinmask = (struct sockaddr_in *)ifap->ifa_netmask;
			newsin = (struct sockaddr_in *)&ss;
			ifsin = (struct sockaddr_in *)ifap->ifa_addr;
			if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr,
			    &sinmask->sin_addr, sizeof (struct in_addr))) {
				goto found;
			}
			break;
#ifdef INET6
		case AF_INET6:
			/*
			 * realsin6: address that recvfrom gave us.
			 * ifsin6: address of interface being examined.
			 * clntsin6: address that client want us to contact
			 *           it on
			 * servsin6: local address of RPC service.
			 * sin6mask: netmask of this interface
			 * newsin6: initially a copy of clntsin, eventually
			 *          the merged address
			 *
			 * For v6 link local addresses, if the client contacted
			 * us via a link-local address, and wants us to reply
			 * to one, use the scope id to see which one.
			 */
			realsin6 = (struct sockaddr_in6 *)clnt;
			ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
			in6_fillscopeid(ifsin6);
			clntsin6 = (struct sockaddr_in6 *)clnt_sa;
			servsin6 = (struct sockaddr_in6 *)serv_sa;
			sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
			newsin6 = (struct sockaddr_in6 *)&ss;
			if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) &&
			    IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) &&
			    IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) {
				if (ifsin6->sin6_scope_id !=
				    realsin6->sin6_scope_id)
					continue;
				goto found;
			}
			if (!bitmaskcmp(&ifsin6->sin6_addr,
			    &clntsin6->sin6_addr, &sin6mask->sin6_addr,
			    sizeof (struct in6_addr)))
				goto found;
			break;
#endif
		default:
			goto freeit;
		}
	}
	/*
	 * Didn't find anything. Get the first possibly useful interface,
	 * preferring "normal" interfaces to point-to-point and loopback
	 * ones.
	 */
	bestif = NULL;
	for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
		if (ifap->ifa_addr->sa_family != clnt->sa_family ||
		    !(ifap->ifa_flags & IFF_UP))
			continue;
		if (!(ifap->ifa_flags & IFF_LOOPBACK) &&
		    !(ifap->ifa_flags & IFF_POINTOPOINT)) {
			bestif = ifap;
			break;
		}
		if (bestif == NULL)
			bestif = ifap;
		else if ((bestif->ifa_flags & IFF_LOOPBACK) &&
		    !(ifap->ifa_flags & IFF_LOOPBACK))
			bestif = ifap;
	}
	ifap = bestif;
found:
	switch (clnt->sa_family) {
	case AF_INET:
		memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len);
		newsin->sin_port = servsin->sin_port;
		tbuf.len = clnt_sa->sa_len;
		tbuf.maxlen = sizeof (struct sockaddr_storage);
		tbuf.buf = newsin;
		break;				
#ifdef INET6
	case AF_INET6:
		assert(newsin6);
		memcpy(newsin6, ifsin6, clnt_sa->sa_len);
		newsin6->sin6_port = servsin6->sin6_port;
		tbuf.maxlen = sizeof (struct sockaddr_storage);
		tbuf.len = clnt_sa->sa_len;
		tbuf.buf = newsin6;
		break;
#endif
	default:
		goto freeit;
	}
	if (ifap != NULL)
		ret = taddr2uaddr(nconf, &tbuf);
freeit:
	freenetconfigent(nconf);
	free(serv_sa);
	free(serv_nbp);
	if (clnt_sa != NULL)
		free(clnt_sa);
	if (clnt_nbp != NULL)
		free(clnt_nbp);
	freeifaddrs(ifp);

#ifdef RPCBIND_DEBUG
	if (debugging)
		fprintf(stderr, "addrmerge: returning %s\n", ret);
#endif
	return ret;
}