熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

在Linux下使用ISDN撥號上網

2013-11-13 12:45:02  來源: Oracle 

  作 者 張中華
  
  任務在一台Linux機器上通過ISDN撥號上網
  
  經過嘗試我成功地做到了這一點我的配置為藍點Linux Kernelisdnlinux vpre上海貝爾生產的ISDN內置卡型號為SBT
  下面介紹具體做法介紹順序為內核>isdnlinux安裝>撥號配置>測試
  
   內核
  上海貝爾SBT型ISDN內置卡使用的芯片為Winbond W這是一種與西門子HiSax驅動程序兼容的芯片該卡是即插即用的無需手工設定中斷請求號和I/O地址要Linux內核支持這種卡在編譯內核時必須選中下列選項
  
  ISDN Support
  Support synchronous PPP
  (多數ISDN設備撥號上網都是使用同步PPP方式)
  Hisax SiemensChipset driver support
  Hisax Support for DSS
  (絕大多數ISDN設備使用的協議都是DSS
  Hisax Support for Winbond W
  
  但我不必急於編譯內核如果現有的內核已經包含這些選項了我又何必重復一遍呢那我怎麼知道現有內核是否已經包含這些選項了呢?看內核編譯配置文件/usr/src/nfig(注意文件名以開頭的文件是隱藏文件要用ls a才可看到)我看到其中有下面這行內容對應於剛才的個選項
  
  CONFIG_ISDN=m
  CONFIG_ISDN_PPP=y
  CONFIG_ISDN_DRV_HISAX=m
  CONFIG_HISAX_EURO=y
  CONFIG_HISAX_W=y
  
  =y表示內核直接支持(代碼已鏈入內核中)=m表示模塊支持(代碼在另外的內核中可由內核載入)於是這就表明藍點Linux 的原有內核已包含這些選項了我就不用重新編譯內核啦
  
   isdnlinux安裝
  欲配置ISDN要用到isdnlinux這一套軟件isdnlinux的主要文件有isdnctrl ipppd等
  獲取isdnlinux源碼的地址為
  
  取得的文件為isdnkutilsvpretargz放於/usr/src目錄下
  進入/usr/src目錄中開始安裝過程
  進入/usr/src
  cd /usr/src
  解開壓縮文件
  tar xzvf isdnkutilsvpretargz
  命令完成後多了一個子目錄isdnkutilsisdnlinux的源碼文件就在其中
  進入該子目錄
  cd isdnkutils
  該目錄中的README文件詳細介紹了如何安裝isdnlinux照章行事即可
  進行配置
  make config
  不做任何改變用缺省的即可
  開始編譯
  make
  未能通過失敗原因是linux/autoconfh文件或目錄不存在這個文件就是/usr/include/linux/autoconfh文件一查確實不存在它是在編譯內核的時候生成的而我並未編譯內核所以當然沒有了好吧想辦法生成它吧
  到linux目錄並進行配置
  cd /usr/src/linux
  make menuconfig
  不做任何改變退出保存即可此時一看/usr/include/linux/autoconfh文件出來了這就夠了不必真的去編譯內核
  回到isdnlinux目錄再編譯
  cd /usr/src/isdnkutils
  make
  剛才的問題沒有了但還是未能通過失敗原因是capi/capic文件中下面幾個符號未定義
  
  CAPI_GET_FLAGS
  CAPI_SET_FLAGS
  CAPI_CLR_FLAGS
  CAPI_NCCI_GETUNIT
  CAPI_NCCI_OPENCOUNT
  
  對應的一段源代碼為
  
  int
  capiext_get_flags(unsigned ApplID unsigned *flagsptr)
  {
  if (ioctl(applidfd(ApplID) CAPI_GET_FLAGS flagsptr) < )
  return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  int
  capiext_set_flags(unsigned ApplID unsigned flags)
  {
  if (ioctl(applidfd(ApplID) CAPI_SET_FLAGS &flags) < )
  return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  int
  capiext_clr_flags(unsigned ApplID unsigned flags)
  {
  if (ioctl(applidfd(ApplID) CAPI_CLR_FLAGS &flags) < )
  return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  char *
  capiext_get_tty_devname(unsigned applid unsigned ncci char *buf size_t size)
  {
  int unit;
  unit = ioctl(applidfd(applid) CAPI_NCCI_GETUNIT &ncci);
  if (unit < 0)
  return 0;
  snprintf(buf, size, "/dev/capi/%d", unit);
  return buf;
  }
  
  char *
  capi20ext_get_raw_devname(unsigned applid, unsigned ncci, char *buf, size_t size)
  {
  int unit;
  unit = ioctl(applid2fd(applid), CAPI_NCCI_GETUNIT, &ncci);
  if (unit < 0)
  return 0;
  snprintf(buf, size, "/dev/capi/r%d", unit);
  return buf;
  }
  
  int capi20ext_ncci_opencount(unsigned applid, unsigned ncci)
  {
  return ioctl(applid2fd(applid), CAPI_NCCI_OPENCOUNT, &ncci);
  }
  
  作者未定義它們,我也不知道這幾個常量該是多少,怎麼辦?我從capi20/capi20.h文件中發現,這幾個函數是" extentions functions (no standard functions)",擴展的非標准函數,我猜測,這幾個函數即使功能不正確,也不會影響ISDN的使用,那麼,我就可以把那幾個未定義的符號注解起來,使編譯通過。tw.wiNgwIT.Com修改源碼如下:
  
  int
  capi20ext_get_flags(unsigned ApplID, unsigned *flagsptr)
  {
  // if (ioctl(applid2fd(ApplID), CAPI_GET_FLAGS, flagsptr) < 0)
  // return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  int
  capi20ext_set_flags(unsigned ApplID, unsigned flags)
  {
  // if (ioctl(applid2fd(ApplID), CAPI_SET_FLAGS, &flags) < 0)
  // return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  int
  capi20ext_clr_flags(unsigned ApplID, unsigned flags)
  {
  // if (ioctl(applid2fd(ApplID), CAPI_CLR_FLAGS, &flags) < 0)
  // return CapiMsgOSResourceErr;
  return CapiNoError;
  }
  
  char *
  capi20ext_get_tty_devname(unsigned applid, unsigned ncci, char *buf, size_t size)
  {
  int unit;
  // unit = ioctl(applid2fd(applid), CAPI_NCCI_GETUNIT, &ncci);
  if (unit < 0)
  return 0;
  snprintf(buf, size, "/dev/capi/%d", unit);
  return buf;
  }
  
  char *
  capi20ext_get_raw_devname(unsigned applid, unsigned ncci, char *buf, size_t size)
  {
  int unit;
  // unit = ioctl(applid2fd(applid), CAPI_NCCI_GETUNIT, &ncci);
  if (unit < 0)
  return 0;
  snprintf(buf, size, "/dev/capi/r%d", unit);
  return buf;
  }
  
  int capi20ext_ncci_opencount(unsigned applid, unsigned ncci)
  {
  // return ioctl(applid2fd(applid), CAPI_NCCI_OPENCOUNT, &ncci);
  return 0;
  }
  
  再次編譯:
  make
  通過了,接著安裝:
  make install
  命令完成後,isdnctrl和ipppd被拷到/sbin目錄下。
  
  3、 撥號配置
  我看了一些別人寫的介紹文章,取用他們寫好的例子,修改其中的電話號碼,用戶名等必須修改的相關內容,然後運行。不幸的是,通常都不能成功。因為這些例子都比較完善而復雜,因此難免和我的配置情況不符合而出錯。我決定從簡單入手,只進行最基本最必要的配置,先不寫成shell文件,而是一條命令一條命令地輸入執行,仔細理解其意義,查看其執行結果。等全部試驗成功後,再寫成shell文件。現在看來,這種做法非常有效,我會同樣來處理類似的問題。
  
  echo 1 > /proc/sys/net/ipv4/ip_dynaddr
  撥號上網大部分都是使用動態IP地址,比如我上163網,只知道撥打163號碼,並不知道遠程服務器(即中國電信機房內的163撥號服務器)的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 3382460
  指明我自己這台ISDN的電話號碼為3382460。

From:http://tw.wingwit.com/Article/program/Oracle/201311/16512.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.