Chinaunix首页 | 论坛 | 博客
  • 博客访问: 538664
  • 博文数量: 139
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-11 22:40
文章分类

全部博文(139)

文章存档

2011年(1)

2009年(3)

2008年(135)

我的朋友

分类: LINUX

2008-05-30 14:57:11

 

/*********************************

*###此文中有引用别人的文章############

*###出处:http://www.cublog.cn/opera/showart.php?blogid=21968&id=144911

*###正是这段文章帮助我有了后面的理解

********************************/

//begiin

一、应用层

uint16 data16;

if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

printf("socket failed\n\r");

}

if(ioctl(fd, SIOCSIFVLAN_PVID_PRI, &data16) < 0)

{

printf("ioctl pvid failed\n\r");

}

二、linux内核

1、 在sockios.h中定义

#define SIOCSIFVLAN_PVID_PRI 0x8985 /* Set 802.1Q VLAN pvid */

2、在af_inet.c中

添加

extern int VLAN1QEN(unsigned int ,void *arg);

在inet_ioctl()函数中添加

case SIOCSIFVLAN_PVID_PRI:

return VLAN1QEN(cmd, arg);

3、另外定义:

static unsigned int VLAN_PVID_PRI = 0;

int VLAN1QEN(unsigned int cmd,void *arg)

{

unsigned int data;

if (copy_from_user(&data, arg, sizeof(int)))

return -EFAULT;

switch (cmd) {

case SIOCSIFVLAN_PVID_PRI:

VLAN_PVID_PRI = data;

break;

default:

return -EINVAL;

}

}

//end

其实,这个问题却是困扰了我很久

在copy_from_user()和copy_to_user()的过程中,使用了arg这个参数指向用户空间某命令参数,在用户空间使用ioctl(int fd,int cmd, *bcf)想内核空间传递这个参数

这里,我实在找不到bcf和arg的联系。

通过半天多的查找翻阅,终于在http://www.cublog.cn/opera/showart.php?blogid=21968&id=144911找到了这篇短文,解开了我的疑惑。

这里我把我的理解写在这里:

首先,ioctl的功能我就不说了,网上比较多,大致是用来控制IO的。

其次,第一个参数fd是一个文件描述符,我们这里是建立的一个套接字描述符

再次,第二个参数,是在sockios.h中定义的一个32位描述符,我们也可以在这里添加新的类型,用来扩展实际需求。

最后,第三个参数,是一个指针,用来指向某些我们实际应用中的参数。

在af_inet.c中的inet_ioctl()函数中的switch——case中,对上面第二个参数分别进行了描述。

例如我所需要的是这样的一个类型:

ioctl( fd, SIOCSIFBR, &bcf )

在inet_ioctl()函数中如下表示: Linux/net/ipv4/af_inet.c

int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)

switch (cmd)

{……

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);
879 #endif
return -ENOPKG;
……

}//switch end here

这里inet_ioctl()中的第三个参数arg,正好对应在ioctl中的的三个参数&bcf,其实,inet_ioctl属于ioctl在linux内核中的网络设备ioctl的底层函数,用来处理网络设备的一些IO操作。

上面的一小段程序显示,我们用户层ioctl函数中的第三个参数对应在br_ioctl_hook(arg)中的arg上。

而在我们的另外一个函数中定义了一个函数叫br_ioctl(arg)函数,并且其中使用了copy_to_user 和copy_from_user 用来将用户层中ioctl函数传下来的 命令在内核中进行相应的处理。最后,用一句:br_ioctl_hook = br_ioctl 将这个函数送进inet_ioctl中。

这里我才明白,我一直想要弄懂的东西

ioctl —— br_ioctl之间的关系

ioctl这个从用户空间向内核空间传递参数的函数,目前使用的可能不是很多,或者这个东西大家都比较明白,唯独我不大清楚,所以今天找了半天才弄到现在这个理解的层次,也不知道对不对。
希望大家指点!

阅读(2569) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~