mii-tool的限制/mii-tool和千兆网络
生活随笔
收集整理的這篇文章主要介紹了
mii-tool的限制/mii-tool和千兆网络
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
| mii-tool的限制/mii-tool和千兆網絡 ??????????????????????? mii-tool的限制mii-tool不支持1000M以上的網卡,這里我們先做個實驗,先看看100M網卡能不能正確顯示: [root@localhost /]# mii-tool -v eth0 ??????????????????????? eth0: negotiated 100baseTx-FD, link ok ??????????????????????? product info: vendor 00:40:63, model 50 rev 10 ??????????????????????? basic mode: autonegotiation enabled ??????????????????????? basic status: autonegotiation complete, link ok ??????????????????????? capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD ??????????????????????? advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD flow-control ??????????????????????? link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD ??????????????????????? #這里顯示100M網卡 [root@localhost /]# ethtool eth0 ??????????????????????? Settings for eth0: ??????????????????????? Supported ports: [ TP MII ] ??????????????????????? Supported link modes: 10baseT/Half 10baseT/Full ??????????????????????? 100baseT/Half 100baseT/Full ??????????????????????? Supports auto-negotiation: Yes ??????????????????????? Advertised link modes: 10baseT/Half 10baseT/Full ??????????????????????? 100baseT/Half 100baseT/Full ??????????????????????? Advertised auto-negotiation: Yes ??????????????????????? Speed: 100Mb/s ??????????????????????? Duplex: Full ??????????????????????? Port: MII ??????????????????????? PHYAD: 1 ??????????????????????? Transceiver: internal ??????????????????????? Auto-negotiation: on ??????????????????????? Supports Wake-on: pumbg ??????????????????????? Wake-on: d ??????????????????????? Current message level: 0x00000001 (1) ??????????????????????? Link detected: yes ??????????????????????? #這里也顯示是100M網卡 正常對于100M以下的網卡都能夠用這倆個命令來查看,但是對于100M以上網卡的,mii-tool就會出現問題 mii-tool -v eth0 ??????????????????????? eth0: negotiated 100baseTx-FD, link ok ??????????????????????? product info: vendor 00:aa:00, model 56 rev 0 ??????????????????????? basic mode: autonegotiation enabled ??????????????????????? basic status: autonegotiation complete, link ok ??????????????????????? capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD ??????????????????????? advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD flow-control ??????????????????????? link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD ??????????????????????? 10baseT-HD ??????????????????????? #這里顯示100M網卡,實際上我是1000M的接口 ethtool eth0 ??????????????????????? Settings for eth0: ??????????????????????? Supported ports: [ TP ] ??????????????????????? Supported link modes: 10baseT/Half 10baseT/Full ??????????????????????? 100baseT/Half 100baseT/Full ??????????????????????? 1000baseT/Full ??????????????????????? Supports auto-negotiation: Yes ??????????????????????? Advertised link modes: 10baseT/Half 10baseT/Full ??????????????????????? 100baseT/Half 100baseT/Full ??????????????????????? 1000baseT/Full ??????????????????????? Advertised auto-negotiation: Yes ??????????????????????? Speed: 1000Mb/s ??????????????????????? Duplex: Full ??????????????????????? Port: Twisted Pair ??????????????????????? PHYAD: 0 ??????????????????????? Transceiver: internal ??????????????????????? Auto-negotiation: on ??????????????????????? Supports Wake-on: umbg ??????????????????????? Wake-on: d ??????????????????????? Current message level: 0x00000007 (7) ??????????????????????? Link detected: yes ??????????????????????? #這里卻正確的顯示1000M網卡 這里簡單分析一下mii-tool的顯示部份的實現: ??????????????????????? 1、首先在主函數中打開套接字,循環調用處理函數: ??????????????????????? int main(int argc, char **argv) ??????????????????????? { ??????????????????????? int i; ??????????????????????? char s[6]; ??????????????????????? /* Open a basic socket. */ ??????????????????????? if ((skfd = socket(AF_INET, SOCK_DGRAM,0)) ??????????????????????? perror("socket"); ??????????????????????? exit(-1); ??????????????????????? } for (i = 0; i ??????????????????????? sprintf(s, "eth%d", i); ??????????????????????? do_one_xcvr(skfd, s, 1); ??????????????????????? } return 0; ??????????????????????? } ??????????????????????? do_one_xcvr的主要功能是調用ioctl取得網卡的phy_id,然后進一步處理: ??????????????????????? int do_one_xcvr(int skfd, char *ifname, int maybe) ??????????????????????? { ??????????????????????? struct mii_data *mii = (struct mii_data *)&ifr.ifr_data; ??????????????????????? /* Get the vitals from the interface. */ ??????????????????????? strncpy(ifr.ifr_name, ifname, IFNAMSIZ); ??????????????????????? if (ioctl(skfd, SIOCGMIIPHY, &ifr) ??????????????????????? { ??????????????????????? if (!maybe || (errno != ENODEV)) ??????????????????????? { ??????????????????????? fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %sn", ??????????????????????? ifname, strerror(errno)); ??????????????????????? } ??????????????????????? return 1; ??????????????????????? } show_basic_mii(skfd, mii->phy_id); ??????????????????????? } 關于SIOCGMIIPHY等宏的定義,很容易就能夠找到了,這里不分析了…… ??????????????????????? show_basic_mii是整個核心了: ??????????????????????? int show_basic_mii(int sock, int phy_id) ??????????????????????? { ??????????????????????? char buf[100]; ??????????????????????? int i, mii_val[32]; ??????????????????????? int bmcr, bmsr, advert, lkpar; ??????????????????????? /* Some bits in the BMSR are latched, but we can't rely ??????????????????????? on being ??????????????????????? the only reader, so only the current values are ??????????????????????? meaningful */ ??????????????????????? mdio_read(sock, MII_BMSR); ??????????????????????? for (i = 0; i ??????????????????????? mii_val = mdio_read(sock, i); if (mii_val[MII_BMCR] == 0xffff) { ??????????????????????? fprintf(stderr, " No MII transceiver present!.n"); ??????????????????????? return -1; ??????????????????????? } /* Descriptive rename. */ ??????????????????????? bmcr = mii_val[MII_BMCR]; bmsr = mii_val[MII_BMSR]; ??????????????????????? advert = mii_val[MII_ANAR]; lkpar = mii_val[MII_ANLPAR]; sprintf(buf, "%s: ", ifr.ifr_name); ??????????????????????? if (bmcr & MII_BMCR_AN_ENA) { ??????????????????????? if (bmsr & MII_BMSR_AN_COMPLETE) { ??????????????????????? if (advert & lkpar) { ??????????????????????? strcat(buf, (lkpar & MII_AN_ACK) ? ??????????????????????? "negotiated" : "no autonegotiation,"); ??????????????????????? strcat(buf, media_list(advert & lkpar, 1)); ??????????????????????? strcat(buf, ", "); ??????????????????????? } else { ??????????????????????? strcat(buf, "autonegotiation failed, "); ??????????????????????? } ??????????????????????? } else if (bmcr & MII_BMCR_RESTART) { ??????????????????????? strcat(buf, "autonegotiation restarted, "); ??????????????????????? } ??????????????????????? } else { ??????????????????????? sprintf(buf+strlen(buf), "%s Mbit, %s duplex, ", ??????????????????????? (bmcr & MII_BMCR_100MBIT) ? "100" : "10", ??????????????????????? (bmcr & MII_BMCR_DUPLEX) ? "full" : "half"); ??????????????????????? } ??????????????????????? strcat(buf, (bmsr & MII_BMSR_LINK_VALID) ? "link ok" : ??????????????????????? "no link"); printf("%sn", buf); return 0; ??????????????????????? } ??????????????????????? 能夠看到,主要是通過mdio_read來讀取相關信息的,之后就是判斷比較和輸出了,而輸出網卡物一類型的時候,用到了media_list,先來看看mdio_read: ??????????????????????? static int mdio_read(int skfd, int location) ??????????????????????? { ??????????????????????? struct mii_data *mii = (struct mii_data *)&ifr.ifr_data; ??????????????????????? mii->reg_num = location; ??????????????????????? if (ioctl(skfd, SIOCGMIIREG, &ifr) ??????????????????????? fprintf(stderr, "SIOCGMIIREG on %s failed: %sn", ??????????????????????? ifr.ifr_name, ??????????????????????? strerror(errno)); ??????????????????????? return -1; ??????????????????????? } ??????????????????????? return mii->val_out; ??????????????????????? } ??????????????????????? 同樣,也是用ioctl……^o^,再來看看media_list,他主要根據mdio_read返回來的相關值讀取一個事先封裝好的結構數組: ??????????????????????? static char *media_list(int mask, int best) ??????????????????????? { ??????????????????????? static char buf[100]; ??????????????????????? int i; ??????????????????????? *buf = ''; ??????????????????????? mask >>= 5; ??????????????????????? for (i = 4; i >= 0; i--) { ??????????????????????? if (mask & (1 ??????????????????????? strcat(buf, " "); ??????????????????????? strcat(buf, media.name); ??????????????????????? if (best) break; ??????????????????????? } ??????????????????????? } ??????????????????????? if (mask & (1 ??????????????????????? strcat(buf, " flow-control"); ??????????????????????? return buf; ??????????????????????? } ??????????????????????? 最后來看看media的定義的賦值: ??????????????????????? const struct { ??????????????????????? char *name; ??????????????????????? u_short value; ??????????????????????? } media[] = { ??????????????????????? /* The order through 100baseT4 matches bits in the BMSR ??????????????????????? */ ??????????????????????? { "10baseT-HD", MII_AN_10BASET_HD }, ??????????????????????? { "10baseT-FD", MII_AN_10BASET_FD }, ??????????????????????? { "100baseTx-HD", MII_AN_100BASETX_HD }, ??????????????????????? { "100baseTx-FD", MII_AN_100BASETX_FD }, ??????????????????????? { "100baseT4", MII_AN_100BASET4 }, ??????????????????????? { "100baseTx", MII_AN_100BASETX_FD | MII_AN_100BASETX_HD ??????????????????????? }, ??????????????????????? { "10baseT", MII_AN_10BASET_FD | MII_AN_10BASET_HD }, ??????????????????????? }; 這里沒有定義100M以上的接口,所以,mii-tool不支持1000M http://liubin.blog.51cto.com/282313/107793 |
總結
以上是生活随笔為你收集整理的mii-tool的限制/mii-tool和千兆网络的全部內容,希望文章能夠幫你解決所遇到的問題。