`
sony-soft
  • 浏览: 1023119 次
文章分类
社区版块
存档分类
最新评论

浅析ethx网卡控制函数ioctl实现具体流程

 
阅读更多

浅析ethx网卡控制函数ioctl实现具体流程

====================
1.应用层程序iwpriv
wireless tools网络配置应用程序iwpriv命令格式:
iwpriv ethX private-command [parameters]

iwpriv部分实现源码如下:
int main(int argc, char *argv[])
{
...
sockfd = socket(AF_INET, SOCK_STREAM, 0);
...
ioctl(sockfd, ioctl_val, &iwr);//将控制命令通过ioctl发送到无线网卡
...
}
====================
2.系统调用sys_ioctl
应用层通过ioctl(sockfd, ioctl_val, &iwr);触发sys_ioctl系统调用,实际流程:
sys_ioctl=>vfs_ioctl=>do_ioctl=最后调用
filp->f_op->unlocked_ioctl执行具体的ioctl操作,该操作就是sock_ioctl,至于为什么是sock_ioctl,后边作了进一步分析
sock_ioctl=>
{
...
#ifdef CONFIG_WIRELESS_EXT
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
err = dev_ioctl(net, cmd, argp);//

} else
#endif
...
}
dev_ioctl=>wext_handle_ioctl
{
...
/* Take care of Wireless Extensions */
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
return wext_handle_ioctl(net, &ifr, cmd, arg);
...
}
wext_handle_ioctl=>wireless_process_ioctl=>
然后通过if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL)函数,
从系统管理的net链表中,把ioctl指定的ethX对应的struct net_device摘出来,
最后调用ioctl_private_call(handler)或者调用dev->do_ioctl(dev, ifr, cmd)来处理该ioctl,
这两个函数分别指向wlan_handler_def和wlan_do_ioctl
====================
3.wifi网卡是怎么登记到kernel上的
wlan_probe()=>wlan_add_card()=>alloc_etherdev()=>
之后将操作方法添加到struct net_device *dev=alloc_etherdev()申请的dev上去,其中包括:
...
/* Setup the OS Interface to our functions */
dev->open = wlan_open;
dev->hard_start_xmit = wlan_hard_start_xmit;
dev->stop = wlan_close;
dev->do_ioctl = wlan_do_ioctl;
dev->set_mac_address = wlan_set_mac_address;

dev->tx_timeout = wlan_tx_timeout;
dev->get_stats = wlan_get_stats;
dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def;
dev->set_multicast_list = wlan_set_multicast_list;
...
4.socket系统调用如何关联上ioctl和ethX设备

asmlinkage long sys_socket(int family, int type, int protocol);

sys_socket=>sock_create=>__sock_create=>sock = sock_alloc();通过sock_mnt->mnt_sb从socket文件系统的超级块上申请一个inode节点,这样也就同时获得了由该inode描述的一个sock结构体单元,所以sokcet和dentry目录项等效,
接下来从net_families全局管理结构体中找到当前family对应的ops操作集,
net_proto_family *pf=net_families[family];
pf->create(net, sock, protocol);//核心调用,对于ipv4,就是inet_create
以ipv4为例
static struct net_proto_family inet_family_ops = {
.family = PF_INET,
.create = inet_create,
.owner= THIS_MODULE,
};
还记得上面应用层创建sokcet的函数吧,
sockfd = socket(AF_INET, SOCK_STREAM, 0);//AF_INET虽然等于PF_INET,但是因为种种原因我们提倡使用PF_INET
可见family等于AF_INET,type等于SOCK_STREAM,协议protocol为0,也就是采用IP协议,
inet_create=>inetsw[sock->type]也就是inetsw[SOCK_STREAM],
从inetsw[sock->type]中找到已经登记的protocol网络协议处理函数,
inetsw[]是怎么填充的呢?inet_init()=>inet_register_protosw(inetsw_array)=>这样inetsw_array中的所有protocol处理模块都将登记到inetsw中了,
static struct inet_protosw inetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = IPPROTO_TCP,
.prot = &tcp_prot,
.ops = &inet_stream_ops,
.capability = -1,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK,
},

{
.type = SOCK_DGRAM,
.protocol = IPPROTO_UDP,
.prot = &udp_prot,
.ops = &inet_dgram_ops,
.capability = -1,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_PERMANENT,
},


{
.type = SOCK_RAW,
.protocol = IPPROTO_IP,/* wild card */
.prot = &raw_prot,
.ops = &inet_sockraw_ops,
.capability = CAP_NET_RAW,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
}
};
至于inet_init,则是以fs_initcall(inet_init)方式,以5号优先级被build in到了内核中,当kernel启动时会在start_kernel=>rest_init=>kernel_init=>do_basic_setup=>do_initcalls中依据优先级号优先于其他module驱动被调用.
这样sock->ops = answer->ops;对于ipv4也就等于inet_stream_ops,
接下来就是将ops填充到file操作指针中了,
sys_socket=>sock_map_fd=>sock_attach_fd=>
dentry->d_op = &sockfs_dentry_operations;
init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE, &socket_file_ops);
file->private_data = sock;
其中init_file=>file->f_op = fop;也就是file->f_op = socket_file_ops;
所以read(),wirte(),poll()和ioctl()应用程序调用的file->f_op就是socket_file_ops了,
比如:
read()对应sock_aio_read网络异步读
write()对应sock_aio_write网络异步写
ioctl()对应sock_ioctl

socket_file_ops结构体具体实现如下:
static const struct file_operations socket_file_ops = {
.owner =THIS_MODULE,
.llseek =no_llseek,
.aio_read =sock_aio_read,
.aio_write =sock_aio_write,
.poll =sock_poll,
.unlocked_ioctl = sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_sock_ioctl,
#endif
.mmap =sock_mmap,
.open =sock_no_open,/* special open code to disallow open via /proc */
.release =sock_close,
.fasync =sock_fasync,
.sendpage =sock_sendpage,
.splice_write = generic_splice_sendpage,
};
网卡控制因为涉及到的知识点比较多,上面只是从宏观上对数据流程做了一个简单的介绍,深入到其中的每个知识点,都会牵扯出一系列文章,读者需要自己去一个个的慢慢深入,希望本文能够对刚刚接触网络驱动的读者有所帮助和启发【gliethttp.Leith】

分享到:
评论

相关推荐

    自动修改linux下/etc/sysconfig/network-scripts/ifcfg-ethX网卡文件的脚本

    自动修改linux下/etc/sysconfig/network-scripts/ifcfg-ethX网卡文件的脚本

    ubuntu修改网卡名称为eth0.docx

    修改Linux Ubuntu系统默认网卡名称,改为ethx的格式,例如:eth0,eth1。

    ethtool命令 查询与设置网卡参数

    ethtool命令用于查询ethX网口基本设置、及设置网卡的参数。 语法格式:ethtool [参数] 常用参数: -i 显示网卡驱动的信息 -E 修改网卡只读存储器字节 -K 修改网卡 Offload 的状态 ethx 查询ethx网口基本...

    VMware 10 中为CentOS 7添加多网卡并重命名

    VMware 10 中为CentOS 7添加多网卡并重命名为ethx(eth0,eth1失败)(还想再添加网卡eth1???),因为工作需要切换到CentOS 7系统,网络配置,比较麻烦: 最小化安装的CentOS 7里面甚至连ifconfig、route -ne都没有,...

    ethx-core:ETHX INC的基础项目

    欢迎来到ETHX 项目结构 我们正在使用 Next.js:这是一个使用引导的项目。 -了解Next.js功能和API。 交互式Next.js教程。 打字稿: 故事书: TailwindCSS: 一切都应该使用原子设计更多细节创建完整本书是在网上找到...

    CentOS桌面环境中网卡启动失败的解决方法

    我在最小化安装CentOS中网卡启动正常,但是当我们装了桌面版的CentOS后,发现不管使用哪种启动网卡的方式都会启动失败。 截图如下: 后来查阅报错原因,NetworkManager管理工具和/etc/sysconfig/network-scripts/...

    自动生成linux网卡配置脚本分享

    主要介绍了自动生成linux网卡配置的脚本,...本脚本功能,第一次添加网卡后,启动虚拟机,然后运行脚本(可以写在启动脚步中),然后根据ifconfig -a 的信息来创建ifcfg-ethX的配置文件或者修改对应的ifcfg-ethX的mac

    ethtool-3.9 下载

    Ethtool是Linux下用于查询及设置网卡参数的命令。 概要: ethtool ethX //查询ethX网口基本设置 ethtool –h //显示ethtool的命令帮助(help) ethtool –i ethX //查询ethX网口的相关信息 ethtool –d ethX //查询...

    Docker跨主机网络(manual)的实现

    在 Macvlan 出现之前,我们只能为一块以太网卡添加多个 IP 地址,却不能添加多个 MAC 地址,因为 MAC 地址正是通过其全球唯一性来标识一块以太网卡的,即便你使用了创建 ethx:y 这样的方式,你会发现所有这些“网卡...

    适合生产环境的 preseed 文件 适用于 EFI 启动环境 经过多次测试没有任何问题,直接使用

    3. 安装后的系统根据习惯 网卡命名默认采用的是 ethX 这种传统的网卡命名模式 4. 用户名和密码默认都是 debian , 请根据自己实际情况使用 openssl passwd -6 或者 mkpasswd -m sha-512 命令修改 d-i passwd/user-...

    适合生产环境的 preseed 文件 适用于传统 BIOS 启动环境 经过多次测试没有任何问题,直接使用

    3. 安装后的系统根据习惯 网卡命名默认采用的是 ethX 这种传统的网卡命名模式 4. 用户名和密码默认都是 debian , 请根据自己实际情况使用 openssl passwd -6 或者 mkpasswd -m sha-512 命令修改 d-i passwd/user-...

    移液器:SDNNFV协处理器控制器

    移液器通过在协处理器端口后面创建虚拟网络,然后充当该网络的SDN控制器来实现此目的。 使用将数据包无缝切换到其适当的目的地。 用法 如果尚不存在OVS容器,请启动OVS: docker-compose -f docker-compose-ovs.yml...

    Centos6 网络配置的实例详解

    /etc/sysconfig/network-scripts/ifcfg-ethX,其中ifcfg-ethX中的X代表第几块网卡,一般都是第一块,也就是ifcfg-eth0 下面是配置项目的讲解,这里展示的是自定义IP和DNS的配置文件 DEVICE=eth0#网卡设备名称 ...

    ethx-autonomous-mobile-robot:自主移动机器人问题集和练习(2017年Spring)@ ETH

    ethx-autonomous-mobile-robot:自主移动机器人问题集和练习(2017年Spring)@ ETH

    Linux 网络接口配置文件及相关工具

    网络接口(interface)是网络硬件设备在操作系统中的表示方法,比如网卡在Linux操作系统中用 ethX,是由0开始的正整数,比如eth0、eth1...... ethX。而普通猫和ADSL的接口是 pppX,比如ppp0等;

    linux命令(网络管理)1

    (网络接口可以使用service命令进行重启,关闭,开启操作||||ifup/ifdown效果同前)在linux中网络接口(网卡)用ethX表示 X为0,1,2

    批量自动安装NREP(Nagios Remote Plugin Executor)脚本

    此脚本命名nrpe_install.sh,适用于Centos 7或者RedHat RHEL 7,仅仅需要把mon_ip改成你所在系统的IP,然后执行 sh nrpe_install.sh,...如果有多个网卡,并且网口设备名不是ethX,请自行稍许修改脚本,也能很好的工作。

    suricata-configuration:Suricata 概述和设置说明

    跑步: 接下来在 IDS 模式下运行 suricata: ./run.sh -IDS ethX 其中 ethx 是监控流量的接口。 在 IPS 模式下运行 suricata: ./run.sh -IPS ethX 这将使用 iptables 规则将流量路由到 suricata。 要查看 http 日志...

    CentOS8中的nmcli使用详解

    nmcli c add type ethernet con-name ethX ifname ethX ipv4.addr 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.method manual # 创建connection,配置动态ip(等同于配置ifcfg,其中BOOTPROTO=dhcp,并ifup

    网络接口状态检测与自动分配IP小程序

    自己写的网络接口状态检测与自动分配IP小程序,可替代dhcp不正常的系统,或用于检测ethX link up/down状态。

Global site tag (gtag.js) - Google Analytics