文/馬馬
【任務】
在一台Linux機器上,通過ISDN撥號上網。
【筆者的配置】
藍點Linux 2.0、Kernel-2.2.16、isdn4linux v3.1pre1,上海貝爾生產的ISDN內置卡,型號為SBT6021。
內核支持
上海貝爾SBT6021型ISDN內置卡,使用的芯片為Winbond W6692,這是一種與西門子“HiSax”驅動程序兼容的芯片,該卡是即插即用的,無需手工設置中斷請求和I/O地址。但需要Linux內核支持這種內置卡,在編譯內核時,必須選中下列選項:
ISDN Support
Support synchronous PPP
(多數ISDN設備撥號上網都是使用同步PPP方式)
Hisax SiemensChipset driver support
Hisax Support for DSS1
(絕大多數ISDN設備使用的協議都是DSS1)
Hisax Support for Winbond W6692
大家不必急於編譯內核,如果現有的內核已經包含這些選項了,那麼就不必再重復一遍了。那怎麼知道現有內核是否已經包含這些選項了呢?看內核編譯配置文件“/usr/src/linux/.config”(注意:文件名以“.”開頭的文件是隱藏文件,要用“ls -a”才可看到)。大家若看到其中有下面這5行內容,對應於剛才的5個選項:
CONFIG_ISDN=m
CONFIG_ISDN_PPP=y
CONFIG_ISDN_DRV_HISAX=m
CONFIG_HISAX_EURO=y
CONFIG_HISAX_W6692=y
“=y”是表示內核直接支持(代碼已鏈入內核中),“=m”表示模塊支持(代碼在另外的內核中,可由內核載入)。這就表明,藍點Linux 2.0的原有內核已包含這些選項,大家就不用重新編譯這些內核了。
isdn4linux安裝
欲配置ISDN,要用到isdn4linux這一套軟件。isdn4linux的主要文件有isdnctrl、ipppd等。
isdn4linux的源代碼可以到以下網站獲取:http://isdn4linux.org,下載得到文件為“isdn4k-utils.v3.1pre1.tar.gz”,放到“/usr/src”目錄下。接下來進入“/usr/src”目錄中,開始安裝過程。
cd /usr/src (先進入“/usr/src”)
tar xzvf isdn4k-utils.v3.1pre1.tar.gz (解開壓縮文件)
命令完成後能看到多了一個子目錄,isdn4k-utils,isdn4linux的源代碼文件就在其中。
進入該子目錄:cd isdn4k-utils
該目錄中的“README”文件詳細介紹了如何安裝“isdn4linux”,可以參考說明即可。
接著是進行配置(命令是:make config),不做任何改變,用缺省的即可。
下一步是開始編譯:make
結果未能通過,失敗原因是“linux/ autoconf.h”文件或目錄不存在。這個文件就是“/usr/include/linux/autoconf.h”文件,一查確實不存在。它是在編譯內核的時候生成的,而我們並未編譯內核,所以當然沒有了。好吧,想辦法生成它。先進入linux目錄並進行配置:
cd /usr/src/linux
make menuconfig
不做任何改變,退出,保存即可。此時一看,“/usr/include/linux/autoconf.h”文件出來了,這就夠了,不必真的去編譯內核。
接著回到isdn4linux目錄再編譯:
cd /usr/src/isdn4k-utils
make
剛才的問題沒有了,但還是未能通過,失敗原因是capi20/capi20.c文件中下面幾個參量未定義:
CAPI_GET_FLAGS
CAPI_SET_FLAGS
CAPI_CLR_FLAGS
CAPI_NCCI_GETUNIT
CAPI_NCCI_OPENCOUNT
這5個參量分別出現在一段源代碼中,本文選取一段說明,其余相同:
int capi20ext_get_flags(unsigned ApplID,unsigned *flagsptr)
{
if (ioctl(applid2fd(ApplID),CAPI_GET_FLAGS,flagsptr) < 0)
return CapiMsgOSResourceErr;
return CapiNoError;
}
這些參量作者未定義它們,筆者也不知道這幾個常量該是多少,怎麼辦?查看capi20/capi20.h文件發現,這幾個函數是“extentions functions (no standard functions)”(擴展的非標准函數)。筆者猜測,即使這幾個函數功能不正確,也該不會影響ISDN的使用,於是,我們就可以把那幾個未定義的符號注解起來,使編譯通過。修改源代碼如下:
int
capi20ext_get_flags(unsigned ApplID,unsigned *flagsptr)
{
// if (ioctl(applid2fd(ApplID),CAPI_GET_FLAGS,flagsptr) < 0)
// return CapiMsgOSResourceErr;
return CapiNoError;
}
再次編譯,通過了。接著繼續安裝:make install,命令完成後,復制isdnctrl和ipppd到/sbin目錄下。
ISDN基本配置
參照別人文章中的例子,修改其中的電話號碼、用戶名等相關內容,然後運行。很不幸,沒有成功。因為這些例子都比較完善且復雜,也就難免和筆者的配置情況不符。只好從簡單入手,只進行最基本最必要的配置,暫時先不寫成shell文件,逐條命令輸入並執行,仔細理解其意義,查看其執行結果。等到全部測試成功後,再寫成shell文件。現在看來,這種做法很有效,因此可以同樣來處理類似的問題。
配置ISDN:
echo 1 > /proc/sys/net/ipv4/ip_ dynaddr
撥號上網大部分都是使用動態IP地址,我們不知道遠程撥號服務器的IP地址是多少,也不可能知道它會給電腦分配什麼IP地址。在“/proc/sys/net/ipv4/ip_dynaddr”中寫入“1”,就是告訴內核要使用動態IP地址。
modprobe hisax type=36 protocol=2
安裝ISDN卡的驅動程序。前面已經說過,上海貝爾SBT6021型ISDN內置卡中使用的芯片W6692是由HiSax驅動程序驅動的,type=36是指使用W6692芯片,protocol=2指ISDN協議是用“DSS1”,詳細內容可參看“/usr/src/linux/ Documentation/isdn/README.HiSax”文件。
isdnctrl addif ippp0
ISDN通過同步“PPP”方式上網,其對應的接口(Interface)會是“/dev/ippp0”、“/dev/ippp1”等。這條命令告訴內核,加入“ippp0”這個Interface,換句話說,告訴內核有個ISDN設備,准備通過同步PPP方式上網。從此以後,“ippp0”就代表了筆者的ISDN設備。
isdnctrl addphone ippp0 out 163
指撥叫的電話號碼,這裡是163,通過中國電信撥號上網的大部分也都是163。
isdnctrl eaz ippp0 2024245
指筆者自己這台ISDN的電話號碼為2024245。
isdnctrl l2_prot ippp0 hdlc
第2層協議用的是“hdlc”。
isdnctrl l3_prot ippp0 trans
第3層協議用的是“trans”。
isdnctrl encap ippp0 syncppp
用同步PPP方式。
isdnctrl dialmode ippp0 manual
手工撥號方式,在此方式下,撥號時用“isdnctrl dial ippp0”命令,掛斷時用“isdnctrl hangup ippp0”命令。另外還有“auto”(自動方式),不過,還是先用手工方式比較直觀穩定。
isdnctrl dialmax ippp0 3
1次撥號有可能連不通,不要緊,程序會自動重撥的,這裡規定了最多重撥3次。
isdnctrl huptimeout ippp0 500
線路空閒一段時間後,會自動掛斷,缺省是空閒10秒後掛斷,太短了,筆者改為500秒。
普通網絡配置
Linux的普通網絡配置主要包含兩個方面:1)對各接口本身的配置,Interface是指以太網卡、Modem、ISDN等設備;配置信息包括網絡地址、子網掩碼、網關等;相應的配置工具為ifconfig程序。2)對路由表的配置。路由表規定了到各個目的地的數據包應走哪個網關,使用哪個Interface等,相應的配置工具為route程序。
在進行配置之前,先看一下目前的配置情況是什麼樣的。筆者的Linux機器在一個局域網上,局域網的域名為server.net,地址為203.0.0.111,這台機器的主機名為admin,地址為203.0.0.1。
用ifconfig命令查看Interface配置,顯示信息如下:
eth0 Link encap:Ethernet HWaddr 00:20:AF:F1:0A:4A
inet addr:203.0.0.1 Bcast:203.0.0.255 Mask:255.255.255.0
...
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
...
顯示信息表明:有2個Interface,“eth0”代表以太網卡;“lo”是個虛擬的“loopback”設備。
接著用route命令看路由表配置,顯示信息如下:
Kernel IP routing table
Destination adminway Genmask Flags Metric Ref Use Iface
admin.server.net * 255.255.255.255 UH 0 0 0 eth0
203.0.0.111 * 255.255.255.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
信息表明,有3條路由信息。要用上ISDN(ippp0),必須用“ifconfig”對“ippp0”進行配置,並用“route”增加1條使用它的路由。配置ippp0:
ifconfig ippp0 0.0.0.0 pointopoint 0.0.0.0 netmask 0.0.0.0
使用PPP(pointopoint)協議,“point to point”前面是本機地址,後面是遠程服務器地址,這裡全是0.0.0.0,行嗎?行,因為前面已經作了配置“echo 1 > /proc/sys/net/ipv4/ip_ dynaddr”,告訴內核將使用動態IP地址,因此在這裡用0.0.0.0並無所謂,當這個PPP連接建立起來後,它會自動用真正的IP地址代替這些0.0.0.0的。
此時再用ifconfig查看,得到如下類似信息:
eth0 Link encap:Ethernet HWaddr 00:20:AF:F1:0A:4A
inet addr:203.0.0.1 Bcast:203.0.0.255 Mask:255.255.255.0
...
ippp0 Link encap:Point-to-Point Protocol
UP POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:30
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
...
發現多了1個“ippp0 Interface”,但由於未曾建立真正的連接,它的本機地址和遠程服務器地址都未給出。於是增加1條使用ippp0的路由:
route add default ippp0
這裡指定缺省(default)的數據包都經過“ippp0”傳送。缺省的數據包?什麼意思?前面,筆者用route查看時有3條路由信息,這些信息指定了發往3個目的地(Destination)的數據包該怎麼走,其他沒有指定怎麼走的數據包(在這裡,就是除了那3種數據包之外的所有數據包),即為缺省數據包,比如要到168.160.224.103(新浪網sina.com.cn)的數據包,就屬於缺省數據包。於是這條命令就做到了這一點:如果要上新浪網看新聞,就得經過“ippp0(ISDN)”,這正是筆者所希望的。這時候再用route查看一下情況如何:
Kernel IP routing table
Destination adminway Genmask Flags Metric Ref Use Iface
admin.server.net?255.255.255.255 UH 0 0 0 eth0
203.0.0.111?255.255.255.0 U 0 0 0 eth0
127.0.0.0?255.0.0.0 U 0 0 0 lo
default?0.0.0.0 U 0 0 0 ippp0
其中,“default”路由信息多了1條,注意其對應的gateway是“?”。需要有一個後台服務程序“ipppd”來為ISDN PPP服務:
ipppd user abc noipdefault ipcp-accept -local ipcp-accept-remote defaultroute mru 1500 mtu 1500 /dev/ippp0 &&
前面的user abc指定了用戶名為abc,口令呢?多數163撥號上網使用的認證方法都是“PAP”認證,用戶名、口令信息放在“/etc/ppp/pap- secrets”文件中,這裡的用戶名為abc,口令為199198(筆者隨便定的),於是修改“/etc/ppp/ pap-secrets”文件如下:
# Secrets for authentication using PAP
# client server secret IP addresses
abc?199198
後面的“noipdefault ipcp-accept-local ipcp-accept-remote”指接受遠程撥號服務器分配的本機地址和遠程服務器地址,這正是動態IP地址的含義。“defaultroute”指當連接建立起來後,增加“default”路由條目,這是很關鍵的。“mru 1500 mtu 1500”指最大發送單元和最大接收單元均為1500字節。這個程序為“/dev/ippp0”提供服務。
測試
好,當配置工作完成後,試一下。撥號:
isdnctrl dial ippp0
用ifconfig查看一下,得到類似下面的信息:
eth0 Link encap:Ethernet HWaddr 00:20:AF:F1:0A:4A
inet addr:203.0.0.1 Bcast:203.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::220:afff:fef1:a4a/10 Scope:Link
inet6 addr: fe80::20:aff1:a4a/10 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29 errors:0 dropped:0 overruns:0 frame:0
TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:10 Base address:0x6000
ippp0 Link encap:Point-to-Point Protocol
inet addr:61.229.52.17 P-t-P:202.103.229.38 Mask:255.0.0.0
UP POINTOPOINT RUNNING NOARP MTU:1500 Metric:1
RX packets:22 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:30
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:3924 Metric:1
RX packets:43 errors:0 dropped:0 overruns:0 frame:0
TX packets:43 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
“ippp0”中的本機地址(inet addr)是61.229.52.17,PPP遠程服務器地址(P-t-P)是202.103.229.38,代替了原來指定的0.0.0.0,說明動態IP地址是起作用的。
route
得到類似下面的信息:
Kernel IP routing table
Destination adminway Genmask Flags Metric Ref Use Iface
admin.server.net?255.255.255.255 UH 0 0 0 eth0
203.0.0.111?255.255.255.0 U 0 0 0 eth0
127.0.0.0?255.0.0.0 U 0 0 0 lo
202.0.0.0?255.0.0.0 U 0 0 0 ippp0
default 202.103.229.38 0.0.0.0 UG 0 0 0 ippp0
“default”對應的“gateway”是202.103.229.38,代替了原來的“?”,再看清楚點,它正好是“ippp0”的遠程服務器地址。
怎麼知道ISDN的狀態呢?
imontty
得到類似下面的信息:
ISDN channel status:
Channel Usage Type Number
HiSax Out Net 163
HiSax Off
“HiSax1”是連出去了(Out),撥打號碼是163。
看到歸看到,還得實際測試一下才知道行不行。ping 202.103.223.98 (廣西賀州視窗網站)
結果顯示線路是通的。
ping sina.com.cn
不行了。出現域名解析的問題,找到“/etc/resolv.conf”文件,修改如下:
nameserver 127.0.0.1
指明域名服務器為127.0.0.1(虛擬的loopback),實際上經路由表中的“default”條目,轉發到遠程服務器上,暗度陳倉了。再ping sina.com.cn,OK。
要掛斷,使用命令:
isdnctrl hangup ippp0
如果想要恢復原狀,繼續下面的動作,和剛才的撥號配置正好一一相反。
kill ipppd
停止ipppd服務。
route del default
去掉路由表中增加的條目。
ifconfig ippp0 down
isdnctrl delif ippp0
關停並刪除ippp0 Interface。
modprobe -r hisax
卸下驅動程序。
形成shell文件
逐行命令操作全部通過後,下面就可以把它們寫成shell文件。
“/etc/ppp/isdn-start”文件內容如下:
# Dyna address
echo 1>/proc/sys/net/ipv4/ip_dynaddr
# Load module
modprobe hisax type=36 protocol=2
# Add and config ISDN interface
isdnctrl addif ippp0
isdnctrl addphone ippp0 out 163
isdnctrl eaz ippp0 3382460
isdnctrl l2_prot ippp0 hdlc
isdnctrl l3_prot ippp0 trans
isdnctrl encap ippp0 syncppp
isdnctrl dialmode ippp0 manual
isdnctrl dialmax ippp0 3
isdnctrl huptimeout ippp0 600
ifconfig ippp0 0.0.0.0 pointopoint 0.0.0.0 netmask 0.0.0.0
# Add to routing table
route add default ippp0
# Run ipppd
ipppd user abc
noipdefault
ipcp-accept-local
ipcp-accept-remote
defaultroute
mru 1500
mtu 1500
/dev/ippp0 &&
# Dial
isdnctrl dial ippp0
/etc/ppp/isdn-stop文件內容如下:
# Hangup
isdnctrl hangup ippp0
# Stop ipppd
kill ipppd
# Remove from routing table
route del default
# Del ISDN interface
ifconfig ippp0 down
isdnctrl delif ippp0
# Unload module
modprobe -r hisax
讓它們成為可執行文件:
chmod a+x /etc/ppp/isdn-start
chomd a+x /etc/ppp/isdn-stop
以後的事情就簡單了。要撥號上網,使用命令“/etc/ppp/isdn-start”;要下線掛斷,使用命令“/etc/ppp/isdn-stop”。
筆者的Linux機器是在一個局域網上的,現在這台機器可以上網了,怎麼讓局域網內的其他Win 98/ME/2000機器通過這台機器也能上網呢?其中一個簡單的方法就是使用“IP Masquerade”(IP偽裝)技術,這樣就可以實現一機代理多機上網了。