Esempio n. 1
0
/*
 * Print the status of the interface.  If an address family was
 * specified, show only it; otherwise, show them all.
 */
static void
status(const struct afswtch *afp, const struct sockaddr_dl *sdl,
	struct ifaddrs *ifa)
{
	struct ifaddrs *ift;
	int allfamilies, s;
	struct ifstat ifs;

	if (afp == NULL) {
		allfamilies = 1;
		ifr.ifr_addr.sa_family = AF_LOCAL;
	} else {
		allfamilies = 0;
		ifr.ifr_addr.sa_family =
		    afp->af_af == AF_LINK ? AF_LOCAL : afp->af_af;
	}
	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));

	s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
	if (s < 0)
		err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family);

	printf("%s: ", name);
	printb("flags", ifa->ifa_flags, IFFBITS);
	if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1)
		printf(" metric %d", ifr.ifr_metric);
	if (ioctl(s, SIOCGIFMTU, &ifr) != -1)
		printf(" mtu %d", ifr.ifr_mtu);
	putchar('\n');

	for (;;) {
		if ((descr = reallocf(descr, descrlen)) != NULL) {
			ifr.ifr_buffer.buffer = descr;
			ifr.ifr_buffer.length = descrlen;
			if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) {
				if (ifr.ifr_buffer.buffer == descr) {
					if (strlen(descr) > 0)
						printf("\tdescription: %s\n",
						    descr);
				} else if (ifr.ifr_buffer.length > descrlen) {
					descrlen = ifr.ifr_buffer.length;
					continue;
				}
			}
		} else
			warn("unable to allocate memory for interface"
			    "description");
		break;
	}

	if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
		if (ifr.ifr_curcap != 0) {
			printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
			putchar('\n');
		}
		if (supmedia && ifr.ifr_reqcap != 0) {
			printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS);
			putchar('\n');
		}
	}

	tunnel_status(s);

	for (ift = ifa; ift != NULL; ift = ift->ifa_next) {
		if (ift->ifa_addr == NULL)
			continue;
		if (strcmp(ifa->ifa_name, ift->ifa_name) != 0)
			continue;
		if (allfamilies) {
			const struct afswtch *p;
			p = af_getbyfamily(ift->ifa_addr->sa_family);
			if (p != NULL && p->af_status != NULL)
				p->af_status(s, ift);
		} else if (afp->af_af == ift->ifa_addr->sa_family)
			afp->af_status(s, ift);
	}
#if 0
	if (allfamilies || afp->af_af == AF_LINK) {
		const struct afswtch *lafp;

		/*
		 * Hack; the link level address is received separately
		 * from the routing information so any address is not
		 * handled above.  Cobble together an entry and invoke
		 * the status method specially.
		 */
		lafp = af_getbyname("lladdr");
		if (lafp != NULL) {
			info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl;
			lafp->af_status(s, &info);
		}
	}
#endif
	if (allfamilies)
		af_other_status(s);
	else if (afp->af_other_status != NULL)
		afp->af_other_status(s);

	strncpy(ifs.ifs_name, name, sizeof ifs.ifs_name);
	if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 
		printf("%s", ifs.ascii);

	close(s);
	return;
}
Esempio n. 2
0
/*
 * Print the status of the interface.  If an address family was
 * specified, show only it; otherwise, show them all.
 */
static void
status(const struct afswtch *afp, int addrcount, struct	sockaddr_dl *sdl,
       struct if_msghdr *ifm, struct ifa_msghdr *ifam)
{
    struct	rt_addrinfo info;
    int allfamilies, s;
    struct ifstat ifs;

    if (afp == NULL) {
        allfamilies = 1;
        afp = af_getbyname("inet");
    } else
        allfamilies = 0;

    ifr.ifr_addr.sa_family = afp->af_af == AF_LINK ? AF_INET : afp->af_af;
    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));

    s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);
    if (s < 0)
        err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family);

    printf("%s: ", name);
    printb("flags", flags, IFFBITS);
    if (ifm->ifm_data.ifi_metric)
        printf(" metric %ld", ifm->ifm_data.ifi_metric);
    if (ifm->ifm_data.ifi_mtu)
        printf(" mtu %ld", ifm->ifm_data.ifi_mtu);
    putchar('\n');

    if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
        if (ifr.ifr_curcap != 0) {
            printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
            putchar('\n');
        }
        if (supmedia && ifr.ifr_reqcap != 0) {
            printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS);
            putchar('\n');
        }
    }

    tunnel_status(s);

    while (addrcount > 0) {
        info.rti_addrs = ifam->ifam_addrs;
        /* Expand the compacted addresses */
        rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam,
                  &info);

        if (allfamilies) {
            const struct afswtch *p;
            p = af_getbyfamily(info.rti_info[RTAX_IFA]->sa_family);
            if (p != NULL && p->af_status != NULL)
                p->af_status(s, &info);
        } else if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family)
            afp->af_status(s, &info);
        addrcount--;
        ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
    }
    if (allfamilies || afp->af_af == AF_LINK) {
        const struct afswtch *lafp;

        /*
         * Hack; the link level address is received separately
         * from the routing information so any address is not
         * handled above.  Cobble together an entry and invoke
         * the status method specially.
         */
        lafp = af_getbyname("lladdr");
        if (lafp != NULL) {
            info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl;
            lafp->af_status(s, &info);
        }
    }
    if (allfamilies)
        af_other_status(s);
    else if (afp->af_other_status != NULL)
        afp->af_other_status(s);

    strncpy(ifs.ifs_name, name, sizeof ifs.ifs_name);
    if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0)
        printf("%s", ifs.ascii);

    if (flags & IFF_POLLING) {
        if (ioctl(s, SIOCGIFPOLLCPU, &ifr) == 0 && ifr.ifr_pollcpu >= 0)
            printf("\tpollcpu: %d\n", ifr.ifr_pollcpu);
    }

    close(s);
    return;
}