This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
RE: Re: How to get Ethernet link status?
- From: Jay Foster <jay at systech dot com>
- To: 'Grant Edwards' <grante at visi dot com>, ecos-discuss at sources dot redhat dot com
- Date: Fri, 19 Dec 2008 08:54:04 -0800
- Subject: RE: [ECOS] 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(ð_stats, 0, sizeof(eth_stats));
eth_stats.ifreq = if_request; /* Structure copy */
if (ioctl(sockfd, SIOCGIFSTATS, ð_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