[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > C/C++ > 正文
Unix編程/應用問答中文版 ---10.網卡相關問題
本文出自:http://www.nsfocus.com 維護:小四 (2002-10-30 06:02:01)
10.   網卡相關問題 
10.1  如何在程序中獲取本機MAC地址 
10.2  如何在Sun工作站上安裝3塊網卡 
10.3  如何在Solaris x86上安裝網卡驅動 
10.4  Solaris 單網卡多IP(以太網卡別名) 
10.5  如何修改主機名(hostname) 
10.6  SPARC/Solaris 2.5/2.6/7/8下如何設置網卡100Mb全雙工 
10.7  Unix/Linux/BSD如何對抗ARP欺騙攻擊 
10.8   
10.9   
10.10 
10.11 x86/Solaris如何強制設定網卡速率 
10.12 Solaris/FreeBSD/Linux如何確定網卡Capability/Speed 
10.13 
10.14 traceroute是怎實現的 
-------------------------------------------------------------------------- 

10. 網卡相關問題 

10.1 如何在程序中獲取本機MAC地址 

Q: 如何在C代碼中獲取本機MAC地址,我用strace跟蹤ifconfig 

   ioctl(4, SIOCGIFHWADDR, 0xbffffb80)     = 0 
   ioctl(4, SIOCGIFADDR, 0xbffffb80)       = 0 
   ioctl(4, SIOCGIFBRDADDR, 0xbffffb80)    = 0 
   ioctl(4, SIOCGIFNETMASK, 0xbffffb80)    = 0 

D: Unix Programmer 

用gethostname()/gethostbyname()依賴本機的域名解析系統,比如/etc/hosts文 
件、/etc/nsswitch.conf文件、/etc/resolv.conf文件。這樣獲取本機IP是不可靠的。 
如果/etc/hosts文件中沒有指定本機IP,則依賴DNS是否配置了PTR資源記錄。可靠的 
辦法應該是strace ifconfig、truss ifconfig,實際就是照ifconfig的實現去獲取 
本機IP。 

A: David Peter <dave.peter@eu.citrix.com> 

strace是Linux下的工具,由HP-UX 10.20的ioctl不支持SIOCGIFHWADDR,可能需要 
DLPI接口或者針對/dev/lan0的NETSTAT ioctl,為了使用NETSTAT ioctl還需要重啟 
動,而且HP不讚成繼續使用NETSTAT ioctl,HP-UX 11.00不再支持。 

根據手頭一個古老的工具,Digital Unix下ioctl支持SIOCRPHYSADDR。至SGI上的 
IRIX,我想可能需要一個原始套接字,比如: 

s = socket( PF_RAW, SOCK_RAW, RAWPROTO_SNOOP ) 

D: scz <scz@nsfocus.com> 2001-11-20 11:46 

SPARC/Solaris下只有root用戶才可以ifconfig -a看到本機MAC地址,普通用戶並不 
能這樣做,但可以嘗試在dmesg輸出中查找,由dmesg使用的數據有可能被破壞,這 
個辦法並不可靠。 

"arp <本機IP地址>"可以看到本機MAC地址,使用的技術實際上就是前面編程演示的 

ioctl( s, SIOCGARP, &arpreq ) 

此外還可以用如下命令獲取本機MAC地址 

ndd /dev/arp arp_cache_report | grep MYADDR 

10.2 如何在Sun工作站上安裝3塊網卡 

Q: 我想在Sun工作站上安裝3塊網卡,怎辦 

A: Santosh 

請遵循如下步驟 

1) 在Sun工作站上增加網卡 

2) 用boot -r啟動系統 

3) 觀察啟動信息,確認每塊網卡都被識別出來,比如這種信息 

   PCI-device: network@1,1, hme #0 
   SUNW,hme0 is /pci@1f,4000/network@1,1 

   實際中如果每塊網卡都被識別出來,有hme0、hme1 和 hme2,當然1和2可能不是 
   這個名字。 

4) 到/etc目錄下創建hostname.hme0、hostname.hme1 和 hostname.hme2。在每個文 
   件中分別指定IP地址,編輯/etc/hosts文件增加相應入口。 

5) 重啟機器 

10.3 如何在Solaris x86上安裝網卡驅動 

A: James Adkins <jadkins@peregrine.com> 

不需要修改"pcn.conf"文件。開始我只是"touch /reconfigure",Solaris x86檢測 
到了網卡,但是"ifconfig -a"的時候只有loopback接口,是我嘗試如下步驟: 

# drvconfig 
# devlinks 
# touch /reconfigure 

重啟動一切ok 

10.4 Solaris 單網卡多IP(以太網卡別名) 

Q: 對Solaris 2.5.1來說,可以在一塊物理網卡上配置多個IP地址 

A: Sun Microsystems 1998-03-31 

下面以lance ethernet (le0) 設備為例說明 

1) 編輯/etc/hosts文件 

128.195.10.31 myhost 
128.195.10.46 myhost2 
128.195.10.78 myhost3 

2) 創建/etc/hostname.le0:n文件,注意hostname.le0:0就是hostname.le0 

/etc/hostname.le0   (Contains name myhost) 
/etc/hostname.le0:1 (Contains name myhost2) 
/etc/hostname.le0:2 (Contains name myhost3) 

注意這種文件就一行內容,主機名。 

3) 如果想立即生效 

% ifconfig le0:1 up 
% ifconfig le0:1 129.153.76.72 
% ifconfig le0:1 down 

Q: Solaris 8下如何給一塊以太網卡賦予多個IP地址? 

A: Vadim V. Kouevda <VKouevda@pcinetgw.is.bear.com> 

ifconfig le0 plumb 
ifconfig le0 ether 0:1:2:3:4:5 
ifconfig le0:1 plumb 
ifconfig le0:1 ... up 
ifconfig le0:2 plumb 
ifconfig le0:2 ... up 

到/etc/init.d目錄下修改IP地址、子網掩碼等設置。 

D: scz <scz@nsfocus.com> 

有三個文件需要注意,/etc/rcS.d/S30rootusr.sh(/etc/init.d/rootusr)、 
/etc/rc2.d/S69inet(/etc/init.d/inetinit)和/etc/rc2.d/S72inetsvc 
(/etc/init.d/inetsvc)。 

Q: 如何在一塊物理網卡上綁定多個IP地址 

A: Sun Microsystems 1997-10-27 

所謂虛擬網絡接口指一個物理接口多個不同IP地址,Solaris允許一個物理網絡接口 
對應多個邏輯接口,換句話說,即使只有一塊網卡,也可以配置多個IP地址。參看 
ifconfig(1M)手冊頁。對Solaris 2.x,可以在一塊網卡上綁定256個不同IP地址。 
Sun OS 4.x(Solaris 1.x)不支持。 

/usr/sbin/ndd -get /dev/ip ip_addrs_per_if 

對Solaris 2.6,通過ndd可以配置超過256(0-255)個IP地址。 

/usr/sbin/ndd -set /dev/ip ip_addrs_per_if 1-8192 

將這條命令增加到/etc/rc2.d/S69inet啟動腳本中去。 

1) 編輯/etc/hosts文件(或者nis host map),為每個虛擬接口增加條目。別忘記修 
   改NIS、NIS+、DNS數據庫。 

2) 為每個接口創建/etc/hostname.<interface:#>文件,比如/etc/hostname.le0:1、 
   hostname.le0:2、hostname.le0:3 ... le0:255。文件內容為單行IP地址或者主 
   機名。比如創建如下文件 

   /etc/hostname.le0:1  (不要使用le0:0,那就是le0) 
   /etc/hostname.le0:2 

   Solaris 2.5.1下最多1024個虛擬接口。每個文件內容是自己對應的虛擬接口IP地 
   址或者主機名。 

3) 如果使用了子網,應該在/etc/netmasks中增加 

   network_address  netmask 

   157.145.0.0  255.255.255.0 

4) 重啟系統 

5) ifconfig -a驗証之 

某些第三方應用程序此時可能會出問題。出安全考慮,可以 

ndd -set /dev/ip ip_forwarding 0 
ndd -set /dev/ip ip_strict_dst_multihoming 1 

參看RFC1112 - <<Host Extensions for IP Multicasting>>。 

如果因為配置虛擬接口出現不期望的路由,考慮手動"route delete"。可以增加一個 
啟動腳本/etc/rc2.d/S99vif,用完成這些任務。 

對Solaris 2.6,可能還需要 

ndd -set /dev/ip ip_enable_group_ifs 0 (2.6下缺省是1,7下缺省是0) 

將這條命令增加到/etc/rc2.d/S69inet啟動腳本中去。 

10.5 如何修改主機名(hostname) 

Q: Solaris 2.6下如何修改主機名(hostname) 

A: Herve Poussin <poussin@partner-system.com> 

需要修改如下文件 

/etc/hosts 
/etc/hostname.<interface> 
/etc/nodename 
/etc/net/*/hosts (3 files, man -s 7D ticotsord) 

如果你運行在VxVM下,則應該 

# vxdctl hostid <new_name> 
# vxdctl init <new_name> 

10.6 SPARC/Solaris 2.5/2.6/7/8下如何設置網卡100Mb全雙工 

Q: 我從SPARC連接3Com交換機時,總是使用半雙工,如何配置網卡強行使用100Mb全 
   雙工 

A: Martin Scerri <martin_scerri@bigfoot.com> 

下列回答來自"Sun管理員FAQ 12.3",並且只適合Solaris 2.5及其以版本, 
Sun OS 4.x及其更早版本不支持hme接口。 

一般網卡可以和交換機自動協商使用100Mb全雙工,如果協商失敗,可能看到諸如 
"late collision"一類的消息,出現丟包甚至完全不能工作的現象。為了強行指定使 
用某一確定的工作模式,比如100Mb FD,可以用ndd做如下操作: 

# 指定操作hme0接口 
ndd -set /dev/hme instance 0 
# 關閉自動協商 
ndd -set /dev/hme adv_autoneg_cap  0 
# 打開100Mb FD支持 
ndd -set /dev/hme adv_100fdx_cap   1 
# 關閉100Mb HD支持 
ndd -set /dev/hme adv_100hdx_cap   0 
# 關閉10Mb FD支持 
ndd -set /dev/hme adv_10fdx_cap    0 
# 關閉10Mb HD支持 
ndd -set /dev/hme adv_10hdx_cap    0 

同樣需要在對端(比如交換機)強行指定使用100Mb FD模式。 

注意:Fast ethernet hubs 總是使用100Mb HD模式 
      ethernet hubs 總是使用10Mb HD模式 

如果你想強行指定系統中所有hme網卡在啟動時進入同一確定模式,可以在 
/etc/system文件中設置,下例表示進入100Mbit FD模式: 

set hme:hme_adv_autoneg_cap=0 
set hme:hme_adv_100fdx_cap=1 
set hme:hme_adv_100hdx_cap=0 
set hme:hme_adv_10hdx_cap=0 
set hme:hme_adv_10fdx_cap=0 

A: Andreas.Gouder <Andreas.Gouder@t-online.de> 

你可以用如下命令獲取當前設置 

# ndd -get /dev/hme link_mode 

0 半雙工 
1 全雙工 

# ndd -get /dev/hme link_status 

0 Link Down 
1 Link up 

# ndd -get /dev/hme link_speed 

0 10Mbps 
1 100Mbps 

10.7 Unix/Linux/BSD如何對抗ARP欺騙攻擊 

Q: Solaris的靜態ARP表項(arp -s)還是會被動態刷新,我只確認Linux/FreeBSD的靜 
   態ARP表項不會被動態刷新,到底有沒有稍微通用點的對抗ARP欺騙攻擊的方法。 

A: scz <scz@nsfocus.com> 

下面以Solaris系統為例說明,其他系統大同小異。 

1) 建立靜態ARP表 

/usr/bin/touch /etc/static_arp_entry 
/usr/bin/chown root:root /etc/static_arp_entry 
/usr/bin/chmod 600 /etc/static_arp_entry 

編輯/etc/static_arp_entry文件,輸入類似內容 

192.168.8.90    00:00:00:11:11:11 

/usr/sbin/arp -s -f /etc/static_arp_entry 

可以在/etc/rc2.d/S69inet啟動腳本中增加這條命令。參看arp(1M)、arp(7P)手冊頁 
了解更多細節。這種技術對系統影響不大,對網絡影響較大,破壞了動態ARP解析過 
程。Solaris系統中,靜態ARP表不會過期,必須用"arp -d"手動刪除。但是, 
Solaris系統的靜態ARP表項可以被動態刷新,僅僅依靠靜態ARP表項並不能對抗ARP欺 
騙攻擊,相反縱容了ARP欺騙攻擊,因為虛假的靜態ARP表項不會自動超時消失。當然, 
可以考慮利用cron機制補救之。(增加一個crontab) 

為了對抗ARP欺騙攻擊,對Solaris系統來說,應該結合"禁止相應網絡接口做ARP解 
析"和"使用靜態ARP表"的設置 

2) 禁止某個網絡接口做ARP解析(對抗ARP欺騙攻擊) 

"/sbin/ifconfig hme0 -arp"命令將禁止hme0接口做ARP解析,hme0接口不會發送/接 
收ARP報文。必須配合使用靜態ARP表,否則無法完成正常網絡通信。參看 
ifconfig(1M)了解更多細節。假設/etc/rc2.d/S69inet啟動腳本中存在如下內容 

/sbin/ifconfig hme0 -arp 
/usr/sbin/arp -s -f /etc/static_arp_entry 

假設/etc/static_arp_entry文件內容如下 

192.168.8.90    00:00:00:11:11:11 

這裡192.168.8.90是一台PWin98,也做靜態ARP設置(因為對方不會響應ARP請求報文) 

arp -s 192.168.10.6 08-00-20-a8-2e-ac 

此時192.168.8.90與192.168.10.6可以正常通信,並且192.168.10.6不受ARP欺騙攻 
擊的影響。事實上,絕大多數Unix/Linux/BSD操作系統,都可以結合"禁止相應網絡 
接口做ARP解析"和"使用靜態ARP表"的設置來對抗ARP欺騙攻擊。對Linux/FreeBSD 
系統,因為其靜態ARP表項(arp -s)不會被動態刷新,所以不需要"禁止相應網絡接口 
做ARP解析"即可對抗ARP欺騙攻擊。 

10.11 x86/Solaris如何強制設定網卡速率 

Q: x86/Solaris,我如何強行指定網卡的工作狀態為100Mbps full-duplex,ndd(1M) 
   不工作 

A: CERNET 水木清華 Unix版 inc 2001-10-11 20:29 

x86/Solaris下的網卡驅動不支持ndd(1M)設置網卡工作狀態,要達到目的,唯一的辦 
法是通過driver.conf(4)指定。x86/Solaris 8的iprb(7D)手冊頁建議使用 
ForceSpeedDuplex選項。對其它驅動,參看如下例子 

vi /kernel/drv/iprb.conf  <-- 用ifconfig -a確認一下 

# To force full duplex operation, uncomment the following line: 
# full-duplex=1; 

# To force half duplex operation, uncomment the following line: 
# full-duplex=0; 

# To force 10Mbps operation, uncomment the following line: 
# speed=10; 

# To force 100Mbps operation, uncomment the following line: 
# speed=100; 

奇怪的是iprb.conf原來沒有上面的內容,elxl.conf卻有。注意,不同網卡是有區別 
的,我試了RealTek RTL8139/8129、3Com 3C905B TX、Intel,只有Intel的可以這樣 
修改,RealTek RTL8029的我不確定。 

D: CERNET 水木清華 Unix版 2001-10-12 10:36 

由x86下網卡驅動不支持ndd(1M)獲取網卡狀態,被迫使用netstat -k 

ifconfig -a 找出網絡接口名 

netstat -k <interface> | grep ifspeed 

某些x86網卡驅動支持,某些不支持,這個辦法同樣適合SPARC網卡驅動,雖然者 
可以直接使用ndd(1M)。 

10.12 Solaris/FreeBSD/Linux如何確定網卡Capability/Speed 

A: 小四 <scz@nsfocus.com> 2001-12-07 17:06 

Solaris 

# netstat -k hme0 | grep ifspeed 

# ndd -get /dev/hme link_mode 

0 半雙工 
1 全雙工 

# ndd -get /dev/hme link_status 

0 Link Down 
1 Link up 

# ndd -get /dev/hme link_speed 

0 10Mbps 
1 100Mbps 

FreeBSD用ifconfig就可以看到 

status: active      <-- 網線接到一個HUB上了 
status: no carrier  <-- 未接網線 

Linux和Windows系列我到現在也不確認。 

A: starw@smth.org 

在高版本的Linux系統中net-tools包中有一個mii-tool命令,可以用檢查這些數據, 
而不是溶合在ifconfig的輸出中。 

10.14 traceroute是怎實現的 

Q: traceroute是怎實現的 

A: 小四 <cloudsky@263.net> 

traceroute(對Windows系列是tracert)通過逐步增加TTL值的方法,發送常規IP分 
組來實現。第一次發送分組時TTL為1,第一個路由器接收到該分組之將TTL值減1, 
結果為0,是就丟棄該分組,並發回一個"TTL超時"的ICMP報文,該報文的源地址是 
這第一個路由器。緊接著發送一個TTL為2的分組。注意,traceroute發送常規的UDP 
報文到一個不用的UDP端口。當初考慮將路由跟蹤的功能加入IP協議本身,定義一個 
"路由跟蹤"選項,路由器處理帶有該選項的IP包時立即發回一個跟蹤報文到源站點。 
然而這種做法還停留在實驗室階段,因為這需要改變所有已經存在的路由器,而且在 
某種程度上與端到端原則相違背。 

1) 傳統的Unix實現是UDP+ICMP 
2) 其實從原理上TCP+ICMP也是可以的,某些Unix系統採用了這種實現 
3) Windows另有一種實現,Icmp Echo Request+ICMP 
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
Unix編程/應用問答中文版 ---9.圖形界面相關問題 (2002-10-29 06:02:00)
Unix編程/應用問答中文版 ---8.Solaris內核編程相關問題 (2002-10-28 06:02:00)
Unix編程/應用問答中文版 ---7.DNS相關問題 (2002-10-25 06:02:00)
Unix編程/應用問答中文版 ---6./etc/system可調資源限制 (2002-10-24 06:02:00)
Unix編程/應用問答中文版 ---5.塊設備相關問題 (2002-10-23 06:02:00)
Unix編程/應用問答中文版 ---4.系統資源相關問題 (2002-10-22 06:02:00)
Unix編程/應用問答中文版 ---3.-lelf、-lkvm、-lkstat相關問題 (2002-10-21 06:02:01)
Unix編程/應用問答中文版 ---2.堆棧相關問題 (2002-10-18 06:02:00)
Unix編程/應用問答中文版 ---1.系統管理配置問題 (2002-10-17 06:02:00)
Unix編程/應用問答中文版 ---0.簡介 Unix/C傳奇問題 (2002-10-16 06:02:01)
 

★  樊強制作 歡迎分享  ★