This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Re: How to get Ethernet link status?


Here's a code snippet example of how SIOCGIFSTATS can be used.

{
	struct ifaddrs *if_list, *if_info;
	struct ifreq if_request;
	char buffer[INET_ADDRSTRLEN];
	u_short flags;
	int sockfd;
	char *if_description;

	/* Get the interface information */
	if (getifaddrs(&if_list) < 0)
	{
		diag_printf("Failed to get interface information: %s.\n",
			strerror(errno));
		return;
	}
	if (if_list == NULL)
	{
		diag_printf("No network interfaces were found.\n");
		return;
	}
	if_info = if_list;

	/* Get a socket handle for interface queries */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0)
	{
		diag_printf("failed to get socket: %s\n",
			strerror(errno));
	}

	/* Print out the list of interfaces */
	for (if_info = if_list; if_info != NULL; if_info =
if_info->ifa_next)
	{
		/* Only display IPv4 Interfaces */
		if (!if_info->ifa_addr || if_info->ifa_addr->sa_family !=
AF_INET)
			continue;

		/* Figure out what type of interface this is */
		if (strncmp(if_info->ifa_name, "eth", 3) == 0)
			if_description = "Ethernet";
		else if (strncmp(if_info->ifa_name, "lo", 2) == 0)
			if_description = "Loopback";
		else if (strncmp(if_info->ifa_name, "ppp", 3) == 0)
			if_description = "Point-to-Point";
		else
			if_description = "Unknown";

		/* Display the interface information */
		flags = if_info->ifa_flags;
		diag_printf("%s Interface %s\n", if_description,
if_info->ifa_name);
		diag_printf("Interface State: %s, %sRunning\n",
			(flags & IFF_UP)?"Up":"Down", (flags &
IFF_RUNNING)?"":"Not ");

		/* Display the interface type.  Technically, certain
combinations
		 * of these flags are not valid, but print them all out
anyway
		 * to aid debugging.
		 */
		diag_printf("Interface Type: ");
		if (flags & IFF_POINTOPOINT)
			diag_printf("Point-to-Point ");
		if (flags & IFF_LOOPBACK)
			diag_printf("Loopback ");
		if (flags & IFF_BROADCAST)
			diag_printf("Broadcast ");
		if (flags & IFF_MULTICAST)
			diag_printf("Multicast ");

		/* Display address information */
		diag_printf("Netmask: %s\n",
			inet_ntop(AF_INET,
			(const void *)&(((struct sockaddr_in
*)if_info->ifa_netmask)->sin_addr),
			buffer, sizeof(buffer)));
		diag_printf("Local Address: %s\n",
			inet_ntop(AF_INET,
			(const void *)&(((struct sockaddr_in
*)if_info->ifa_addr)->sin_addr),
			buffer, sizeof(buffer)));
		if (flags & IFF_POINTOPOINT)
		{
			diag_printf("Remote Address: %s\n",
				inet_ntop(AF_INET,
				(const void *)&(((struct sockaddr_in
*)if_info->ifa_dstaddr)->sin_addr),
				buffer, sizeof(buffer)));
		}
		if (flags & IFF_BROADCAST)
		{
			diag_printf("Broadcast Address: %s\n",
				inet_ntop(AF_INET,
				(const void *)&(((struct sockaddr_in
*)if_info->ifa_broadaddr)->sin_addr),
				buffer, sizeof(buffer)));
		}

		/* If possible, get the MTU setting */
		strcpy(if_request.ifr_name, if_info->ifa_name);
		if (sockfd >= 0 && ioctl(sockfd, SIOCGIFMTU, &if_request) ==
0)
		{
			diag_printf("Maximum Transmit Unit (MTU): %u",
				if_request.ifr_mtu);
		}

		/* If present, get the hardware address */
		if (sockfd >= 0 && ioctl(sockfd, SIOCGIFHWADDR, &if_request)
== 0)
		{
			diag_printf("Hardware Address: "
				"%02X:%02X:%02X:%02X:%02X:%02X",
				(bit8)if_request.ifr_hwaddr.sa_data[0],
				(bit8)if_request.ifr_hwaddr.sa_data[1],
				(bit8)if_request.ifr_hwaddr.sa_data[2],
				(bit8)if_request.ifr_hwaddr.sa_data[3],
				(bit8)if_request.ifr_hwaddr.sa_data[4],
				(bit8)if_request.ifr_hwaddr.sa_data[5]);
		}

		diag_printf("Other Flags: 0x%04X\n", flags);
#ifdef 	CYGPKG_NET
		/* Get SNMP interface statistics */
		if (sockfd >= 0)
		{
			struct ether_drv_stats eth_stats;

			memset(&eth_stats, 0, sizeof(eth_stats));
			eth_stats.ifreq = if_request;	/* Structure copy */
			if (ioctl(sockfd, SIOCGIFSTATS, &eth_stats) == 0)
			{
				if (eth_stats.speed != 0)
				{
					diag_printf("Speed: ");
					if (eth_stats.speed >= 1000000)
						diag_printf("%uMb",
eth_stats.speed/1000000);
					else
						diag_printf("%u",
eth_stats.speed);
				}
				if ((eth_stats.duplex == 2) ||
(eth_stats.duplex == 3))
				{
					diag_printf("Duplex: %s",
	
(eth_stats.duplex==3)?"Full":"Half");
				}
				diag_printf("TX Packets: %u",
eth_stats.tx_count);
				diag_printf("Good TX Packets: %u",
eth_stats.tx_good);
				diag_printf("TX Carrier Loss: %u",
eth_stats.tx_carrier_loss);
				diag_printf("TX Collisions: %u",
eth_stats.tx_total_collisions);
				diag_printf("RX Packets: %u",
eth_stats.rx_count);
				diag_printf("Good RX Packets: %u",
eth_stats.rx_good);
				diag_printf("RX Packets Delivered: %u",
eth_stats.rx_deliver);
				diag_printf("RX CRC Errors: %u",
eth_stats.rx_crc_errors);
				diag_printf("RX Align Errors: %u",
eth_stats.rx_align_errors);
				diag_printf("RX Resource Errors: %u",
eth_stats.rx_resource_errors + eth_stats.rx_resource);
				diag_printf("RX Overrun Errors: %u",
eth_stats.rx_overrun_errors);
				diag_printf("RX Collisions: %u",
eth_stats.rx_collisions);
				diag_printf("RX Short Frames: %u",
eth_stats.rx_short_frames);
				diag_printf("RX Long Frames: %u",
eth_stats.rx_too_long_frames);
				diag_printf("RX Symbol Errors: %u",
eth_stats.rx_symbol_errors);
			}
		}
#endif

Jay

-----Original Message-----
From: Grant Edwards [mailto:grante@visi.com]
Sent: Friday, December 19, 2008 8:23 AM
To: ecos-discuss@sources.redhat.com
Subject: [ECOS] Re: How to get Ethernet link status?


On 2008-12-17, Grant Edwards <grante@visi.com> wrote:
> On 2008-12-17, Jay Foster <jay@systech.com> wrote:
>
>> You may also be able to use the SIOCGIFSTATS socket ioctl to retrieve the
>> eth_stats (struct ether_drv_stats) structure.  You can get the speed from
>> the speed member and the duplex from the duplex member.  Not all ethernet
>> drivers support the SIOCGIFSTATS ioctl.

I can't figure out what you mean by "ethernet drivers support
the SIOCGIFSTATS ioctl".  My driver suports the
ETH_DRV_GET_IF_STATS control call, but that doesn't seem to be
getting called.  I did find code in the snmp agent that appears
to be using SIOCGIFSTATS, but I have no idea if it actually
works or not  (I still haven't been able to figure out how it's
being used in the SNMP code -- talk about a mess...).

> Bingo! That's what I was looking for. I thought there must be
> an official way to request that info from the driver.

Except I can't get it to work.

I haven't been able to find any real examples or documentation
for SIOCGIFSTATS, nor can I find any connection in the
networking source code between SIOCGIFSTATS and ETH_DRV_GET_IF_STATS.

-- 
Grant Edwards                   grante             Yow! My polyvinyl cowboy
                                  at               wallet was made in Hong
                               visi.com            Kong by Montgomery Clift!


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]