Example #1
0
int
flush_bridgerule(char *brdg, char *member)
{
	int ifs;

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

	if (!is_bridge(ifs, brdg)) {
		printf("%% %s is not a bridge\n", brdg);
		close(ifs);
		return(1);
	}
	if (!is_valid_ifname(member) || is_bridge(ifs, member)) {
		printf("%% %s is not a valid interface\n", member);
		close(ifs);
		return(1);
	}
	bridge_flushrule(ifs, brdg, member);
	close(ifs);

	return(0);
}
Example #2
0
void
bridge_status(void)
{
	struct ifreq ifr;
	struct ifbrparam bp1, bp2;

	if (!is_bridge(name))
		return;

	strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
		return;

	bridge_cfg("\t");

	bridge_list("\t");

	if (aflag && !ifaliases)
		return;

	strlcpy(bp1.ifbrp_name, name, sizeof(bp1.ifbrp_name));
	if (ioctl(s, SIOCBRDGGCACHE, (caddr_t)&bp1) < 0)
		return;

	strlcpy(bp2.ifbrp_name, name, sizeof(bp2.ifbrp_name));
	if (ioctl(s, SIOCBRDGGTO, (caddr_t)&bp2) < 0)
		return;

	printf("\tAddresses (max cache: %u, timeout: %u):\n",
	    bp1.ifbrp_csize, bp2.ifbrp_ctime);

	bridge_addrs("\t\t", 0);
}
Example #3
0
int 
brstatic(char *ifname, int ifs, int argc, char **argv)
{
	int set;

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

	if ((set && argc != 2) || ((!set && argc <1) || (!set && argc > 2))) {
		printf("%% static <mac address> <member>\n");
		printf("%% no static <mac address> [member]\n");
		return(0);
	}

	if (argv[1] && (!is_valid_ifname(argv[1]) || is_bridge(ifs, argv[1])))
	{
		printf("%% invalid member: %s\n", argv[1]);
		return(0);
	}

	if (set)
		bridge_addaddr(ifs, ifname, argv[1], argv[0]);
	else
		bridge_deladdr(ifs, ifname, argv[0]);

	return(0);
}
Example #4
0
int
flush_bridgeall(char *brdg)
{
	int ifs;

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

	if (!is_bridge(ifs, brdg)) {
		printf("%% %s is not a bridge\n", brdg);
		close(ifs);
		return(1);
	}

	bridge_flushall(ifs, brdg);
	close(ifs);

	return(0);
}
Example #5
0
int
brpri(char *ifname, int ifs, int argc, char **argv)   
{
	int set, val;
	const char *errmsg = NULL;
	struct brd *x;
         
	if (NO_ARG(argv[0])) {
		set = 0;
		argv++;
		argc--;
	} else
		set = 1;

	x = (struct brd *) genget(argv[0], (char **)brds, sizeof(struct brd));
	if (x == 0) {
		printf("%% Internal error - Invalid argument %s\n", argv[0]);
		return 0;
	} else if (Ambiguous(x)) {
		printf("%% Internal error - Ambiguous argument %s\n", argv[0]);
		return 0;
	}

	argv++;
	argc--;

	/*
	 * the ifpriority value is ignored for 'no ifpriority' but
	 * we allow it anyways to retain compatibility with the 
	 * set form of this command
	 */
	if ((set && argc != 2) || (!set && (argc < 1 || argc > 2))) {
		printf("%% %s <member> <%s>\n", x->name, x->descr);
		printf("%% no %s <member> [%s]\n", x->name, x->descr);
		return(0);
	}

	if (!is_valid_ifname(argv[0]) || is_bridge(ifs, argv[0]))
	{
		printf("%% invalid member name: %s", argv[0]);
		return(0);
	}

	errno = 0;
	val = strtonum(argv[1], 0, 0xff, &errmsg);
	if (errmsg) {
		printf("%% invalid priority %s: %s\n", argv[1], errmsg);
		return (0);
        }

	switch(x->type) {
	case BRPRI_IFPRIORITY:
		if (set) {
			if (val > 0xff) {
				printf("%% %s exceeds limit\n", x->name);
				return(0);
			}
			bridge_ifprio(ifs, ifname, argv[0], val);
		} else {
			bridge_ifprio(ifs, ifname, argv[0], DEFAULT_IFPRIORITY);
		}	
	break;
	case BRPRI_IFCOST:
		if (set) {
			if (val > 65535) {
				printf("%% %s exceeds limit\n", x->name);
				return(0);
			}
			bridge_ifcost(ifs, ifname, argv[0], val);
		} else {
			bridge_ifcost(ifs, ifname, argv[0], DEFAULT_IFCOST);
		}
	break;
	}
	

	return(0);
}
Example #6
0
int
brport(char *ifname, int ifs, int argc, char **argv)
{
	int set, i;
	struct brc *x;
 
	if (NO_ARG(argv[0])) {
		set = 0;
		argv++;
		argc--;
	} else
		set = 1;

	x = (struct brc *) genget(argv[0], (char **)brps, sizeof(struct brc));
	if (x == 0) {
		printf("%% Internal error - Invalid argument %s\n", argv[0]);
		return 0;
	} else if (Ambiguous(x)) {
		printf("%% Internal error - Ambiguous argument %s\n", argv[0]);
		return 0;
	}

	argv++;
	argc--;

	if (argc == 0) {
		printf("%% %s <if> [if]...\n", x->name);
		printf("%% no %s <if> [if]...\n", x->name);
		return(0);
	}

	for (i = 0; i < argc; i++) {
		if (!is_valid_ifname(argv[i]) ||
		    is_bridge(ifs, argv[i])) {
			printf("%% Invalid interface name %s\n", argv[i]);
			continue;
		}
		switch(x->type) {
		case BRPORT_MEMBER:
			if (set) {
				/* adding a member activates a bridge */
				set_ifflag(ifs, ifname, IFF_UP);
				bridge_add(ifs, ifname, argv[i]);
			} else
				bridge_delete(ifs, ifname, argv[i]);
			break;
		case BRPORT_SPAN:
			if (set)
				bridge_addspan(ifs, ifname, argv[i]);
			else
				bridge_delspan(ifs, ifname, argv[i]);
			break;
		case BRPORT_BLOCKNONIP:
			if (set)
				bridge_ifsetflag(ifs, ifname, argv[i],
				    IFBIF_BLOCKNONIP);
			else
				bridge_ifclrflag(ifs, ifname, argv[i],
				    IFBIF_BLOCKNONIP);
			break;
		case BRPORT_DISCOVER:
			if (set)
				bridge_ifsetflag(ifs, ifname, argv[i],
				    IFBIF_DISCOVER);
			else
				bridge_ifclrflag(ifs, ifname, argv[i],
				    IFBIF_DISCOVER);
			break;
		case BRPORT_LEARN:
			if (set)
				bridge_ifsetflag(ifs, ifname, argv[i],
				    IFBIF_LEARNING);
			else
				bridge_ifclrflag(ifs, ifname, argv[i],
				    IFBIF_LEARNING);
			break;
		case BRPORT_STP:
			if (set)
				bridge_ifsetflag(ifs, ifname, argv[i],
				    IFBIF_STP);
			else
				bridge_ifclrflag(ifs, ifname, argv[i],
				    IFBIF_STP);
			break;
		}
	}

	return(0);
}
Example #7
0
void conf_interfaces(FILE *output, char *only)
{
	FILE *dhcpif, *llfile;
	int ifs, flags, ippntd, br;
#define	LLPREFIX	"/var/run/lladdr"
	char leasefile[sizeof(LEASEPREFIX)+1+IFNAMSIZ];
	char *lladdr, llorig[IFNAMSIZ];
	char llfn[sizeof(LLPREFIX)+IFNAMSIZ];
	char ifdescr[IFDESCRSIZE];

	struct if_nameindex *ifn_list, *ifnp;
	struct ifreq ifr, ifrdesc;
	struct if_data if_data;
	struct vlanreq vreq;

	if ((ifn_list = if_nameindex()) == NULL) {
		printf("%% conf_interfaces: if_nameindex failed\n");
		return;
	}

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

	for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
		strlcpy(ifr.ifr_name, ifnp->if_name, sizeof(ifr.ifr_name));

		if (only && !isprefix(only, ifnp->if_name))
			/* only display interfaces which start with ... */
			continue;
		if (!only) {
			/* interface prefixes to exclude on generic run */
			if (isprefix("pfsync", ifnp->if_name))
				continue;
		}

		if (ioctl(ifs, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
			printf("%% conf: SIOCGIFFLAGS: %s\n", strerror(errno));
			continue;
		}
		flags = ifr.ifr_flags;

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

		/*
		 * Keep in mind that the order in which things are displayed
		 * here is important.  For instance, we want to setup the
		 * vlan tag before setting the IP address since the vlan
		 * must know what parent to inherit the parent interface
		 * flags from before it is brought up.  Another example of
		 * this would be that we need to setup the members on a
		 * bridge before we setup flags on them.
		 */

		/*
		 * set interface/bridge mode
		 */
		if (!(br = is_bridge(ifs, ifnp->if_name)))
			br = 0;
		fprintf(output, "%s %s\n", br ? "bridge" : "interface",
		    ifnp->if_name);

		/*
		 * description, if available
		 * copied straight from ifconfig.c
		 */
		memset(&ifrdesc, 0, sizeof(ifrdesc));
		strlcpy(ifrdesc.ifr_name, ifnp->if_name,
		    sizeof(ifrdesc.ifr_name));
		ifrdesc.ifr_data = (caddr_t)&ifdescr;
		if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 &&
		    strlen(ifrdesc.ifr_data))
			fprintf(output, " description %s\n", ifrdesc.ifr_data);

		/*
		 * print lladdr if necessary
		 */
		if ((lladdr = get_hwdaddr(ifnp->if_name)) != NULL) {
			/* We assume lladdr only useful if we can get_hwdaddr */
			snprintf(llfn, sizeof(llfn), "%s.%s", LLPREFIX,
			    ifnp->if_name);
			if ((llfile = fopen(llfn, "r"))) {
				fgets(llorig, sizeof(llorig), llfile);
				if (strcmp(llorig, lladdr) != 0) {
					fprintf(output, " lladdr %s\n",
					    lladdr);
				}
				fclose(llfile);
			}
		}
		 
		/*
		 * print vlan tag, parent if available.  if a tag is set
		 * but there is no parent, discard.
		 */
		bzero(&vreq, sizeof(struct vlanreq));
		ifr.ifr_data = (caddr_t)&vreq;  

		if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) != -1) {
			struct vlanreq preq;

			bzero(&preq, sizeof(struct vlanreq));

			ifr.ifr_data = (caddr_t)&preq;
			ioctl(ifs, SIOCGETVLANPRIO, (caddr_t)&ifr);

			if(vreq.vlr_tag && (vreq.vlr_parent[0] != '\0')) {
				fprintf(output, " vlan %d parent %s",
				    vreq.vlr_tag, vreq.vlr_parent);
				if(preq.vlr_tag > 0)
					fprintf(output, " priority %d",
					    preq.vlr_tag);
				fprintf(output, "\n");
			}
		}

		conf_intrtlabel(output, ifs, ifnp->if_name);
		conf_intgroup(output, ifs, ifnp->if_name);

		snprintf(leasefile, sizeof(leasefile), "%s.%s",
		    LEASEPREFIX, ifnp->if_name);
		if ((dhcpif = fopen(leasefile, "r"))) {
			fprintf(output, " ip dhcp\n");
			fclose(dhcpif);
			ippntd = 1;
		} else {
			ippntd = conf_ifaddrs(output, ifnp->if_name, flags);
		}

		if (br) {
			conf_brcfg(output, ifs, ifn_list, ifnp->if_name);
		} else {
			char tmp[24];

			conf_media_status(output, ifs, ifnp->if_name);
			conf_ifmetrics(output, ifs, if_data, ifnp->if_name);
			conf_pfsync(output, ifs, ifnp->if_name);
			conf_carp(output, ifs, ifnp->if_name);
			conf_trunk(output, ifs, ifnp->if_name);
			if (timeslot_status(ifs, ifnp->if_name, tmp,
			    sizeof(tmp)) == 1) 
				fprintf(output, " timeslots %s\n", tmp);
			if (conf_dhcrelay(ifnp->if_name, tmp, sizeof(tmp))
			    != NULL)
				fprintf(output, " dhcrelay %s\n", tmp);
		}

		/*
		 * print various flags
		 */
		if (flags & IFF_DEBUG)
			fprintf(output, " debug\n");
		if (flags & (IFF_LINK0|IFF_LINK1|IFF_LINK2)) {
			fprintf(output, " link ");
			if(flags & IFF_LINK0)
				fprintf(output, "0 ");
			if(flags & IFF_LINK1)
				fprintf(output, "1 ");
			if(flags & IFF_LINK2)
				fprintf(output, "2");
			fprintf(output, "\n");
		}
		if (flags & IFF_NOARP)
			fprintf(output, " no arp\n");
		/*
		 * ip X/Y turns the interface up (just like 'no shutdown')
		 * ...but if we never had an ip address set and the interface
		 * is up, we need to save this state explicitly.
		 */
		if (!ippntd && (flags & IFF_UP))
			fprintf(output, " no shutdown\n");
		else if (!(flags & IFF_UP))
			fprintf(output, " shutdown\n");
		fprintf(output, "!\n");
	}
	close(ifs);
	if_freenameindex(ifn_list);
}
Example #8
0
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);
}
Example #9
0
int
intvlan(char *ifname, int ifs, int argc, char **argv)
{
	const char *errmsg = NULL;
	struct ifreq ifr;
	struct vlanreq vreq, preq;
	int set;

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

	argc--;
	argv++;

	if ((set && (argc < 3 || argc > 5)) || (!set && argc > 5) ||
	    argc == 4 ||
	    (argc > 3 && !isprefix(argv[1], "parent")) ||
	    (argc > 5 && !isprefix(argv[3], "priority"))) {
		printf("%% vlan <tag> parent <parent interface> [priority <priority>]\n");
		printf("%% no vlan [tag] [parent <parent interface>] [priority <priority>]\n");
		return 0;
	}

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

	bzero(&vreq, sizeof(vreq));
	bzero(&preq, sizeof(preq));

	ifr.ifr_data = (caddr_t)&vreq;

	if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) == -1) {
		switch(errno) {
		case ENOTTY:
			printf("%% This interface does not support vlan"
			    " tagging\n");
			break;
		default:
			printf("%% intvlan: SIOCGETVLAN: %s\n",
			    strerror(errno));
		}
		return(0);
	}

	if (set) {
		if (!is_valid_ifname(argv[2]) || is_bridge(ifs, argv[2])) {
			printf("%% Invalid vlan parent %s\n", argv[2]);
			return 0;
		}
		strlcpy(vreq.vlr_parent, argv[2], sizeof(vreq.vlr_parent));
		vreq.vlr_tag = strtonum(argv[0], 0, 4096, &errmsg);
		if (errmsg) {
			printf("%% Invalid vlan tag %s: %s", argv[0], errmsg);
			return 0;
		}
		if (vreq.vlr_tag != EVL_VLANOFTAG(vreq.vlr_tag)) {
			printf("%% Invalid vlan tag %s\n", argv[0]);
			return 0;
		}
		if (argc == 5) {
			preq.vlr_tag = strtonum(argv[4], 0, 7, &errmsg);
			if (errmsg) {
				printf("%% Invalid vlan priority %s: %s\n",
				    argv[4], errmsg);
				return 0;
			}
		}
	} else {
		bzero(&vreq.vlr_parent, sizeof(vreq.vlr_parent));
		vreq.vlr_tag = 0;
	}

	if (ioctl(ifs, SIOCSETVLAN, (caddr_t)&ifr) == -1) {
		switch(errno) {
		case EBUSY:
			printf("%% Please disconnect the current vlan parent"
			    " before setting a new one\n");
			return 0;
			break;
		default:
			printf("%% intvlan: SIOCSETVLAN: %s\n",
			    strerror(errno));
			return 0;
		}
	}

	ifr.ifr_data = (caddr_t)&preq;
	if (ioctl(ifs, SIOCSETVLANPRIO, (caddr_t)&ifr) == -1)
		printf("%% intvlan: SIOCSETVLANPRIO: %s\n", strerror(errno));

	return 0;
}
Example #10
0
File: conf.c Project: sthen/nsh
void conf_interfaces(FILE *output, char *only)
{
	int ifs, flags, ippntd, br;
	char *lladdr;
	char ifdescr[IFDESCRSIZE];

	struct if_nameindex *ifn_list, *ifnp;
	struct ifreq ifr, ifrdesc;
	struct if_data if_data;

	if ((ifn_list = if_nameindex()) == NULL) {
		printf("%% conf_interfaces: if_nameindex failed\n");
		return;
	}

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

	for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
		if (only && !isprefix(only, ifnp->if_name))
			/* only display interfaces which start with ... */
			continue;
		if (!only && islateif(ifnp->if_name))
			/* interface prefixes to exclude on generic run */
			continue;

		strlcpy(ifr.ifr_name, ifnp->if_name, sizeof(ifr.ifr_name));

		if (ioctl(ifs, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
			printf("%% conf: SIOCGIFFLAGS: %s\n", strerror(errno));
			continue;
		}
		flags = ifr.ifr_flags;

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

		/* The output order is important! */

		/* set interface/bridge mode */
		if (!(br = is_bridge(ifs, ifnp->if_name)))
			br = 0;
		fprintf(output, "%s %s\n", br ? "bridge" : "interface",
		    ifnp->if_name);

		/*
		 * description, if available
		 * copied straight from ifconfig.c
		 */
		memset(&ifrdesc, 0, sizeof(ifrdesc));
		strlcpy(ifrdesc.ifr_name, ifnp->if_name,
		    sizeof(ifrdesc.ifr_name));
		ifrdesc.ifr_data = (caddr_t)&ifdescr;
		if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 &&
		    strlen(ifrdesc.ifr_data))
			fprintf(output, " description %s\n", ifrdesc.ifr_data);

		if ((lladdr = get_hwdaddr(ifnp->if_name)) != NULL)
			conf_db_single(output, "lladdr", lladdr, ifnp->if_name);
		conf_db_single(output, "rtadvd", NULL, ifnp->if_name);

		conf_vnetid(output, ifs, ifnp->if_name);
		conf_parent(output, ifs, ifnp->if_name);
		conf_rdomain(output, ifs, ifnp->if_name);
		conf_intrtlabel(output, ifs, ifnp->if_name);
		conf_intgroup(output, ifs, ifnp->if_name);
		conf_carp(output, ifs, ifnp->if_name);

		ippntd = conf_ifaddr_dhcp(output, ifnp->if_name, flags);

		if (br) {
			conf_brcfg(output, ifs, ifn_list, ifnp->if_name);
		} else {
			char tmp[24];

			conf_media_status(output, ifs, ifnp->if_name);
			conf_ifmetrics(output, ifs, if_data, ifnp->if_name);
			conf_keepalive(output, ifs, ifnp->if_name);
			conf_pfsync(output, ifs, ifnp->if_name);
			conf_trunk(output, ifs, ifnp->if_name);
			conf_pflow(output, ifs, ifnp->if_name);
			conf_ifxflags(output, ifs, ifnp->if_name);
			if (timeslot_status(ifs, ifnp->if_name, tmp,
			    sizeof(tmp)) == 1) 
				fprintf(output, " timeslots %s\n", tmp);
			if (conf_dhcrelay(ifnp->if_name, tmp, sizeof(tmp))
			    > 0)
				fprintf(output, " dhcrelay %s\n", tmp);
			conf_sppp(output, ifs, ifnp->if_name);
			conf_pppoe(output, ifs, ifnp->if_name);
		}
		conf_ifflags(output, flags, ifnp->if_name, ippntd);
	}
	close(ifs);
	if_freenameindex(ifn_list);
}
Example #11
0
static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n,
                    void *arg)
{
    FILE *fp = arg;
    struct ifinfomsg *ifi = NLMSG_DATA(n);
    struct rtattr * tb[IFLA_MAX + 1];
    int len = n->nlmsg_len;
    char b1[IFNAMSIZ];
    int af_family = ifi->ifi_family;
    bool newlink;
    int br_index;

    if(n->nlmsg_type == NLMSG_DONE)
        return 0;

    len -= NLMSG_LENGTH(sizeof(*ifi));
    if(len < 0)
    {
        return -1;
    }

    if(af_family != AF_BRIDGE && af_family != AF_UNSPEC)
        return 0;

    if(n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
        return 0;

    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);

    /* Check if we got this from bonding */
    if(tb[IFLA_MASTER] && af_family != AF_BRIDGE)
        return 0;

    if(tb[IFLA_IFNAME] == NULL)
    {
        fprintf(stderr, "BUG: nil ifname\n");
        return -1;
    }

    if(n->nlmsg_type == RTM_DELLINK)
        fprintf(fp, "Deleted ");

    fprintf(fp, "%d: %s ", ifi->ifi_index, (char*)RTA_DATA(tb[IFLA_IFNAME]));

    if(tb[IFLA_OPERSTATE])
    {
        int state = *(int*)RTA_DATA(tb[IFLA_OPERSTATE]);
        switch (state)
        {
            case IF_OPER_UNKNOWN:
                fprintf(fp, "Unknown ");
                break;
            case IF_OPER_NOTPRESENT:
                fprintf(fp, "Not Present ");
                break;
            case IF_OPER_DOWN:
                fprintf(fp, "Down ");
                break;
            case IF_OPER_LOWERLAYERDOWN:
                fprintf(fp, "Lowerlayerdown ");
                break;
            case IF_OPER_TESTING:
                fprintf(fp, "Testing ");
                break;
            case IF_OPER_DORMANT:
                fprintf(fp, "Dormant ");
                break;
            case IF_OPER_UP:
                fprintf(fp, "Up ");
                break;
            default:
                fprintf(fp, "State(%d) ", state);
        }
    }

    if(tb[IFLA_MTU])
        fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));

    if(tb[IFLA_MASTER])
    {
        fprintf(fp, "master %s ",
                if_indextoname(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
    }

    if(tb[IFLA_PROTINFO])
    {
        uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]);
        if(state <= BR_STATE_BLOCKING)
            fprintf(fp, "state %s", port_states[state]);
        else
            fprintf(fp, "state (%d)", state);
    }

    fprintf(fp, "\n");
    fflush(fp);

    newlink = (n->nlmsg_type == RTM_NEWLINK);

    if(tb[IFLA_MASTER])
        br_index = *(int*)RTA_DATA(tb[IFLA_MASTER]);
    else if(is_bridge((char*)RTA_DATA(tb[IFLA_IFNAME])))
        br_index = ifi->ifi_index;
    else
        br_index = -1;

    bridge_notify(br_index, ifi->ifi_index, newlink, ifi->ifi_flags);

    return 0;
}
Example #12
0
File: if.c Project: 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);
}
Example #13
0
File: if.c Project: yellowman/nsh
int
intvlan(char *ifname, int ifs, int argc, char **argv)
{
#ifndef SIOCSIFPARENT /* 5.9- */
	const char *errmsg = NULL;
	struct ifreq ifr;
	struct vlanreq vreq;
#endif
	int set;

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

	argc--;
	argv++;

	if ((set && argc != 3) || (!set && argc > 3) ||
	    (argc == 3 && !isprefix(argv[1], "parent"))) {
		printf("%% vlan <tag> parent <parent interface>\n");
		printf("%% no vlan [tag] [parent <parent interface>]\n");
		return 0;
	}

#ifndef SIOCSIFPARENT /* 5.9- */
	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));

	bzero(&vreq, sizeof(vreq));

	ifr.ifr_data = (caddr_t)&vreq;

	if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) == -1) {
		switch(errno) {
		case ENOTTY:
			printf("%% This interface does not support vlan"
			    " tagging\n");
			break;
		default:
			printf("%% intvlan: SIOCGETVLAN: %s\n",
			    strerror(errno));
		}
		return(0);
	}
#endif
	if (set) {
		if (!is_valid_ifname(argv[2]) || is_bridge(ifs, argv[2])) {
			printf("%% Invalid vlan parent %s\n", argv[2]);
			return 0;
		}
#ifndef SIOCSIFPARENT	/* 5.9- */
		strlcpy(vreq.vlr_parent, argv[2], sizeof(vreq.vlr_parent));
		vreq.vlr_tag = strtonum(argv[0], 0, 4095, &errmsg);
		if (errmsg) {
			printf("%% Invalid vlan tag %s: %s", argv[0], errmsg);
			return 0;
		}
		if (vreq.vlr_tag != EVL_VLANOFTAG(vreq.vlr_tag)) {
			printf("%% Invalid vlan tag %s\n", argv[0]);
			return 0;
		}
	} else {
		bzero(&vreq.vlr_parent, sizeof(vreq.vlr_parent));
		vreq.vlr_tag = 0;
#endif
	}

#ifdef SIOCSIFPARENT	/* 6.0+ */
	if (set) {
		char *vnet_argv[] = { "vnetid", argv[0], '\0' };
		char *par_argv[] = { "parent", argv[2], '\0' };

		intparent(ifname, ifs, 2, par_argv);
		intvnetid(ifname, ifs, 2, vnet_argv);
	} else {
		char *vnet_argv[] = { "no", "vnetid" };
		char *par_argv[] = { "no", "parent" };

		intparent(ifname, ifs, 2, par_argv);
		intvnetid(ifname, ifs, 2, vnet_argv);
	}

#else
	if (ioctl(ifs, SIOCSETVLAN, (caddr_t)&ifr) == -1) {
		switch(errno) {
		case EBUSY:
			printf("%% Please disconnect the current vlan parent"
			    " before setting a new one\n");
			return 0;
			break;
		default:
			printf("%% intvlan: SIOCSETVLAN: %s\n",
			    strerror(errno));
			return 0;
		}
	}
#endif

	return 0;
}
Example #14
0
int guess_filesystem(int start_session)
{
    int ret = 0;

    read_super(start_session);

#undef _DEBUG
#ifdef _DEBUG
    /* buffer is defined */
    if (is_cdi())     printf("CD-I, ");
    if (is_cd_rtos()) printf("CD-RTOS, ");
    if (is_isofs())   printf("ISOFS, ");
    if (is_hs())      printf("HS, ");
    if (is_bridge())  printf("BRIDGE, ");
    if (is_xa())      printf("XA, ");
    if (is_cdtv())    printf("CDTV, ");
    puts("");
#endif

    /* filesystem */
    if (is_cdi() && is_cd_rtos() && !is_bridge() && !is_xa()) {
        return FS_INTERACTIVE;
    } else {	/* read sector 0 ONLY, when NO greenbook CD-I !!!! */

        read_super2(start_session);

#ifdef _DEBUG
	/* buffer2 is defined */
	if (is_photocd()) printf("PHOTO CD, ");
	if (is_hfs()) printf("HFS, ");
	if (is_ext2()) printf("EXT2 FS, ");
	puts("");
#endif
        if (is_hs())
	    ret |= FS_HIGH_SIERRA;
	else if (is_isofs()) {
	    if (is_cd_rtos() && is_bridge())
	        ret = FS_ISO_9660_INTERACTIVE;
	    else if (is_hfs())
	        ret = FS_ISO_HFS;
	    else
	        ret = FS_ISO_9660;
	    isofs_size = get_size();

	    read_super4(start_session);

#ifdef _DEBUG
	    /* buffer4 is defined */
	    if (is_bootable()) printf("BOOTABLE, ");
	    puts("");
#endif
	    if (is_bootable())
		ret |= BOOTABLE;

	    if (is_bridge() && is_xa() && is_isofs() && is_cd_rtos()) {
	        read_super5(start_session);

#ifdef _DEBUG
		/* buffer5 is defined */
		if (is_video_cdi()) printf("VIDEO-CDI, ");
		puts("");
#endif
		if (is_video_cdi())
		    ret |= VIDEOCDI;
	    }
	} else if (is_hfs())
	    ret |= FS_HFS;
	else if (is_ext2())
	    ret |= FS_EXT2;
	else {

	    read_super3(start_session);

#ifdef _DEBUG
	    /* buffer3 is defined */
	    if (is_ufs()) printf("UFS, ");
	    puts("");
#endif
	    if (is_ufs())
	        ret |= FS_UFS;
	    else
	        ret |= FS_UNKNOWN;
	}
    }
    /* other checks */
    if (is_xa())
        ret |= XA;
    if (is_photocd())
	ret |= PHOTO_CD;
    if (is_cdtv())
	ret |= CDTV;
    return ret;
}