需要在ETH的驱动中实现struct ethtool_ops里的get_link函数指针
#include
#include
#include
#include
#include
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned char u8;
#include
#include
int detect_mii(int skfd, char *ifname)
{
struct ifreq ifr;
u16 *data, mii_val;
unsigned phy_id;
/* Get the vitals from the interface. */
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0)
{
fprintf(stderr, "SIOCGMIIPHY on %s failed: %s\n", ifname,
strerror(errno));
(void) close(skfd);
return 2;
}
data = (u16 *)(&ifr.ifr_data);
phy_id = data[0];
data[1] = 1;
if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0)
{
fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
strerror(errno));
return 2;
}
mii_val = data[3];
return(((mii_val & 0x0016) == 0x0004) ? 0 : 1);
}
int detect_ethtool(int skfd, char *ifname)
{
struct ifreq ifr;
struct ethtool_value edata;
memset(&ifr, 0, sizeof(ifr));
edata.cmd = ETHTOOL_GLINK;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)-1);
ifr.ifr_data = (char *) &edata;
if (ioctl(skfd, SIOCETHTOOL, &ifr) == -1)
{
printf("ETHTOOL_GLINK failed: %s\n", strerror(errno));
return 2;
}
return (edata.data ? 0 : 1);
}
int main(int argc, char **argv)
{
int skfd = -1;
char *ifname;
int retval;
if( argv[1] )
ifname = argv[1];
else
ifname = "eth0";
/* Open a socket. */
if (( skfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 )
{
printf("socket error\n");
exit(-1);
}
retval = detect_ethtool(skfd, ifname);
if (retval == 2)
retval = detect_mii(skfd, ifname);
close(skfd);
if (retval == 2)
printf("Could not determine status\n");
if (retval == 1)
printf("Link down\n");
if (retval == 0)
printf("Link up\n");
return retval;
}
阅读(1740) | 评论(0) | 转发(0) |