socket 嘛和檔案仝款,有 struct file_operations,ioctl() 系統呼叫時,會執行 sock_ioctl()。[見 Linux /net/socket.c]
long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
其中 file 只用到 file->private_data,其實就是指向 struct socket,然後可取得 socket 其它相關資訊,例如 struct sock、 struct net 等。cmd 是指令編號,定義在 <linux/sockios.h>。arg 是 cmd 用的參數,通常指到 user space 的一塊記憶體。sock_ioctl() 會依據 cmd 設定或讀取 owner/group、bridge、VLAN、DLCI,另外 0x89F? (SIOCDEVPRIVATE) 和 0x8B?? (SIOCIW*) 這兩段是呼叫 dev_ioctl() 交由 device 處理,剩下的呼叫 socket 的 ops->ioctl()。
在 dev_ioctl(),幾乎所有的 cmd 都將 arg 所指的 user space 資料複製到 kernel space 作為 struct ifreq 使用,執行結束後會再複製回 user space,此時 ioctl() 系統呼叫的 arg 所指資料結構需要符合 struct ifreq,才能正確傳遞資訊 [見 Linux /net/core/dev.c,struct ifreq 定義在 <linux/if.h>]。
呼叫 dev_ioctl() 交由 device 處理需要找到特定 device 的資料結構,也就是 struct net_device。struct ifreq 包含 ifr_name,也就是 ifconfig 看到的網路界面名稱,用來找出 struct net_device。程式碼如下:
struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
/* 註:以前是 dev->do_ioctl */
預留的 cmd
- SIOCDEVPRIVATE ~ SIOCDEVPRIVATE+15, 共16 個專門給 device 使用。
- Wireless 預留 SIOCIWFIRST ~ SIOCIWLAST,共 256 個,定義在 <linux/wireless.h>,包括 SIOCIWFIRSTPRIV ~ SIOCIWLASTPRIV 有 32 個。其中奇數是 GET cmd 才能回傳資料給 user space。處理這些 cmd 的函式,可能是 iw_handler_get_iwstats (SIOCGIWSTATS)、 iw_handler_get_private (SIOCGIWPRIV)、或者來自函式表 dev->ieee80211_ptr->wiphy->wext 或 dev->wireless_handlers ,不然就用 ndo_do_ioctl()。
- plip 更改內部 timeout 值。
- ppp-stats 取得 ppp 驅動程式的資訊。
- LDD3 ch17
- Linux 3.3.8 source codes
沒有留言:
張貼留言