1 Alpha驅動程序——獲取與使用
2 一台機器使用多個以太網卡
3 這個以太東東不干活。為什麼?
4 NE1000 / NE2000網卡(及其系列)的問題
5 SMC Ultra/EtherEZ和WD80*3網卡的問題
6 3Com網卡的問題
7 非特定網卡的FAQs
這裡是一些有關使用Linux進行以太網連接的常見問題。某些特定問題按照制造商進行分類。可能你想問的問題別人已經問過(而且被回答了!),所以即使沒有在這裡找到你的答案,還可能在諸如Dejanews之類的新聞檔案中找到你所要的。
1 Alpha驅動程序——獲取與使用
我聽說我的網卡有一個更新的或初步的/alpha驅動程序。從哪兒得到它呢?
最新的“新”驅動程序可以在Donald的FTP站點:cesdis.gsfc.nasa.gov裡面的/pub/linux/下找到。因為事情變化很頻繁,可能需要四處找一找。或者使用WWW浏覽器去:
Don的Linux主頁
查找你想要的驅動程序更簡單一些。(留神WWW浏覽器會悄悄地把源碼中的TABs替換為空格,等等 - 如果無法確定的話,使用FTP下載,至少也得用WWW浏覽器的FTP URL。)
如果驅動程序確實是alpha版本,或pre-alpha版本,那麼請恰當地對待它。換句話說,不要抱怨,因為你無法弄清用它能做些什麼。同樣,如果它使你的機器宕機了,不要抱怨。相反,你應該發給我們一份材料組織很好的Bug報告,如果是一個布丁,那就更好!
注意,某些“可用”的實驗性/alpha驅動程序已經包含在標准的內核源碼樹中。在運行make config時你首先要回答的一個問題就是“Prompt for development and/or incomplete code/drivers”。在此你要回答“Y”以包括任何alpha/實驗性驅動程序。
2 一台機器使用多個以太網卡
做些什麼才能讓Linux運行兩塊以太網卡?
這個問題的答案取決於驅動程序是否被用做可載入的模塊或者直接編譯進了內核。大多數Linux發行版本現在都使用模塊化的驅動程序。這樣就不用發行許多內核,每種內核設置一個不同的內建驅動程序。使用一個單一的基本內核,如果特定用戶系統需要,一旦系統啟動,就足以從驅動程序模塊文件(通常存儲在/lib/modules/)中載入個別的驅動程序。
把驅動程序作為模塊使用:對於PCI驅動程序,模塊通常會自動檢測該品牌類型所有安裝的網卡。但對於ISA網卡,探尋一個網卡是不安全的操作,因此你需要提供網卡的I/O地址以便模塊知道去哪裡查找。這一信息存儲在文件/etc/conf.modules中。
例如,如果一個用戶有兩塊ISA NE2000網卡,一塊在0x300,一塊在0x240,它們在/etc/conf.modules文件中顯示如下:
alias eth0 ne
alias eth1 ne
options ne io=0x240,0x300
這幾行的意義:就是說如果管理員(或內核)進行modprobe eth0或者modprobe eth1,那麼為eth0或者eth1載入ne.o驅動程序。此外,在載入ne.o模塊時,使用選項io=0x240,0x300,這樣驅動程序就知道去哪裡尋找網卡。注意0x很重要 - DOS裡常用的300h在這裡沒有用。改變0x240和0x300的順序會使哪一塊物理網卡以eth0和eth1結尾發生改變。
同這個例子一樣,大多數ISA模塊驅動程序可以接受多個以逗號分隔的I/O值以處理多塊網卡。但是,某些(老的?)驅動程序,比如3c501.o模塊,目前載入一個模塊只能處理一塊網卡。這樣,要檢測兩塊網卡就必須載入兩次該模塊。此時,文件/etc/conf.modules將如下所示:
alias eth0 3c501
alias eth1 3c501
options eth0 -o 3c501-0 io=0x280 irq=5
options eth1 -o 3c501-1 io=0x300 irq=7
在此例中,選項-o用來給每個模塊實例一個唯一的名字,因為不能用同一個名字載入兩個模塊。選項irq=也是用來指定網卡設置的硬件IRQ。(此方法也能用於可接受多個以逗號分隔的I/O值的模塊,但這樣會使模塊被不必要地載入兩次,降低了效率。)
最後一個例子,假設用戶有一塊在0x350的3c503網卡和一塊在0x280的SMC Elite16 (wd8013)網卡。則應該這樣:
alias eth0 wd
alias eth1 3c503
options wd io=0x280
options 3c503 io=0x350
對於PCI網卡,只要用alias語句把ethN接口和相應的驅動程序名聯系起來就行了,因為PCI網卡的I/O地址可以被安全地檢測到。
可用的模塊一般存放在/lib/modules/`uname -r`/net下,這裡uname -r命令可以得到內核的版本(比如2.0.34)。你可以在這裡看看哪一個驅動程序適合你的網卡。一旦你在conf.modules文件裡進行了正確的設置,就可以用下面的方法檢查一下:
modprobe ethN
dmesg tail
這裡“N”是你要檢測的以太網卡的接口號。
使用編譯進內核的驅動程序:如果你需要的驅動程序編譯進了內核,那麼處理多塊以太網卡的接口已經存在了。但缺省情況下只自動檢測一塊以太網卡。這樣就避免了啟動時檢測敏感網卡可能引起的麻煩。
(注意:在2.1.x之後的內核中,啟動檢測被分為安全和不安全的兩類,所有安全的檢測(如對PCI和EISA網卡)可以自動找到所有相關的網卡。在至少有一塊ISA網卡的多網卡系統中還需要進行以下的處理。)
有兩種方法可以啟動對第二塊(或第三塊等等)網卡的自動檢測。最簡單的方法是向內核傳遞啟動參數,由LILO完成。使用ether=0,0,eth1這樣簡單的啟動參數就可以完成對第二塊網卡的檢測。此時按照啟動時找到的網卡順序分配eth0和eth1。假如你想讓0x300處的網卡為eth0,而0x280處的網卡為eth1,那麼可以使用
LILO: linux ether=5,0x300,eth0 ether=15,0x280,eth1
命令ether=可以接受的參數並不僅限於如上所示的IRQ + I/O + name。請參看傳遞以太網參數......以了解全部的句法、網卡特定參數和LILO使用技巧。
這些啟動參數可以固定,這樣就不用每次都必須重新敲一遍。參看LILO手冊中有關LILO 的配置選項“append”。
第二種方法(不建議使用)是編輯文件Space.c並用零替換I/O地址中的0xffe0入口。0xffe0入口是用來告訴內核不要檢測該設備 -- 把它替換為零就啟動了對該設備的自動檢測。
注意,如果想用Linux作為兩個網絡間的路由,你需要啟動IP轉發並重新編譯內核。一般在一台老式的AT/286上運行“kbridge”一類的軟件就相當不錯了。
如果你是一邊在網絡沖浪,一邊看本文檔,最好去閱讀Donald的WWW站點上的mini-howto。看一下多塊以太網卡.
3 這個以太東東不干活。為什麼?
如上所述,命令ether=只對編譯進了內核的驅動程序起作用。現在大多數的發行版本都用模塊的方式使用驅動程序,所以很少再使用ether=命令了。(某些早期文檔需要更新以反映這一變化。)如果你想使用模塊化的以太網驅動程序的選項,必須修改/etc/conf.modules文件。
如果你是使用編譯的驅動程序,而且已經把ether=加進了LILO 配置文件,需要重新運行lilo使更新後的配置文件生效。
4 NE1000 / NE2000網卡(及其兼容卡)的問題
問題:在用v2.0.x啟動時沒有檢測到PCI NE2000兼容網卡。
原因:在v2.0.30之前的ne.c驅動程序只知道基於RealTek 8029的兼容網卡的PCI ID號。在此只後才出現了使用其它PCI ID號的PCI NE2000兼容網卡,所以驅動程序無法檢測這些網卡。
解決方案:最簡單的方法是把Linux內核升級到v2.0.31以上版本。它可以識別五種不同的NE2000-PCI芯片的ID號,在啟動或載入模塊時自動檢測到它們。如果你升級到了2.0.34以上版本,會有一個比原先的ISA/PCI驅動程序稍小但更高效的PCI專用NE2000驅動程序。
問題:啟動時PCI NE2000兼容網卡被報告為ne1000(8比特網卡!)或者在v2.0.x下載入ne.o模塊不起作用。
原因:某些PCI兼容網卡不支持字節存取(因此不是百分之百的兼容NE2000)。這使檢測時被誤認為NE1000網卡。
解決方案:你需要升級到v2.0.31以上版本。現在的驅動程序會檢測到這種硬件Bug。
問題:PCI NE2000網卡的性能很差,即使按照性能技巧章節所說的減小了窗口大小。
原因:十多年前設計和出售的初始8390芯片的技術數據手冊上提到,為了得到最高的可靠性,在每次寫操作之前需要一個讀操作。驅動程序能夠輕易地做到這一點,但從v1.2內核時代起,缺省情況下取消了這一操作。有一個用戶報告說重新使用這一“錯誤的特性”就可以改善廉價的PCI NE2000兼容網卡的性能。
解決方案:由於只有一個用戶提出報告把它作為解決方案,不要對此寄予太大的希望。重新使用寫之前的讀操作可以簡單地編輯linux/drivers/net/下的驅動程序文件,取消包含NE_RW_BUGFIX的那一行的注釋,然後重建內核或載入相應的模塊。如果這樣確實有效,請給我發一封e-mail,描述性能上的差異和你所使用的網卡/芯片類型。(對ne2k-pci.c驅動程序也可以如法炮制。)
問題:ne2k-pci.c驅動程序對PCI NE2000網卡報告諸如timeout waiting for Tx RDC錯誤信息,無法正常工作。
原因:你的網卡或網卡到PCI總線的連接無法處理該驅動程序使用的長字I/O優化。
解決方案:首先,檢查BIOS/CMOS設置,看看與PCI總線相關的計時對於可靠的操作是否過於嚴格了。否則,使用ISA/PCI的ne.c驅動程序(或者刪除ne2k-pci.c中的#define USE_LONGIO),使你的網卡可用。
問題:沒檢測到ISA的即插即用NE2000網卡(如RealTek 8019)。
原因:初始的NE2000特性不支持即插即用,因此Linux的NE2000驅動程序也不支持即插即用。
解決方案:使用網卡所附的DOS配置盤取消PnP,並為該網卡設置一個指定的I/O地址和IRQ。在/etc/conf.modules裡增加這樣的一行options ne io=0xNNN,這裡0xNNN是你為網卡設置的16進制I/O地址。(假設你使用的是模塊化驅動程序;否則,在啟動時使用一個ether=0,0xNNN,eth0參數。你也可以進入BIOS/CMOS設置,把IRQ從PnP改為Legacy-ISA。如果你需要為兼容其它的操作系統而保留PnP設置,那麼你可以看一下isapnptools包。使用man isapnp看看它是否已經安裝在你的系統上了。如果沒有,浏覽一下下面的連接:
ISA PNP Tools
問題:在啟動檢測時NE*000驅動程序報告“not found (no reset ack)”。
原因:這跟上面所說的改動有關。在證實8390處於所檢測的I/O地址之後,進行重新設置。在網卡完成重新設置後,應當通知重新設置完成。你的網卡沒有通知,所以驅動程序認為不存在NE網卡。
解決方案:你可以在啟動時使用一個未被使用的mem_end16進制值0xbad,告訴驅動程序你有一個壞網卡。在使用0xbad撤消時你必須為網卡提供一個非零的I/O地址。例如,在0x340的網卡不響應重新設置,則使用如下方法:
LILO: linux ether=0,0x340,0,0xbad,eth0
這樣,即使你的網卡不響應重新設置,網卡檢測還能繼續下去。如果你是以模塊方式使用驅動程序,那麼可以象提供I/O地址一樣提供選項bad=0xbad。
問題:NE*000網卡使機器在第一次網絡訪問時死機。
原因:這個問題從早期的1.1.57內核到現在都出現過,而且只在有限的幾種軟件配置的兼容網卡上出現。看來是需要用某些特殊的方法來初始化它們。
解決方案:有幾個人報告在熱啟動(即loadlin或Ctrl-Alt-Del)Linux之前,運行提供的DOS軟件配置程序或提供的DOS驅動程序可以使網卡工作。這表明這些卡需要以某種特殊的方式初始化,與當前的Linux驅動程序稍有區別。
問題:在0x360的NE*000以太網卡沒有檢測到。
原因:你的NE2000網卡在I/O空間占據了0x20個字節,使它與0x378處的並口發生沖突。其它可能的設備是0x370處的第二個軟盤控制器(如果有的話),以及0x376--0x377處的第二個IDE控制器。如果該口已被其它驅動程序注冊,內核將不再進行檢測。
解決方案:把你的網卡移到0x280, 0x340, 0x320一類的地址,或者在編譯時不支持並行打印機。
問題:每次打印時網絡都斷開(NE2000)。
原因:與上一個問題相同,但你的內核比較老,不支持對重疊I/O區域的檢查。使用如上的解決方案,有空時獲取一個新的內核。
問題:沒檢測到0xNNN: 00 00 C5 ... 處的NE*000以太網卡。(非法標識yy zz)
原因:首先,你是否在地址0xNNN處有一個NE1000或NE2000網卡?如果有,報告的硬件地址是否象一個合法地址?如果是的話,那麼你的NE*000兼容網卡很差勁。所有的 NE*000兼容網卡都假定網卡上的SA PROM的第14和15字節為0x57。而你的網卡不是這樣 -- 它的值為“yy zz”。
解決方案:有兩種解決方法。最簡單的方法就是如上所述的“no reset ack” 解決方案,使用一個0xbad的mem_end值。這樣在提供一個非零的I/O地址時就可以忽略標識檢查。此方法無需重新編譯內核。
第二種方法(對黑客)需要修改驅動程序,並重新編譯內核(或模塊)。在驅動程序(/usr/src/linux/drivers/net/ne.c)的42行有一個“Hall of Shame”列表。這個表是用來檢測那些差勁的兼容網卡的。例如,DFI網卡在PROM的前三個字節使用“DFI”,而不是象要求的那樣在第14和15字節使用0x57。
問題:機器在啟動時出現“8390...”或“WD....”信息後死機。拔掉NE2000就好了。
解決方案:把你的NE2000地址改為0x340一類的地址。此外,你可以在和“ether=”參數一起使用“reserve=”啟動參數,保護網卡不受其它設備驅動程序檢測的影響。
原因:你的NE2000兼容網卡兼容性不好。一個激活的NE2000是個無底洞,會使其它的驅動程序陷在其空間內進行自動檢測。把NE2000改到一個不常用的地址就可以從其它的自動檢測中消除這一陷阱,機器也就可以啟動了。
問題:機器啟動時在進行SCSI檢測時死機。
原因:這個問題跟上面的一樣,改變以太網卡的地址,或使用reserve/ether啟動參數。
問題:機器啟動時在進行聲卡檢測時死機。
原因:不可能,實際上是發生在靜默方式的SCSI檢測過程中,與上面的問題一樣。
問題:啟動時檢測不到NE2000 - 根本就沒有啟動信息。
解決方案:因為造成檢測不到的原因很多,所以沒有“神奇的解決方案”。下面列出了可能有所幫助的一些措施。
1) 構建一個只包含需要的設備驅動程序的內核。證實你確實是從新內核啟動的。忘記運行lilo等會使你從老的內核啟動。(仔細觀察啟動時報告的構建時間/日期。)聽起來很明顯,但我們以前都犯過這個錯。通過檢查System.map文件裡ne_probe一類的名稱,確定驅動程序已包含在新的內核裡。
2) 仔細觀察啟動信息。看看它是否提及正在進行諸如“NE*000 probe at 0xNNN: not found (blah blah)”一類的ne2k檢測,或者就是靜悄悄地失敗了。這裡的區別很大。使用dmesgmore在登錄後浏覽啟動信息,或者在啟動完成顯示登錄提示符時使用Shift-PgUp卷回屏幕。
3) 啟動後,執行cat /proc/ioports,證實網卡要求的全部I/O空間是空的。如果網卡在0x300,那麼ne2k驅動程序要求的空間為0x300-0x31f。如果其它設備的驅動程序注冊了其中的一個口,就不會對該地址進行檢測,而是靜悄悄地檢測下一個要檢測的地址。常見的情況是lp驅動程序保留了0x378,或者第二個IDE通道保留了0x376,這就使ne驅動程序停止檢測0x360-0x380。
4) 與上面一樣執行cat /proc/interrupts。確定沒有其它設備注冊了你為以太網卡設置的中斷。這種情況下,檢測可以進行,以太網卡驅動程序會在啟動時大聲抱怨無法得到所要求的IRQ中斷線。
5) 如果你還為驅動程序靜悄悄地失敗而苦惱,那麼編輯並給檢測增加一些printk()。比如,對於ne2k,你可以在linux/drivers/net/ne.c中增加/刪除某些行(用 “+”或“-”表示),如下所示: --------------------------------------------------------------------------------
int reg0 = inb_p(ioaddr);
+ printk("NE2k probe - now checking %x\n",ioaddr);
- if (reg0 == 0xFF)
+ if (reg0 == 0xFF) {
+ printk("NE2k probe - got 0xFF (vacant I/O port)\n");
return ENODEV;
+ }
--------------------------------------------------------------------------------
那麼它就會輸出檢查的每一個口地址信息,你可以看到你的網卡地址是否被檢測了。
6) 你還可以從Don的ftp站點(在howto中也提及了)獲取ne2k的診斷程序,看看你在啟動進入Linux後能否用它檢測你的網卡。使用“-p 0xNNN”選項告訴它在哪裡尋找你的網卡。(缺省情況下只檢測0x300,與啟動時的探測不同,不會檢測其它的地址。)在找到網卡時的輸出如下: --------------------------------------------------------------------------------
Checking the ethercard at 0x300.
Register 0x0d (0x30d) is 00
Passed initial NE2000 probe, value 00.
8390 registers: 0a 00 00 00 63 00 00 00 01 00 30 01 00 00 00 00
SA PROM 0: 00 00 00 00 c0 c0 b0 b0 05 05 65 65 05 05 20 20
SA PROM 0x10: 00 00 07 07 0d 0d 01 01 14 14 02 02 57 57 57 57
NE2000 found at 0x300, using start page 0x40 and end page 0x80.
--------------------------------------------------------------------------------
你的注冊值和PROM值可能會不一樣。注意,對16比特網卡,所有PROM值都增加一倍,以太網卡地址(00:00:c0:b0:05:65)出現在第一行,加倍後的0x57標識出現在PROM的結尾。
在0x300處沒有安裝網卡時的輸出如下: --------------------------------------------------------------------------------
Checking the ethercard at 0x300.
Register 0x0d (0x30d) is ff
Failed initial NE2000 probe, value ff.
8390 registers: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
SA PROM 0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
SA PROM 0x10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Invalid signature found, Wordlength 2.
--------------------------------------------------------------------------------
出現值0xff的原因是在讀取空I/O口時返回的就是該值。如果在檢測的區域內有其它硬件,你可以看到一些非0xff的值。
7) 嘗試在運行提供的DOS驅動程序或配置程序之後,從DOS啟動軟盤(通過loadlin)熱啟動進入Linux。這可能會進行一些額外的(即非標准的)“魔法”來初始化網卡。
8) 試一下Russ Nelson的ne2000.com包驅動程序,看它能否看見你的網卡 -- 如果還不行,事情就不大妙了。例如:
A:> ne2000 0x60 10 0x300
所用參數為軟件中斷向量、硬件IRQ和I/O地址。你可以從任意的msdos存檔中的pktdrv11.zip裡找到它 -- 現在的版本大概是11以上了。
5 SMC Ultra/EtherEZ和WD80*3網卡的問題
問題:你得到了如下信息:
eth0: bogus packet size: 65531, status=0xff, nXPg=0xff
原因:是共享內存的問題。
解決方案:最普遍的原因是配置的PCI機器沒有映射到ISA內存設備裡。因此你讀到的是PC的RAM(全都是0xff值),而不是存放接收數據包數據的網卡上的RAM。
另一個容易解決的典型問題是板卡沖突,在此區域有緩存或“shadow ROM”,或者你的ISA總線運行速度高於8Mhz。以太網卡上的內存失效的數目也令人驚奇,所以如果你的以太網卡有診斷程序的話,運行一下。
問題:SMC EtherEZ在非共享內存(PIO)模式下不工作。
原因:老版本的Ultra驅動程序只支持共享內存模式下的操作。
解決方案:版本2.0以上的內核所附驅動程序就支持可編程I/O模式的操作。升級到v2.0以上版本。
問題:老的wd8003或可跳線的wd8013總是得到錯誤的IRQ。
原因:老的wd8003網卡或可跳線的wd8013兼容卡沒有驅動程序可以從中讀取設置的IRQ的EEPROM。如果驅動程序無法讀到IRQ,就嘗試用auto-IRQ發現它。若auto-IRQ返回0,那麼驅動程序就給8比特網卡分配IRQ 5,或者為16比特網卡分配IRQ 16。
解決方案: 使auto-IRQ代碼無效,並在你的模塊配置文件(對於內建的驅動程序則通過啟動參數)告訴內核你把網卡跳成了什麼IRQ。
問題:SMC Ultra網卡被檢測成了wd8013,但IRQ和共享內存地址是錯的。
原因:Ultra網卡看起來跟wd8013很相象,如果內核裡沒有Ultra驅動程序,wd驅動程序就會把ultra誤認為wd8013。ultra檢測在wd之前,所以一般不會出問題。ultra在EEPROM保存的IRQ和內存地址與wd8013保存的位置不同,所以報告的值是假的。
解決方案:只保留需要的驅動程序重新編譯內核。如果你在同一台機器上同時使用wd和ultra網卡,並使用模塊,那麼首先載入ultra模塊就行了。
6 3Com網卡的問題
問題:3c503選擇了IRQ N,但其它設備也需要IRQ N。(比如CD ROM驅動程序、 modem等。)可以不編譯進內核就解決這個問題嗎?
解決方案:3c503驅動程序按照順序{5, 9/2, 3, 4}檢測空閒的IRQ線,從中找到一個未被使用的IRQ。在網卡被ifconfig操作配置時選擇中斷IRQ。
如果你使用的是模塊化的驅動程序,可以用模塊參數設置各種情況,包括中斷IRQ的值。
下面的語句選擇IRQ9、基址0x300、和if_port #1(外部收發器)。
io=0x300 irq=9 xcvr=1
如果驅動程序被編譯進了內核,你還可以通過LILO在啟動時傳遞參數來設置同樣的值。
LILO: linux ether=9,0x300,0,1,eth0
下面的語句選擇IRQ3、檢測基址、和缺省if_port #0(外部收發器)。
LILO: linux ether=3,0,0,0,eth0
問題:3c503: configured interrupt X invalid, will use autoIRQ.
原因:3c503網卡只能使用中斷IRQ{5, 2/9, 3, 4}中的一個(這些是網卡所能連接的中斷線。)如果你使用一個不在其中的IRQ值,就會得到如上的提示。一般情況下,沒必要為3c503指定中斷值。3c503會在ifconfig配置時使用autoIRQ,並從IRQ{5, 2/9, 3, 4}中選擇一個。
解決方案:使用上述的合法IRQ值,或者不指定IRQ以啟用autoIRQ。
問題:提供的3c503驅動程序無法使用AUI(粗纜以太網)端口。怎樣才能不使用缺省的細纜以太網端口而選擇AUI端口?
解決方案:3c503的AUI端口對於內建驅動程序可以在啟動時選擇,對於模塊化驅動程序可以在插入模塊時選擇。這一選擇會覆蓋未使用的dev->rmem_start變量的低比特位,所以啟動參數:
LILO: linux ether=0,0,0,1,eth0
對內建在內核的驅動程序起作用。
要在載入模塊時指定AUI端口,只需把xcvr=1附加在模塊選項包含你的I/O和IRQ值的那一行就行了。。
7 非特定網卡的FAQs
Linux與ISA的即插即用以太網卡
要獲得最佳效果(問題最少),推薦使用隨網卡附的程序(通常是DOS程序)取消PnP機制,並給網卡設置一個固定的I/O地址和IRQ。確定你使用的I/O地址在啟動時被驅動程序檢測到,如果使用模塊,則在/etc/conf.modules中使用io=選項提供地址。你也可以進入BIOS/CMOS設置,把IRQ從PnP改為Legacy-ISA(如果你的計算機有此選項的話)。
注意,運行基於DOS的配置程序一般並不需要安裝DOS。可以用DOS軟盤啟動,然後從提供的軟盤上運行它們就可以了。你可以自由地下載OpenDOS和FreeDOS。
如果需要使用PnP以與其它操作系統兼容,你就得每次啟動時都使用Linux的isapnptools包配置網卡。你還需要確定為網卡選擇的I/O地址被驅動程序檢測到,或用io=選項提供I/O地址。
啟動時沒有檢測到以太網卡
出現這個問題的常見原因是人們使用的內核不支持特定的網卡。對於模塊化的內核,這一般說明要求的模塊尚未被載入,或者需要用模塊選項指定其I/O地址。
如果你使用的是模塊化的內核,就象大多數用Linux發行版安裝的那樣,試著用一下該發行版的配置工具來選擇網卡所用模塊。對於ISA網卡一個較好的主意是,確定網卡的I/O地址,如果配置工具要求選項則把它作為一個選項(如io=0x340)加進去。如果沒有配置工具,那麼你需要在/etc/conf.modules裡添加正確的模塊名稱(及選項)-- 閱讀man modprobe以了解更多的細節。
如果你使用的發行版套件裡的預編譯內核,那麼查看文檔以確定你安裝的是哪一種內核,以及是否支持你所用的網卡。如果不支持的話,要麼試著找一個支持你網卡的內核,要麼自己生成一個內核。
只保留所需的驅動程序生成自己的內核是個聰明的主意,因為這會減小內核大小(為應用程序保留寶貴的RAM!),減少打擾敏感硬件的設備檢測數目。生成內核並不象聽起來那麼復雜。你只需要對一些有關你想要哪些驅動程序的問題回答是或不是,其它的事都由程序完成。
另一個主要原因是其它的設備占用了網卡所需的部分I/O空間。大多數網卡在I/O空間裡占用了16或32個字節。如果你的網卡設在0x300並要求32個字節,那麼驅動程序就要求0x300-0x31f。如果某個其它設備驅動程序注冊了哪怕其中一個端口,驅動程序就不會對該地址進行檢測,而是靜悄悄地進入下一個檢測地址。所以,在啟動之後,運行一下cat /proc/ioports以確定網卡要求的全部I/O空間都是空的。
還有一個問題就是網卡跳到的I/O地址不是缺省檢測的地址。每個驅動程序的檢測地址列表可以很容易地在驅動程序源碼中的文本注釋裡找到。即使網卡設定的I/O地址不在檢測地址列表上,你也可以在啟動時用ether=命令提供(對內建驅動程序),參見傳遞以太網參數...。模塊化的驅動程序可以在/etc/conf.modules裡使用io=選項指定一個非缺省檢測的地址。
ifconfig報告了錯誤的網卡I/O地址
這不可能。你只是理解錯誤。這不是一個Bug,而且報告的數字是正確的。這只出現在某些基於8390的網卡上(如wd80x3、smc-ultra等),實際的8390芯片位於第一個給定I/O端口加上一個偏移量處。此偏移量保存在dev->base_addr裡,也就是ifconfig報告的值。如果你想看到網卡使用的全部端口,試一下cat /proc/ioports以得到想要的數字。
PCI機器探測到了網卡,但驅動程序檢測失敗。
某些PCI的BIOS在上電時沒有啟用所有的PCI卡,特別是在使用了“PNP OS”的BIOS選項情況下。這一特性是為了支持當前依然使用某些實模式驅動程序的Windows版本。或者禁用該選項,或者升級到一個可以啟用被禁用網卡的新驅動程序。
PCI機器裡的共享內存ISA網卡不工作(0xffff)
這常表現為顯示讀出大量0xffff值。除非你正確地設置了PCI ROM BIOS/CMOS SETUP配置,任何類型的共享內存網卡都不會在PCI機器上工作。你必須把網卡所用內存區域設置為可以從ISA總線訪問共享內存。如果你不知道哪些設置有用,那麼詢問你的供應商或者當地的計算機大拿。對於AMI BIOS,在“Plug and Play”部分有一個“ISA Shared Memory Size”和“ISA Shared Memory Base”的設置。對於類似wd8013和SMC Ultra的網卡,把共享內存的大小從缺省的禁用改為16kB,並把基址改為網卡的共享內存地址。
網卡看來在發送數據,但沒有收到過數據。
執行cat /proc/interrupts。這樣產生的列表會顯示網卡產生的所有中斷事件的實時數目。如果為0或在試圖使用網卡時沒有增加,那麼可能是與計算機安裝的其它設備發生物理中斷沖突(無論其它的設備是否安裝/提供了驅動程序)。把其中一個設備的IRQ改為未使用的IRQ。
異步傳輸模式(ATM)支持
Werner Almesberger在進行Linux的ATM的支持工作。他使用的是Efficient Networks的ENI155p板(Efficient Networks)和Zeitnet的ZN1221板(Zeitnet)。
Werner說ENI155p的驅動程序已經很穩定了,而ZN1221的驅動程序還沒有完成。
去下面的連接查看一下最新的進展:
Linux ATM Support
吉比特以太網支持
Linux支持吉比特以太網嗎?
是的,目前至少已經有了兩個驅動程序。在v2.0和v2.2內核裡有一個Packet Engines G-NIC PCI吉比特以太網適配器的驅動程序。驅動程序的更多細節、支持和更新可訪問:
http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.Html
v2.2內核提供的acenic.c驅動程序可用於Alteon的AceNIC吉比特以太網卡和其它如3Com的3c985一類的基於Tigon的網卡。這個驅動程序還可以用於NetGear的GA620,但還需要證實。
FDDI支持
Linux支持FDDI嗎?
是的。Larry Stefani為v2.0編寫了Digital的DEFEA(FDDI EISA)和DEFPA(FDDI PCI)網卡驅動程序。它被包含進v2.0.24內核。目前還沒有其它的網卡被支持。
全雙工支持
全雙工能達到20MBps嗎?Linux支持嗎?
Cameron Spitzer對全雙工10Base-T網卡有如下論斷:“如果你連在全雙工交換HUB上,你的系統足夠快而且不做太多其它的工作,它會使你的網絡在兩個方向上都保持忙碌。不存在什麼全雙工的10BASE-2或10BASE-5(細纜和粗纜)。全雙工是通過取消適配器的碰撞檢測來達到的。這就是為什麼用同軸電纜實現不了全雙工;LAN無法以全雙工方式運轉。 10BASE-T(RJ45接口)使用不同的線進行發送和接收,所以二者可能同時進行。交換HUB處理碰撞問題。信號速率是10Mbps。”
所以,你只能以10Mbps速率接收或發送數據,無法期望得到兩倍的性能提高。對於是否支持,取決於網卡和可能的驅動程序。有些網卡可以自動協商,有些需要驅動程序支持,還有的需要用戶在網卡的EEPROM配置中設置選項。只有那些認真的用戶會注意到全雙工與半雙工模式間的差別。
SMP機器上的Linux以太網卡
如果你有錢買多處理器(MP)的計算機,那麼最好買一個好點兒的以太網卡。對v2.0內核這還不是個問題,但對v2.2就成問題了。大多數老式的非智能(如ISA總線的PIO和共享內存設計)網卡在設計時根本沒考慮多處理器應用。簡單地說就是買一個現代設計的智能網卡,並確定有能夠處理多處理器操作的驅動程序。(注意這裡的“現代設計” - PCI-NE2000就是在現代總線上有10多年歷史的老式設計。)在驅動程序的源碼裡查找spin_lock可以很好地說明該驅動程序是否能夠處理多處理器操作。下面詳細解釋了為何要為多處理器應用購買好的網卡(以及不買會出現什麼問題)。
在v2.0內核,在任意時刻只有一個處理器允許進入“內核態”(即改變內核數據或運行設備驅動程序)。所以從網卡(及相關驅動程序)的角度來看,這與單處理器操作沒有什麼不同,所以不會出問題。(這也是得到一個可以工作的Linux多處理器版本的最簡單的辦法 -- 使用一個大鎖使得一次只有一個處理器處於內核狀態。這樣你就知道不可能有兩個處理器同時要修改同一數據!)
在任意時刻只有一個處理器允許進入內核態的不利之處在於只有運行自我控制和密集計算的程序時才會獲得多處理器的優越性。如果程序進行了大量諸如向磁盤或網絡讀/寫數據的I/O操作,在處於內核的那個處理器努力運行所有的設備驅動程序以滿足I/O請求的同時,其它的處理器都必須等待自己的I/O請求被處理完成。這樣內核就成為了瓶頸,由於只有一個處理器運行在內核態,多處理器機器的性能在I/O任務重、單鎖的情況下迅速降級到接近單處理器的水平。
很明顯這與理想情況相差太遠(尤其是對於文件/WWW服務器、路由器等),v2.2的內核就使用了粒度更小的鎖——也就是說同時可以有多個處理器進入內核。不再是對整個內核使用一個大鎖,而是使用許多較小的鎖保護關鍵數據,防止同時被多個處理器控制——例如,一個處理器可以運行網卡驅動程序,同時另一個處理器可以運行磁盤驅動器的驅動程序。
好的,這樣就有問題了:更小的鎖定就意味著可以有一個處理器試圖通過以太網驅動程序發送數據,同時另一個處理器試圖訪問同一個驅動程序/網卡來做別的事情(比如通過cat /proc/net/dev得到網卡統計數據)。哎呦——你的網卡正在通過網線發數據,你又要用它來收數據。網卡被同時要求做兩件事(或更多),會弄糊塗的,所以有可能在處理過程中網卡使你的機器死機。
因此,為單處理器寫的驅動程序不再適用——它需要更新控制對網卡訪問的鎖,使得網卡的接收、發送和操作配置數據這三種任務以網卡穩定操作所要求的程度串行化起來。沒有更新為使用穩定多處理器操作的鎖的驅動程序在輕的網絡負載下可能看起來會正常工作,但在兩個(或更多)處理器試圖同時進行多個任務時就會造成死機,或至少表現出奇怪的行為,這就是問題。
更新後的意識到多處理器的以太網驅動程序將要求一個驅動程序范圍的鎖,使得內核進入驅動程序的訪問入口被限制為一次一個。這樣,任務就被串行化,而對硬件的處理就如同在單處理器下一樣,也就一定應當穩定。使用驅動程序范圍的鎖的不利之處在於它類似於對整個內核加鎖(但規模較小)對性能的影響——也就是說,一次只可以有一個處理器處理網卡。[技術提示:如果增加的鎖是irqsave類型的而且被持有較長時間,對性能的影響還包括增加了中斷延遲。]
這裡可以進行的改進有兩處。可以嘗試減少獲得與釋放鎖之間所用的時間,或者在驅動程序內部實現更為細化的鎖(比如滿足網卡需求的前提下,把整個驅動程序的鎖替換為若干保護同時訪問若干敏感寄存器或設置的鎖)。
但是,對於老式的非智能網卡而言,在設計時根本就沒有考慮過多處理器的應用,這樣的改進可能無法實現。更糟的是非智能網卡一般要求處理器在網卡和內存之間傳送數據,所以在最壞的情況下,每當在ISA總線傳送1.5kB數據包時,鎖都被一直保持著。
現代的智能網卡一般無需處理器的幫助就可以直接在網卡和內存之間傳遞網絡數據。這是個很大的改進,因為只需要在處理器通知網卡使用哪一塊內存保存下一個網絡數據包的那一小段時間持有鎖。現代的網卡在設計時同樣也不要求對整個驅動程序使用一個大鎖。
Alpha/AXP的PCI板上的Linux以太網卡
對於v2.0,只有3c509、depca、de4x5、pcnet32和所有8390驅動程序(wd、smc-ultra、ne、3c503等等)是編寫成“結構無關”的,所以它們可以運行在基於DEC的Alpha CPU系統上。其它一些從Donald的WWW主頁上下載的更新過的PCI驅動程序也可以工作,因為它們也是按照結構無關的思想編寫的。
注意,使驅動程序與結構無關所需要進行的改動並不很復雜。只需要如下進行:
--把所有與jiffies有關的值都乘以HZ/100,得到Alpha使用的不同的HZ值。(即timeout=2;變成timeout=2*HZ/100;)
--把所有I/O內存(從640k到1MB)的指針引用替換為相應的readb() writeb() readl() writel()調用,如下例所示。 --------------------------------------------------------------------------------
- int *mem_base = (int *)dev->mem_start;
- mem_base[0] = 0xba5eba5e;
+ unsigned long mem_base = dev->mem_start;
+ writel(0xba5eba5e, mem_base);
--------------------------------------------------------------------------------
--把所有使用I/O內存作為源或目的地址的memcpy()調用替換為相應的memcpy_fromio()或者memcpy_toio()調用。
以結構無關的方式處理內存訪問的細節在近期的內核所附的文件linux/Documentation/IO-mapping.txt中進行了說明。
SUN/Sparc硬件上的Linux以太網卡
要得到最新的Sparc信息,可以訪問以下URL:
Linux Sparc
注意,有些Sparc的以太網硬件從主機獲得其MAC地址,因此可能會有多個接口具有相同的MAC地址。如果想在同一個網絡上使用多個接口,可以使用ifconfig的hw選項以分配唯一的MAC地址。
把PCI驅動程序移植到Sparc平台上與上面提到的AXP平台相似。可能的差異出在endian上,因為Sparc是big endian,而AXP和ix86是little endian。
其它硬件上的Linux以太網卡
還有一些其它硬件平台可以運行Linux,比如Atari/Amiga(m68k)。就象Sparc一樣,最好是訪問每個Linux支持的平台主頁,以了解當前都支持哪些硬件。(歡迎提供這樣的站點連接——把它們發給我!)
不使用Hub連接10/100BaseT
可以不使用Hub連接基於10/100BaseT(RJ45)的系統嗎?
如果不使用額外的設備或機械裝置,可以很容易地連接兩台這樣的機器,但不可能再多。參閱雙絞線——解釋了如何做到這一點。而且你不可能簡單地交叉幾根線或其它什麼就弄出一個Hub,不復制Hub也無法正確完成沖突信號。
SIOCSIFxxx: No sUCh device
在啟動時出現了一大堆“SIOCSIFxxx: No such device”信息,後面還有一條“SIOCADDRT: Network is unreachable”,怎麼回事?
你的以太網設備在啟動/插入模塊時沒有被檢測到,當ifconfig和route運行時,它們沒有可用的設備。使用dmesg more來浏覽啟動信息,看看有沒有檢測以太網卡的信息。
SIOCSFFLAGS: Try again
在運行“ifconfig”時出現“SIOCSFFLAGS: Try again”——怎麼回事?
某些其它的設備使用了以太網卡想用的IRQ,所以以太網卡無法使用該IRQ。你不必重新啟動來解決這個問題,因為某些設備只是在需要時才獲取IRQ,在完成後就釋放了。例如某些聲卡、串口、軟盤驅動器等。你可以鍵入cat /proc/interrupts來看看哪些中斷正在被使用。絕大多數Linux以太網卡驅動程序只有在用“ifconfig”打開時才獲取IRQ。如果你能讓其它設備“放開”所需的IRQ中斷線,那麼你就可以用ifconfig來“再試一下”了。
使用“ifconfig”得到的連接為UNSPEC,而硬件地址是00:00:00:00:00:00
在不帶參數運行ifconfig時,報告說連接為UNSPEC(而不是10Mbs以太網),而且硬件地址都是零。
這是因為運行的“ifconfig”程序版本比內核的版本高。在與老版本的內核一起運行時,新版本的ifconfig無法報告這些特性。你可以升級內核,或者“降級”ifconfig,或者干脆不理會這個錯誤。內核知道硬件地址,所以即使ifconfig無法讀出它也沒有關系。
如果使用的ifconfig程序比使用的內核舊很多的話,也會出現一些奇怪的信息。
大量的RX和TX錯誤
在不帶參數運行ifconfig時,報告大量的接收和發送數據包錯誤。但看起來工作正常——怎麼回事?
再看一遍。報告是說RX packets big number 停頓 errors 0 停頓 dropped 0 停頓 overrun 0。所以你看到的那個大數字是機器接收和發送的數據包總數。如果還覺得不可思議,鍵入cat /proc/net/dev試試。
/dev/下以太網卡的入口
/dev/eth0象是個到/dev/xxx的連接。這樣對嗎?
與你聽過的正好相反,/dev/*下的文件沒被使用。你可以刪除掉任何/dev/wd0, /dev/ne0以及類似的入口。
Linux與“trailers”
在“ifconfig”網卡時,需要禁止trailers嗎?
不能禁止trailers,而且也沒必要。“trailers”是避免在網絡層復制數據的工具。其想法是使用一個大小為“H”的固定大小的頭,把可變大小的頭信息放在包的尾部,並把所有包定位在頁開始之前的“H”字節。這只是個好想法,在實際中工作得並不好。如果有人建議使用“-trailers”,那不過是找個替罪羊罷了。這對解決問題沒有任何意義,但如果問題真的自行解決了,那麼他就可以吹噓自己的神奇本領了。 訪問原始以太網設備
在Linux下怎樣不通過TCP/IP之類的東西訪問原始的以太網設備? --------------------------------------------------------------------------------
int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));
--------------------------------------------------------------------------------
這樣就可以得到一個接收所有協議類型的socket。對它執行recvfrom()調用,它就會用sa_family裡的設備類型和sa_data數組裡的設備名來填充sockaddr。我不知道是誰最早在Linux裡使用SOCK_PACKET,但它確實是個非常好的東西。你也可以通過sendto()調用發送原始數據包。當然,在這樣做時你必須擁有root的權限。
Alpha/AXP的PCI板上的Linux以太網卡
對於v2.0,只有3c509、depca、de4x5、pcnet32和所有8390驅動程序(wd、smc-ultra、ne、3c503等等)是編寫成“結構無關”的,所以它們可以運行在基於DEC的Alpha CPU系統上。其它一些從Donald的WWW主頁上下載的更新過的PCI驅動程序也可以工作,因為它們也是按照結構無關的思想編寫的。
注意,使驅動程序與結構無關所需要進行的改動並不很復雜。只需要如下進行:
--把所有與jiffies有關的值都乘以HZ/100,得到Alpha使用的不同的HZ值。(即timeout=2;變成timeout=2*HZ/100;)
--把所有I/O內存(從640k到1MB)的指針引用替換為相應的readb() writeb() readl() writel()調用,如下例所示。 --------------------------------------------------------------------------------
- int *mem_base = (int *)dev->mem_start; - mem_base[0] = 0xba5eba5e; + unsigned long mem_base = dev->mem_start; + writel(0xba5eba5e, mem_base);
--------------------------------------------------------------------------------
--把所有使用I/O內存作為源或目的地址的memcpy()調用替換為相應的memcpy_fromio()或者memcpy_toio()調用。
以結構無關的方式處理內存訪問的細節在近期的內核所附的文件linux/Documentation/IO-mapping.txt中進行了說明。
SUN/Sparc硬件上的Linux以太網卡 要得到最新的Sparc信息,可以訪問以下URL:
Linux Sparc
注意,有些Sparc的以太網硬件從主機獲得其MAC地址,因此可能會有多個接口具有相同的MAC地址。如果想在同一個網絡上使用多個接口,可以使用ifconfig的hw選項以分配唯一的MAC地址。
把PCI驅動程序移植到Sparc平台上與上面提到的AXP平台相似。可能的差異出在endian上,因為Sparc是big endian,而AXP和ix86是little endian。
其它硬件上的Linux以太網卡 還有一些其它硬件平台可以運行Linux,比如Atari/Amiga(m68k)。就象Sparc一樣,最好是訪問每個Linux支持的平台主頁,以了解當前都支持哪些硬件。(歡迎提供這樣的站點連接——把它們發給我!)
不使用Hub連接10/100BaseT 可以不使用Hub連接基於10/100BaseT(RJ45)的系統嗎?
如果不使用額外的設備或機械裝置,可以很容易地連接兩台這樣的機器,但不可能再多。參閱雙絞線——解釋了如何做到這一點。而且你不可能簡單地交叉幾根線或其它什麼就弄出一個Hub,不復制Hub也無法正確完成沖突信號。
SIOCSIFxxx: No sUCh device 在啟動時出現了一大堆“SIOCSIFxxx: No such device”信息,後面還有一條“SIOCADDRT: Network is unreachable”,怎麼回事?
你的以太網設備在啟動/插入模塊時沒有被檢測到,當ifconfig和route運行時,它們沒有可用的設備。使用dmesg more來浏覽啟動信息,看看有沒有檢測以太網卡的信息。
SIOCSFFLAGS: Try again 在運行“ifconfig”時出現“SIOCSFFLAGS: Try again”——怎麼回事?
某些其它的設備使用了以太網卡想用的IRQ,所以以太網卡無法使用該IRQ。你不必重新啟動來解決這個問題,因為某些設備只是在需要時才獲取IRQ,在完成後就釋放了。例如某些聲卡、串口、軟盤驅動器等。你可以鍵入cat /proc/interrupts來看看哪些中斷正在被使用。絕大多數Linux以太網卡驅動程序只有在用“ifconfig”打開時才獲取IRQ。如果你能讓其它設備“放開”所需的IRQ中斷線,那麼你就可以用ifconfig來“再試一下”了。
使用“ifconfig”得到的連接為UNSPEC,而硬件地址是00:00:00:00:00:00 在不帶參數運行ifconfig時,報告說連接為UNSPEC(而不是10Mbs以太網),而且硬件地址都是零。
這是因為運行的“ifconfig”程序版本比內核的版本高。在與老版本的內核一起運行時,新版本的ifconfig無法報告這些特性。你可以升級內核,或者“降級”ifconfig,或者干脆不理會這個錯誤。內核知道硬件地址,所以即使ifconfig無法讀出它也沒有關系。
如果使用的ifconfig程序比使用的內核舊很多的話,也會出現一些奇怪的信息。
大量的RX和TX錯誤 在不帶參數運行ifconfig時,報告大量的接收和發送數據包錯誤。但看起來工作正常——怎麼回事?
再看一遍。報告是說RX packets big number 停頓 errors 0 停頓 dropped 0 停頓 overrun 0。所以你看到的那個大數字是機器接收和發送的數據包總數。如果還覺得不可思議,鍵入cat /proc/net/dev試試。
/dev/下以太網卡的入口 /dev/eth0象是個到/dev/xxx的連接。這樣對嗎?
與你聽過的正好相反,/dev/*下的文件沒被使用。你可以刪除掉任何/dev/wd0, /dev/ne0以及類似的入口。
Linux與“trailers” 在“ifconfig”網卡時,需要禁止trailers嗎?
不能禁止trailers,而且也沒必要。“trailers”是避免在網絡層復制數據的工具。其想法是使用一個大小為“H”的固定大小的頭,把可變大小的頭信息放在包的尾部,並把所有包定位在頁開始之前的“H”字節。這只是個好想法,在實際中工作得並不好。如果有人建議使用“-trailers”,那不過是找個替罪羊罷了。這對解決問題沒有任何意義,但如果問題真的自行解決了,那麼他就可以吹噓自己的神奇本領了。 訪問原始以太網設備 在Linux下怎樣不通過TCP/IP之類的東西訪問原始的以太網設備? --------------------------------------------------------------------------------
int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));
--------------------------------------------------------------------------------
這樣就可以得到一個接收所有協議類型的socket。對它執行recvfrom()調用,它就會用sa_family裡的設備類型和sa_data數組裡的設備名來填充sockaddr。我不知道是誰最早在Linux裡使用SOCK_PACKET,但它確實是個非常好的東西。你也可以通過sendto()調用發送原始數據包。當然,在這樣做時你必須擁有root的權限。
如果使用的ifconfig程序比使用的內核舊很多的話,也會出現一些奇怪的信息。
大量的RX和TX錯誤 在不帶參數運行ifconfig時,報告大量的接收和發送數據包錯誤。但看起來工作正常——怎麼回事?
再看一遍。報告是說RX packets big number 停頓 errors 0 停頓 dropped 0 停頓 overrun 0。所以你看到的那個大數字是機器接收和發送的數據包總數。如果還覺得不可思議,鍵入cat /proc/net/dev試試。
/dev/下以太網卡的入口 /dev/eth0象是個到/dev/xxx的連接。這樣對嗎?
與你聽過的正好相反,/dev/*下的文件沒被使用。你可以刪除掉任何/dev/wd0, /dev/ne0以及類似的入口。
Linux與“trailers” 在“ifconfig”網卡時,需要禁止trailers嗎?
不能禁止trailers,而且也沒必要。“trailers”是避免在網絡層復制數據的工具。其想法是使用一個大小為“H”的固定大小的頭,把可變大小的頭信息放在包的尾部,並把所有包定位在頁開始之前的“H”字節。這只是個好想法,在實際中工作得並不好。如果有人建議使用“-trailers”,那不過是找個替罪羊罷了。這對解決問題沒有任何意義,但如果問題真的自行解決了,那麼他就可以吹噓自己的神奇本領了。 訪問原始以太網設備 在Linux下怎樣不通過TCP/IP之類的東西訪問原始的以太網設備? --------------------------------------------------------------------------------
int s=socket(AF_INET,SOCK_PACKET,htons(ETH_P_ALL));
--------------------------------------------------------------------------------
這樣就可以得到一個接收所有協議類型的socket。對它執行recvfrom()調用,它就會用sa_family裡的設備類型和sa_data數組裡的設備名來填充sockaddr。我不知道是誰最早在Linux裡使用SOCK_PACKET,但它確實是個非常好的東西。你也可以通過sendto()調用發送原始數據包。當然,在這樣做時你必須擁有root的權限。