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