2006/11/13

數位家庭產品初探 -- linux-IGD 源碼研究

全部檔案列表為: config.c gatedevice.c iptc.c main.c pmlist.c util.c

先從簡單看起,config.c, 這是採用正規表示法分析設定檔 /etc/upnpd.conf。其設定檔格式定義在 struct GLOBALS(globals.h) 裡。

char extInterfaceName[IFNAMSIZ]; // 對外網卡的名稱,如 eth1
char intInterfaceName[IFNAMSIZ]; // 對內網卡的名稱,如 eth0, 這兩個來自啟動命令
// 底下來自 /etc/upnpd.conf 的設定
int debug; // 0 無訊息輸出,1 輸出錯誤訊息至 syslog, 2 同 1 外含一般資訊,3 同 2 外含動態資訊
char iptables[50]; // iptables 命令的絕對路徑
char upstreamBitrate[10]; // 上傳 bitrate 限制
char downstreamBitrate[10]; // 下載 bitrate 限制
char forwardChainName[20]; // 放進 iptables forward chain 的名稱,例如 FORWARD
char preroutingChainName[20]; // 放進 iptables prerouting 的名稱,如 PREROUTING
int forwardRules; // 1 - 啟動 forward rules 嵌入 iptables 功能, 0 關閉
long int duration; // 0 - no duration
// SS 或 HH:MM - duration from the time of addition
// @SS 或 @HH:MM - expire mapping at the specified time of day
char descDocName[20];
char xmlPath[50];


main.c : 照源碼寫法,其命令語法 "upnpd [-f] EXT INT" 裡的 -f 位置不能亂動,這一點該注意。程式流程為:

.分析 /etc/upnpd.conf
.設定內/外部網卡
.取得內外部網卡的 Ip address
.對 daemon 的處理,這邊的寫法以前沒看過,可以參考一下。
.設定 umask(0) 之外,開啟 syslog "upnpd" <-- 在 /var/log/syslog 中含 upnpd
.呼叫 UpnpInit(intIpAddress,0) 做初始化 <-- 請見 libupnp
.呼叫 UpnpSetWebServerRootDir(g_vars.xmlPath) 設定 upnp 需要用到的 web server 目錄,其埠號是動態的,相關函數有 UpnpGetServerIpAddress(), UpnpGetServerPort()。若有異常則隨時用 UpnpFinish() 中斷 uPnP.
.接下來進入重頭戲,UpnpRegisterRootDevice() 註冊一個 uPnP Root Device
.StateTableInit() 會透過呼叫 UpnpDownloadXmlDoc() 自 web server 下載 gatedesc.xml, 請見 /etc/linuxigd/gatedesc.xml
.UpnpSendAdvertisement() 廣告週知,並進入聆聽中斷服務以便持續整個 IGD。
.聆聽中斷服務的方式是透過 #include <signal.h> 來完成,包含 SIGINT, SIGTERM, SIGUSR1
.最後正常結束(聆聽中斷),需要 UpnpUnRegisterRootDevice()+UpnpFinish();

以上整個邏輯不難,gatedevice.c 定義跟「device」有關的服務,例如 StateTableInit(), HandleSubscriptionRequest(), EventHandler() 定義了 UPNP_EVENT_SUBSCRIPTION_REQUEST, UPNP_CONTROL_GET_VAR_REQUEST, UPNP_CONTROL_ACTION_REQUEST 等,其他如 GetConnectionTypeInfo(), SetConnectionType(), GetNATRSIPStatus()

linux-igd 本身不支援 RSIP, 但 NAT 會。還有很多未列。請見 uPnP spec.(這一點我後續會再配合著發表心得) iptc.c 全部跟防火牆功能有關,應該搭配 iptables(libiptc) 的源碼來看。

pmlist.c 處理封包 port mapping 的函式 util.c 定義三個函式,get_sockfd(), GetIpAddressStr(), trace() 所以接下來我會研究一下 uPnP IGD 的 Spec.

0 意見: