linux内核网络钩子函数使用,Linux内核IOCTL网络控制框架实现实例分析
4.6、inet_ioctl函數
由于inet_ioctl函數內容分支很多,但功能、處理不難理解,所以我把一些不常見的內容都省去,挑簡單重要的說,完全在于拋磚引玉:
static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
…
switch(cmd)
{
case FIOSETOWN://設置屬主
case SIOCSPGRP://設置進程組
err = get_user(pid, (int *) arg);
if (err)
return err;
if (current->pid != pid && current->pgrp != -pid &&
!capable(CAP_NET_ADMIN))
return -EPERM;
sk->proc = pid;
return(0);
case FIOGETOWN://獲取屬主
case SIOCGPGRP://獲取進程組
return put_user(sk->proc, (int *)arg);
case SIOCGSTAMP://
if(sk->stamp.tv_sec==0)
return -ENOENT;
err = copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval));
if (err)
err = -EFAULT;
return err;
case SIOCADDRT://增加路由
case SIOCDELRT://刪除路由
case SIOCRTMSG:
return(ip_rt_ioctl(cmd,(void *) arg));//IP路由配置
case SIOCDARP://刪除arp項
case SIOCGARP://獲取arp項
case SIOCSARP://創建/修改arp項
return(arp_ioctl(cmd,(void *) arg));//arp配置
case SIOCGIFADDR://獲取接口地址
case SIOCSIFADDR://設置接口地址
case SIOCGIFBRDADDR://獲取廣播地址
case SIOCSIFBRDADDR://設置廣播地址
case SIOCGIFNETMASK://獲取網絡掩碼
case SIOCSIFNETMASK://設置網絡掩碼
case SIOCGIFDSTADDR://獲取p2p地址
case SIOCSIFDSTADDR://設置p2p地址
case SIOCSIFPFLAGS: //
case SIOCGIFPFLAGS:
case SIOCSIFFLAGS://設置接口標志
return(devinet_ioctl(cmd,(void *) arg));//網絡接口相關配置,linux內核自帶的ifconfig
//的很多處理都是通過這里實現的
case SIOCGIFBR:
case SIOCSIFBR://網橋設置,稍后的實例就是介紹如何截獲網橋控制鉤子
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) //如果內核支持網橋功能
#ifdef CONFIG_KMOD//若支持內核模塊動態加載
if (br_ioctl_hook == NULL)//網橋鉤子為空則動態請求模塊
request_module("bridge");//加載網橋模塊
#endif
if (br_ioctl_hook != NULL)
return br_ioctl_hook(arg);//通過鉤子函數處理命令參數
#endif
case SIOCGIFDIVERT://
case SIOCSIFDIVERT:
#ifdef CONFIG_NET_DIVERT
return(divert_ioctl(cmd, (struct divert_cf *) arg));
#else
return -ENOPKG;
#endif???? /* CONFIG_NET_DIVERT */
return -ENOPKG;
case SIOCADDDLCI://
case SIOCDELDLCI:// 數據鏈路連接標識控制
#ifdef CONFIG_DLCI
lock_kernel();
err = dlci_ioctl(cmd, (void *) arg);//控制函數
unlock_kernel();
return err;
#endif
#ifdef CONFIG_DLCI_MODULE
#ifdef CONFIG_KMOD
if (dlci_ioctl_hook == NULL)//如果鉤子函數為空,則加載模塊
request_module("dlci");
#endif
if (dlci_ioctl_hook) {//鉤子函數指針不空
lock_kernel();
err = (*dlci_ioctl_hook)(cmd, (void *) arg);//調用鉤子函數
unlock_kernel();
return err;
}
#endif
return -ENOPKG;
default:
…
return err;
}
/*NOTREACHED*/
return(0);
}
從上面的函數代碼來看,同套接字有關的控制請求主要有如下幾類:
1、文件操作
2、套接字操作
3、路由選項操作
4、接口操作
5、ARP高速緩存操作
6、網橋控制
7、數據鏈路連接標識控制
結合代碼中的注釋,讀者不難理解具體的控制分支。具體的控制處理就轉到具體的函數里面去處理了,例如關于內核自帶的命令工具ifconfig對ip地址的配置處理,基本都在devinet_ioctl函數中;關于arp命令的處理都在arp_ioctl中處理;關于路由配置都在ip_rt_ioctl中處理。其中參數arg是用戶空間傳來的自定義的數據,可以是結構,可以是聯合或其它一些更復雜的類型,由具體的業務模塊來解釋處理。在隨后的實踐中,我們就是通過arg的不同解釋來做不同的處理。
4.7、網絡主要結構相關字段相互引用圖
通過上面的分析,大家應該大致明白了linux內核網絡ioctl控制框架的實現了。下面是在內核網絡組件初始化后,ipv4相關的結構字段之間相互引用圖,供大家閱讀是參考:
結合前面主要函數調用關系圖與源碼分析,讀者可以很清晰的順著上圖所示的箭頭,從ioctl入口函數開始,方便地找到具體的處理模塊.其中,文件操作對象 socket_file_ops調用sock_ioctl()時,通過inode節點的socket_i字段最終找到inet_ioctl()函數.
總結
以上是生活随笔為你收集整理的linux内核网络钩子函数使用,Linux内核IOCTL网络控制框架实现实例分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机文件传云服务器,手机云服务器传文件
- 下一篇: deque python_3 . pyt