コード例 #1
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/*
 * Check to see whether the interface could be started.  If the IFF_RUNNING
 * flag is set, then we're in good shape.  Otherwise, wireless interfaces are
 * special: we'll attempt to connect to an Access Point as part of the start-up
 * procedure, and IFF_RUNNING won't be present until that's done, so assume
 * that all wireless interfaces are good to go.  This is just an optimization;
 * we could start everything.
 */
static boolean_t
is_startable(struct interface *ifp)
{
	ifp->if_flags = get_ifflags(ifp->if_name, ifp->if_family);
	if (ifp->if_flags & IFF_RUNNING)
		return (B_TRUE);
	return (ifp->if_type == IF_WIRELESS);
}
コード例 #2
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/*
 * Returns the interface structure upon success.  Returns NULL and sets
 * errno upon error.
 */
struct interface *
add_interface(sa_family_t family, const char *name, uint64_t flags)
{
	struct interface *i;
	libnwam_interface_type_t iftype;

	if (name == NULL)
		return (NULL);

	dprintf("add_interface: found interface %s", name);
	if (family == AF_INET6) {
		/*
		 * we don't track IPv6 interfaces separately from their
		 * v4 counterparts; a link either has v4 only, or both
		 * v4 and v6, so we only maintain a v4 interface struct.
		 */
		dprintf("not adding v6 interface for %s", name);
		return (NULL);
	} else if (family != AF_INET) {
		/*
		 * the classic "shouldn't happen"...
		 */
		dprintf("not adding af %d interface for %s", family, name);
		return (NULL);
	}

	if ((iftype = find_if_type(name)) == IF_TUN) {
		/*
		 * for now, we're ignoring tunnel interfaces (we expect
		 * them to be entirely manipulated by higher layer profile
		 * activation/deactivation scripts)
		 */
		dprintf("%s is a tunnel interface; ignoring", name);
		return (NULL);
	}

	if ((i = calloc(1, sizeof (*i))) == NULL) {
		dprintf("add_interface: malloc failed");
		return (NULL);
	}

	(void) strlcpy(i->if_name, name, sizeof (i->if_name));
	i->if_family = family;
	i->if_type = iftype;
	i->if_flags = flags == 0 ? get_ifflags(name, family) : flags;

	dprintf("added interface %s of type %s af %d; is %savailable",
	    i->if_name, if_type_str(i->if_type), i->if_family,
	    (i->if_flags & IFF_RUNNING) ? "" : "not ");

	interface_list_insert(i);

	if (iftype == IF_WIRELESS)
		add_wireless_if(name);

	return (i);
}
コード例 #3
0
ファイル: if.c プロジェクト: northshorenetworks/NSWall
int
intflags(char *ifname, int ifs, int argc, char **argv)
{
	int set, value, flags;

	if (NO_ARG(argv[0])) {
		set = 0;
		argv++;
		argc--;
	} else
		set = 1;

	if (isprefix(argv[0], "debug")) {
		/* debug */
		value = IFF_DEBUG;
	} else if (isprefix(argv[0], "shutdown")) {
		/* shutdown */
		value = -IFF_UP;
	} else if (isprefix(argv[0], "arp")) {
		/* arp */
		value = -IFF_NOARP;
	} else {
		printf("%% intflags: Internal error\n");
		return(0);
	}

	flags = get_ifflags(ifname, ifs);
	if (value < 0) {
		/*
		 * Idea from ifconfig.  If value is negative then
		 * we just reverse the operation. (e.g. 'shutdown' is
		 * the opposite of the IFF_UP flag)
		 */
		if (set) {
			value = -value;
			flags &= ~value;
		} else {
			value = -value;
			flags |= value;
		}
	} else if (value > 0) {
		if (set)
			flags |= value;
		else
			flags &= ~value;
	} else {
		printf("%% intflags: value internal error\n");
	}
	set_ifflags(ifname, ifs, flags);
	return(0);
}
コード例 #4
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/* ARGSUSED */
static int
do_unplumb_if(icfg_if_t *intf, void *arg)
{
	uint64_t flags = get_ifflags(intf->if_name, intf->if_protocol);

	/* We don't touch loopback interface. */
	if (flags & IFF_LOOPBACK)
		return (ICFG_SUCCESS);

	(void) start_child(IFCONFIG, intf->if_name,
	    intf->if_protocol == AF_INET6 ? "inet6" : "inet", "unplumb", NULL);

	return (ICFG_SUCCESS);
}
コード例 #5
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/* ARGSUSED */
static int
do_add_interface(icfg_if_t *intf, void *arg)
{
	uint64_t flags = get_ifflags(intf->if_name, intf->if_protocol);

	/* We don't touch loopback interface. */
	if (flags & IFF_LOOPBACK)
		return (ICFG_SUCCESS);

	/* If adding fails, just ignore that interface... */
	(void) add_interface(intf->if_protocol, intf->if_name, flags);

	return (ICFG_SUCCESS);
}
コード例 #6
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/*
 * Called only in the main thread
 *
 * For IPv6, unplumbing the link local interface causes dhcp and ndpd to remove
 * other addresses they have added.  We watch for routing socket events on the
 * IPv4 interface, which is always enabled, so no need to keep IPv6 around on a
 * switch.
 */
void
clear_cached_address(const char *ifname)
{
	struct interface *ifp;
	uint64_t ifflags;

	if ((ifp = get_interface(ifname)) == NULL) {
		dprintf("clear_cached_address: can't find interface struct "
		    "for %s", ifname);
		(void) start_child(IFCONFIG, ifname, "inet6", "unplumb", NULL);
		return;
	}
	if (ifp->if_v6onlink)
		(void) start_child(IFCONFIG, ifname, "inet6", "unplumb", NULL);
	ifflags = get_ifflags(ifname, AF_INET);
	if ((ifflags & IFF_UP) && !(ifflags & IFF_RUNNING))
		zero_out_v4addr(ifname);
	ifp->if_ipv4addr = INADDR_ANY;
	ifp->if_lflags &= ~IF_DHCPFLAGS;
}
コード例 #7
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/*
 * Walker function used to start info gathering of each interface.  Caller
 * holds ifs_lock.
 */
void
start_if_info_collect(struct interface *ifp, void *arg)
{
	int retv;
	pthread_attr_t attr;

	/*
	 * In certain cases we need to refresh the cached flags value as
	 * it may be stale.  Notably, we can miss a DL_NOTE_LINK_DOWN
	 * event after we initialize interfaces before the routing thread
	 * is launched.
	 */
	if (arg != NULL)
		ifp->if_flags = get_ifflags(ifp->if_name, ifp->if_family);

	/*
	 * Only if the cable of the wired interface is
	 * plugged in, start gathering info from it.
	 */
	if (!is_startable(ifp)) {
		dprintf("not gathering info on %s; not running", ifp->if_name);
		return;
	}

	/*
	 * This is a "fresh start" for the interface, so clear old DHCP flags.
	 */
	ifp->if_lflags &= ~IF_DHCPFLAGS;

	(void) pthread_attr_init(&attr);
	(void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if ((retv = pthread_create(&ifp->if_thr, &attr, gather_interface_info,
	    ifp)) != 0) {
		syslog(LOG_ERR, "create interface gathering thread: %s",
		    strerror(retv));
		exit(EXIT_FAILURE);
	} else {
		dprintf("interface info thread for %s: %d", ifp->if_name,
		    ifp->if_thr);
	}
}
コード例 #8
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/* Called only in the main thread */
void
takedowninterface(const char *ifname, libnwam_diag_cause_t cause)
{
	uint64_t flags;
	struct interface *ifp;

	dprintf("takedowninterface(%s, %d)", ifname, (int)cause);

	if ((ifp = get_interface(ifname)) == NULL) {
		dprintf("takedowninterface: can't find interface struct for %s",
		    ifname);
	}

	flags = get_ifflags(ifname, AF_INET);
	if (flags & IFF_DHCPRUNNING) {
		/*
		 * We generally prefer doing a release, as that tells the
		 * server that it can relinquish the lease, whereas drop is
		 * just a client-side operation.  But if we never came up,
		 * release will fail, because dhcpagent does not allow an
		 * interface without a lease to release, so we have to drop in
		 * that case.  So try release first, then fall back to drop.
		 */
		if (start_child(IFCONFIG, ifname, "dhcp", "wait", "2",
		    "release", NULL) != 0) {
			(void) start_child(IFCONFIG, ifname, "dhcp", "wait",
			    "2", "drop", NULL);
		}
	} else {
		if (flags & IFF_UP)
			(void) start_child(IFCONFIG, ifname, "down", NULL);
		/* need to unset a statically configured addr */
		(void) start_child(IFCONFIG, ifname, "0.0.0.0", "netmask",
		    "0", "broadcast", "0.0.0.0", NULL);
	}

	if (ifp == NULL || ifp->if_v6onlink) {
		/*
		 * Unplumbing the link local interface causes dhcp and ndpd to
		 * remove other addresses they have added.
		 */
		(void) start_child(IFCONFIG, ifname, "inet6", "unplumb", NULL);
	}

	if (ifp == NULL || ifp->if_up_attempted)
		report_interface_down(ifname, cause);

	if (ifp != NULL) {
		/* We're no longer expecting the interface to be up */
		ifp->if_flags = flags & ~IFF_UP;
		if (ifp->if_type == IF_WIRELESS) {
			/* and if it's wireless, it's not running, either */
			ifp->if_flags &= ~IFF_RUNNING;
			disconnect_wlan(ifp->if_name);
		}
		dprintf("takedown interface, zero cached ip address");
		ifp->if_lflags &= ~IF_DHCPSTARTED & ~IF_DHCPACQUIRED;
		ifp->if_ipv4addr = INADDR_ANY;
		ifp->if_up_attempted = B_FALSE;
	}
}
コード例 #9
0
ファイル: interface.c プロジェクト: CoryXie/opensolaris
/*
 * Returns SUCCESS if the interface is successfully brought up,
 * FAILURE if bringup fails, or WAITING if we'll need to wait on the GUI to run.
 * Called only in the main thread or a thread holding machine_lock.
 */
return_vals_t
bringupinterface(const char *ifname, const char *host, const char *ipv6addr,
    boolean_t ipv6onlink)
{
	struct interface *intf;

	intf = get_interface(ifname);
	if (intf == NULL) {
		syslog(LOG_ERR, "could not bring up interface %s: not in list",
		    ifname);
		return (FAILURE);
	}

	/* check current state; no point going on if flags are 0 */
	if ((intf->if_flags = get_ifflags(ifname, intf->if_family)) == 0) {
		dprintf("bringupinterface(%s): get_ifflags() returned 0",
		    ifname);
		return (FAILURE);
	}

	if (intf->if_type == IF_WIRELESS) {
		switch (handle_wireless_lan(ifname)) {
		case WAITING:
			intf->if_up_attempted = B_TRUE;
			return (WAITING);
		case FAILURE:
			syslog(LOG_INFO, "Could not connect to any WLAN, not "
			    "bringing %s up", ifname);
			return (FAILURE);
		}
	}
	intf->if_up_attempted = B_TRUE;

	/* physical level must now be up; bail out if not */
	intf->if_flags = get_ifflags(ifname, intf->if_family);
	if (!(intf->if_flags & IFF_RUNNING)) {
		dprintf("bringupinterface(%s): physical layer down", ifname);
		return (FAILURE);
	}

	/*
	 * If the link layer profile says that we want v6 then plumb it and
	 * bring it up; if there's a static address, configure it as well.
	 */
	if (ipv6onlink) {
		dprintf("bringupinterface: configuring ipv6");
		(void) start_child(IFCONFIG, ifname, "inet6", "plumb", "up",
		    NULL);
		if (ipv6addr) {
			(void) start_child(IFCONFIG, ifname, "inet6", "addif",
			    ipv6addr, "up", NULL);
		}
	}
	intf->if_v6onlink = ipv6onlink;

	if (strcmp(host, "dhcp") == 0) {
		start_dhcp(intf);
	} else {
		(void) start_child(IFCONFIG, ifname, host, NULL);
		(void) start_child(IFCONFIG, ifname, "up", NULL);
	}

	syslog(LOG_DEBUG, "brought up %s", ifname);

	return (SUCCESS);
}
コード例 #10
0
ファイル: if.c プロジェクト: northshorenetworks/NSWall
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, sin2, sin3;
	struct timeval tv;
	struct vlanreq vreq;

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

	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 1;
		}
		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_lastchange.tv_sec) {
		gettimeofday(&tv, (struct timezone *)0);
		c = difftime(tv.tv_sec, if_lastchange.tv_sec);
		days = c / SECSPERDAY;
		c %= SECSPERDAY;
		hours = c / SECSPERHOUR;
		c %= SECSPERHOUR;
		mins = c / SECSPERMIN;
		c %= SECSPERMIN;
		printf(" (last change ");
		if (days)
			printf("%id ", days);
		printf("%02i:%02i:%02i)", hours, mins, c);
	}

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

	type = iftype(if_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");

	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;

		if (ifa->ifa_addr->sa_family != AF_INET)
			continue;

		memcpy(&sin, ifa->ifa_addr, sizeof(struct sockaddr_in));
		memcpy(&sin2, ifa->ifa_netmask, sizeof(struct sockaddr_in));

		if (sin.sin_addr.s_addr == 0 || sin2.sin_addr.s_addr == 0)
			continue;

		if (!ippntd)
			printf("  Internet address");

		printf("%s %s", ippntd ? "," : "",
		    netname4(sin.sin_addr.s_addr, &sin2));

		ippntd = 1;

		if (flags & IFF_POINTOPOINT) {
			memcpy(&sin3, ifa->ifa_dstaddr,
			    sizeof(struct sockaddr_in));
			printf(" (Destination %s)", inet_ntoa(sin3.sin_addr));
		} else if (flags & IFF_BROADCAST) {
			memcpy(&sin3, ifa->ifa_broadaddr,
			    sizeof(struct sockaddr_in));
			/*
			 * 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(sin3.sin_addr.s_addr) !=
			    in4_brdaddr(sin.sin_addr.s_addr,
			    sin2.sin_addr.s_addr))
				printf(" (Broadcast %s)",
				    inet_ntoa(sin3.sin_addr));
		}
	}

	if (ippntd) {
		ippntd = 0;
		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\n",
			    tmp_str, tmp_str2);
		if ((carp = carp_state(ifs, ifname)) != NULL)
			printf("  CARP state %s\n", carp);
		/*
		 * Display MTU, line rate, and ALTQ token rate info
		 * (if available)
		 */
		printf("  MTU %u bytes", if_mtu);
		if (if_baudrate)
			printf(", Line Rate %qu %s\n",
			    MBPS(if_baudrate) ? MBPS(if_baudrate) :
			    if_baudrate / 1000,
			    MBPS(if_baudrate) ? "Mbps" : "Kbps");
		else
			printf("\n");
 
		memset(&vreq, 0, sizeof(struct vlanreq));
		ifr.ifr_data = (caddr_t)&vreq;

		if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) != -1)
			if(vreq.vlr_tag || (vreq.vlr_parent[0] != '\0'))
				printf("  802.1Q vlan tag %d, parent %s\n",
				    vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ?
				    "<none>" : vreq.vlr_parent);
	}

	if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != NULL) {
		printf("  SSID %s", tmp_str);
		if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != NULL)
			printf(", key %s", tmp_str);
		if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str),
		    POWERSAVE) != NULL))
			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_ipackets, if_ibytes, if_ierrors, if_iqdrops);
	printf("  %qu packets output, %qu bytes, %qu errors, %qu unsupported\n",
	    if_opackets, if_obytes, if_oerrors, if_noproto);
	if (if_ibytes && if_ipackets && (if_ibytes / if_ipackets) >= ETHERMIN) {
		/* < ETHERMIN means byte counter probably rolled over */
		printf("  %qu input", if_ibytes / if_ipackets);
		pntd = 1;
	} else
		pntd = 0;
	if (if_obytes && if_opackets && (if_obytes / if_opackets) >= ETHERMIN) {
		/* < ETHERMIN means byte counter probably rolled over */
		printf("%s%qu output", pntd ? ", " : "  ",
		    if_obytes / if_opackets);
		pntd = 1;
	}
	if (pntd)
		printf(" (average bytes/packet)\n");

	switch(if_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_collisions);
		break;
	default:
		break;
	}

	if(verbose) {
		if (flags) {
			printf("  Flags:\n    ");
			bprintf(stdout, flags, ifnetflags);
			printf("\n");
		}
		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);
}
コード例 #11
0
ファイル: if.c プロジェクト: northshorenetworks/NSWall
int
intip(char *ifname, int ifs, int argc, char **argv)
{
	int set, alias, flags, argcmax;
	ip_t ip;
	struct in_addr destbcast;
	struct ifaliasreq addreq, ridreq;
	struct sockaddr_in *sin;
	char  *msg, *cmdname;

	memset(&addreq, 0, sizeof(addreq));
	memset(&ridreq, 0, sizeof(ridreq));

	if (NO_ARG(argv[0])) {
		set = 0;
		argc--;
		argv++;
	} else
		set = 1;

	/*
	 * We use this function for ip and alias setup since they are
	 * the same thing.
	 */
	if (isprefix(argv[0], "alias")) {
		alias = 1;
		cmdname = "alias";
	} else if (isprefix(argv[0], "ip")) {
		alias = 0;
		cmdname = "ip";
	} else {
		printf("%% intip: Internal error\n");
		return 0;
	}

	argc--;
	argv++;

	flags = get_ifflags(ifname, ifs);
	if (flags & IFF_POINTOPOINT) {
		argcmax = 2;
		msg = "destination";
	} else if (flags & IFF_BROADCAST) {
		argcmax = 2;
		msg = "broadcast";
	} else {
		argcmax = 1;
		msg = NULL;
	}

	if (argc < 1 || argc > argcmax) {
		printf("%% %s <address>/<bits> %s%s%s\n", cmdname,
		    msg ? "[" : "", msg ? msg : "", msg ? "]" : "");
		printf("%% %s <address>/<netmask> %s%s%s\n", cmdname,
		    msg ? "[" : "", msg ? msg : "", msg ? "]" : "");
		printf("%% no %s <address>[/bits]\n", cmdname);
		printf("%% no %s <address>[/netmask]\n", cmdname);
		return(0);
	}

	/* ignore 'address' keyword, don't print error */
	if (isprefix(argv[0], "address")) {
		argc--;
		argv++;
	}

	if (isprefix(argv[0], "dhcp")) {
		char *args[] = { PKILL, "dhclient", ifname, '\0' };
		char leasefile[sizeof(LEASEPREFIX)+1+IFNAMSIZ];

		if (set)
			cmdarg(DHCLIENT, ifname);
		else {
			cmdargs(PKILL, args);
			snprintf(leasefile, sizeof(leasefile), "%s.%s",
			    LEASEPREFIX, ifname);
			rmtemp(leasefile);
		}
		return(0);
	}

	ip = parse_ip(argv[0], NO_NETMASK);

	if (ip.family == 0)
		/* bad IP specified */
		return(0);

	if (ip.bitlen == -1) {
		printf("%% Netmask not specified\n");
		return(0);
	}
	
	if (argc == 2)
		if (!inet_aton(argv[1], &destbcast)) {
			printf("%% Invalid %s address\n", msg);
			return(0);
		}
	
	strlcpy(addreq.ifra_name, ifname, sizeof(addreq.ifra_name));
	strlcpy(ridreq.ifra_name, ifname, sizeof(ridreq.ifra_name));

	if (!set) {
		sin = (struct sockaddr_in *)&ridreq.ifra_addr;
		sin->sin_len = sizeof(ridreq.ifra_addr);
		sin->sin_family = AF_INET;
		sin->sin_addr.s_addr = ip.addr.sin.s_addr;
	}

	if (!alias || !set) {
		/*
		 * Here we remove the top IP on the interface before we
		 * might add another one, or we delete the specified IP.
		 */
		if (ioctl(ifs, SIOCDIFADDR, &ridreq) < 0)
			if (!set)
				printf("%% intip: SIOCDIFADDR: %s\n",
				    strerror(errno));
	}

	if (set) {
		sin = (struct sockaddr_in *)&addreq.ifra_addr;
		sin->sin_family = AF_INET;
		sin->sin_len = sizeof(addreq.ifra_addr);
		sin->sin_addr.s_addr = ip.addr.sin.s_addr;
		sin = (struct sockaddr_in *)&addreq.ifra_mask;
		sin->sin_family = AF_INET;
		sin->sin_len = sizeof(addreq.ifra_mask);
		sin->sin_addr.s_addr = htonl(0xffffffff << (32 - ip.bitlen));
		if (argc == 2) {
			sin = (struct sockaddr_in *)&addreq.ifra_dstaddr;
			sin->sin_family = AF_INET;
			sin->sin_len = sizeof(addreq.ifra_dstaddr);
			sin->sin_addr.s_addr = destbcast.s_addr;
		}
		if (ioctl(ifs, SIOCAIFADDR, &addreq) < 0)
			printf("%% intip: SIOCAIFADDR: %s\n", strerror(errno));
	}

	return(0);
}
コード例 #12
0
ファイル: if.c プロジェクト: northshorenetworks/NSWall
int
intlink(char *ifname, int ifs, int argc, char **argv)
{
	const char *errmsg = NULL;
	int set, i, flags, value = 0;

	if (NO_ARG(argv[0])) {
		set = 0;
		argv++;
		argc--;
	} else
		set = 1;

	argv++;
	argc--;

	if ((set && argc < 1) || argc > 3) {
		printf("%% link <012>\n");
		printf("%% no link [012]\n");
		return(0);
	}

	flags = get_ifflags(ifname, ifs);

	if (!set && argc == 0) {
		/*
		 * just 'no link' was specified.  so we remove all flags
		 */
		flags &= ~IFF_LINK0 & ~IFF_LINK1 & ~IFF_LINK2;
	} else 
	for (i = 0; i < argc; i++) {
		int a;

		a = strtonum(argv[i], 0, 2, &errmsg);
		if (errmsg) {
			printf("%% Invalid link flag %s: %s\n", argv[i],
			    errmsg);
			return(0);
		}
		switch(a) {
		case 0:
			value = IFF_LINK0;
			break;
		case 1:
			value = IFF_LINK1;
			break;
		case 2:
			value = IFF_LINK2;
			break;
		}

		if (set)
			flags |= value;
		else
			flags &= ~value;
	}

	set_ifflags(ifname, ifs, flags);

	return(0);
}
コード例 #13
0
ファイル: if.c プロジェクト: 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);
}
コード例 #14
0
ファイル: if.c プロジェクト: yellowman/nsh
int
intip(char *ifname, int ifs, int argc, char **argv)
{
	int s, set, flags, argcmax;
	char *msg, *cmdname;
	ip_t ip;
	/* ipv4 structures */
	struct in_addr in4dest;
	struct ifaliasreq ip4req;
	/* ipv6 structures */
	struct in6_addr in6dest;
	struct in6_aliasreq ip6req;

	if (NO_ARG(argv[0])) {
		set = 0;
		argc--;
		argv++;
	} else
		set = 1;

	/*
	 * We use this function for ip and alias setup since they are
	 * the same thing.
	 */
	if (isprefix(argv[0], "alias")) {
		cmdname = "alias";
	} else if (isprefix(argv[0], "ip")) {
		cmdname = "ip";
	} else {
		printf("%% intip: Internal error\n");
		return 0;
	}

	argc--;
	argv++;

	flags = get_ifflags(ifname, ifs);
	if (flags & IFF_POINTOPOINT) {
		argcmax = 2;
		msg = "destination";
	} else if (flags & IFF_BROADCAST) {
		argcmax = 2;
		msg = "broadcast";
	} else {
		argcmax = 1;
		msg = NULL;
	}

	if (argc < 1 || argc > argcmax) {
		printf("%% %s <address>/<bits> %s%s%s\n", cmdname,
		    msg ? "[" : "", msg ? msg : "", msg ? "]" : "");
		printf("%% %s <address>/<netmask> %s%s%s\n", cmdname,
		    msg ? "[" : "", msg ? msg : "", msg ? "]" : "");
		printf("%% no %s <address>[/bits]\n", cmdname);
		printf("%% no %s <address>[/netmask]\n", cmdname);
		return(0);
	}

	/* ignore 'address' keyword, don't print error */
	if (isprefix(argv[0], "address")) {
		argc--;
		argv++;
	}

	if (isprefix(argv[0], "dhcp")) {
		char *args[] = { PKILL, "dhclient", ifname, '\0' };
		char *args_set[] = { DHCLIENT, ifname, '\0' };
		char leasefile[sizeof(LEASEPREFIX)+1+IFNAMSIZ];

		if (set)
			cmdargs(DHCLIENT, args_set);
		else {
			cmdargs(PKILL, args);
			snprintf(leasefile, sizeof(leasefile), "%s.%s",
			    LEASEPREFIX, ifname);
			rmtemp(leasefile);
		}
		return(0);
	}

	memset(&ip, 0, sizeof(ip));
	parse_ip_pfx(argv[0], NO_NETMASK, &ip);

	if (ip.family == 0)
		/* bad IP specified */
		return(0);

	if (set && !(flags & IFF_POINTOPOINT) && ip.bitlen == -1) {
		printf("%% Netmask not specified\n");
		return(0);
	}
	
	if (ip.bitlen == -1) {
		/*
		 * No netmask specified, set the field at 0.
		 * The kernel mostly ignores netmask for PTP interfaces,
		 * but won't allow anything less than a /128 for an IPv6
		 * PTP interface.
		 */
		if (!(flags & IFF_POINTOPOINT))
			ip.bitlen = 0;
		else if (ip.family == AF_INET)
			ip.bitlen = 32;
		else if (ip.family == AF_INET6)
			ip.bitlen = 128;
	}

	switch(ip.family) {
	case AF_INET:
		memset(&in4dest, 0, sizeof(in4dest));
		if (argc == 2 && !inet_pton(AF_INET, argv[1], &in4dest)) {
			printf("%% Invalid %s address\n", msg);
			return(0);
		}
		memset(&ip4req, 0, sizeof(ip4req));
		pack_ifaliasreq(&ip4req, &ip, &in4dest, ifname);
		/* do it */
		if (ioctl(ifs, set ? SIOCAIFADDR : SIOCDIFADDR, &ip4req) < 0)
			printf("%% intip: SIOC%sIFADDR: %s\n", set ? "A" : "D",
			    strerror(errno));
		break;
	case AF_INET6:
		memset(&in6dest, 0, sizeof(in6dest));
		if (argc == 2 && parse_ipv6(argv[1], &in6dest) != 0) {
			printf("%% Invalid destination address %s\n", argv[1]);
			return(0);
		}
		memset(&ip6req, 0, sizeof(ip6req));
		pack_in6aliasreq(&ip6req, &ip, &in6dest, ifname);
		/* get inet6 socket */
		s = socket(PF_INET6, SOCK_DGRAM, 0);
		if (s < 0) {
			printf("%% socket failed: %s\n", strerror(errno));
			return(0);
		}
		/* turn on inet6 */
		addaf(ifname, AF_INET6, ifs);
		/* do it */
		if (ioctl(s, set ? SIOCAIFADDR_IN6 : SIOCDIFADDR_IN6, &ip6req)
		    < 0) {
			if (!set && errno == EADDRNOTAVAIL)
				printf("%% IP address not found on %s\n",
				    ifname);
			else
				printf("%% intip: SIOC%sIFADDR_IN6: %s\n",
				    set ? "A" : "D", strerror(errno));
		} else {
			ipv6ll_db_store(
			    (struct sockaddr_in6 *)&ip6req.ifra_addr,
			    (struct sockaddr_in6 *)&ip6req.ifra_prefixmask,
			    set ? DB_X_ENABLE : DB_X_REMOVE, ifname);
		}
		close(s);
		break;
	default:
		printf("%% unknown address family: %d\n", ip.family);
		break;
	}
	return(0);
}