用ioctl设置了网卡的ip地址和子网掩码计算掩码后,如何激活

请问用ioctl设置了网卡的ip地址和掩码后,如何激活?
我在程序中用ioctl函数设置了网卡的ip地址和掩码,但是设置完成后,网络并没有激活,还是不能收发数据,但是退出程序用ifconfig-a查看,设置已经成功,然后用ifconfig激活,就可以收发数据了,请问,能不能用ioctl在设置完ip地址和掩码后,直接用ioctl激活?或者还有其他的方法在程序中直接激活网络设置?谢谢啊
morninglight 发表于
system("ifconfig eth0 192.168.168.1 mask 255.255.255.0");就可以直接激活了。
flag 发表于
[code]struct ifreq buf[MAXINTERFACES];int fd,if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) &= 0) {ifc.ifc_len = sizeof(buf);ifc.ifc_buf = (caddr_t)intrface = ifc.ifc_len / sizeof (struct ifreq);printf("interface num is intrface=%d/n/n/n",intrface);while (intrface-- & 0){if (!ioctl (fd, SIOCGIFCONF, (char *) &ifc)) {ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]);if (!buf[intrface].ifr_flags & IFF_UP) { buf[intrface].ifr_flags |=IFF_UP;} ioctl (fd, SIOCSIFFLAGS, (char *) &buf[intrface]);}close(fd);[/code]不用多解释了吧?
morninglight 发表于
版主,你好,我不会用那些ioctl,比如:ioctl (fd, SIOCGIFCONF, (char *) &ifc)和ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]),你能不能解释一下?多谢。
flag 发表于
ioctl是系统调用,用于对设备的操作,如果你了解一些驱动源码的话,应该明白。具体地说,ioctl是向内核提交一个命令,用于获取或者设置和设备相关的参数。SIOCGIFCONF是获取,SIOCSIFFLAGS是设置,看到区别了吗?ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface]);这句是获取设备的当前状态buf[intrface].ifr_flags |=IFF_UP;设置激活标志ioctl (fd, SIOCSIFFLAGS, (char *) &buf[intrface]);然后设置,很简单吧。
morninglight 发表于
谢谢版主指导
相关标签/搜索在linux下如何设置IP地址并将其激活
在linux系统的 /etc/sysconfig/network-script/ifcfg-eth0文件中存放着这台机子网卡IP地址配置的相关信息,它的具体格式为:[root@localhost network-scripts]# cat ifcfg-eth0DEVICE=eth0BOOTPROTO=noneONBOOT=yesTYPE=EthernetNETMASK=255.255.255.128IPADDR=11.19.13.16USERCTL=noPEERDNS=yesGATEWAY=61.49.23.129只要我们按照上面的格式配置好文件的各个数据项,且用/etc/init.d/network reload 命令 或service network [命令]重新导入该文件,我们就可以将我们的网络启动起来。:)
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!ioctl_百度百科
清除历史记录关闭
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
ioctl是中对设备的进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的参数个数如下:int ioctl(int fd, int cmd, …);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就能在用户程序中使用ioctl函数控制设备的I/O通道。
ioctl功 能
控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
返回值:成功为0,出错为-1
usr/include/asm-generic/ioctl.h中定义的宏的注释:
#define _IOC_NRBITS 8 //序数(number)字段的宽度,8bits
#define _IOC_TYPEBITS 8 //幻数(type)字段的字位宽度,8bits
#define _IOC_SIZEBITS 14 //大小(size)字段的字位宽度,14bits
#define _IOC_DIRBITS 2 //方向(direction)字段的字位宽度,2bits
#define _IOC_NRMASK ((1 && _IOC_NRBITS)-1) //序数字段的掩码,0x000000FF
#define _IOC_TYPEMASK ((1 && _IOC_TYPEBITS)-1) //幻数字段的掩码,0x000000FF
#define _IOC_SIZEMASK ((1 && _IOC_SIZEBITS)-1) //大小字段的掩码,0x00003FFF
#define _IOC_DIRMASK ((1 && _IOC_DIRBITS)-1) //方向字段的掩码,0x
#define _IOC_NRSHIFT 0 //序数字段在整个字段中的位移,0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) //幻数字段的位移,8
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) //大小字段的位移,16
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) //方向字段的位移,30
* Direction bits.
#define _IOC_NONE 0U //没有数据传输
#define _IOC_WRITE 1U //向设备写入数据,驱动程序必须从读入数据
#define _IOC_READ 2U //从设备中读取数据,必须向用户空间写入数据
#define _IOC(dir,type,nr,size) \
(((dir) && _IOC_DIRSHIFT) | \
((type) && _IOC_TYPESHIFT) | \
((nr) && _IOC_NRSHIFT) | \
((size) && _IOC_SIZESHIFT))
* used to create numbers
//构造无参数的命令编号
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
//构造从中读取数据的命令编号
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
//用于向驱动程序写入数据命令
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
//用于双向传输
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
*used to decode ioctl numbers..
//从命令参数中解析出数据方向,即写进还是读出
#define _IOC_DIR(nr) (((nr) && _IOC_DIRSHIFT) & _IOC_DIRMASK)
//从命令参数中解析出幻数type
#define _IOC_TYPE(nr) (((nr) && _IOC_TYPESHIFT) & _IOC_TYPEMASK)
//从命令参数中解析出序数number
#define _IOC_NR(nr) (((nr) && _IOC_NRSHIFT) & _IOC_NRMASK)
//从命令参数中解析出用户数据大小
#define _IOC_SIZE(nr) (((nr) && _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE && _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ && _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) && _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK && _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#include &stdlib.h&
#include &stdio.h&
#include &sys/ioctl.h&
int main(void) {
/* use func 8 to determine if the default drive is removable */
..stat = ioctl(0, 8, 0, 0);
..if (!stat)
....printf(&Drive %c is removable.\n&, getdisk() + 'A');
....printf(&Drive %c is not removable.\n&, getdisk() + 'A');
..return 0;
int ioctl( int fd, int request, .../* void *arg */ ) 详解
第三个参数总是一个,但指针的类型依赖于request 参数。我们可以把和网络相关的请求划分为6 类:
ARP 高速缓存操作
路由表操作
下表列出了网络相关ioctl请求的request 参数以及arg 地址必须指向的数据类型:
SIOCATMARK
是否位于带外标记
设置套接口的进程ID 或进程组ID
获取套接口的进程ID 或进程组ID
设置/ 清除非阻塞I/O 标志
设置/ 清除信号驱动异步I/O 标志
获取接收缓存区中的字节数
设置文件的进程ID 或进程组ID
获取文件的进程ID 或进程组ID
SIOCGIFCONF
SIOCSIFADDR
SIOCGIFADDR
SIOCSIFFLAGS
SIOCGIFFLAGS
SIOCSIFDSTADDR
SIOCGIFDSTADDR
SIOCGIFBRDADDR
SIOCSIFBRDADDR
SIOCGIFNETMASK
SIOCSIFNETMASK
SIOCGIFMETRIC
SIOCSIFMETRIC
SIOCGIFMTU
获取所有接口的清单
设置接口地址
获取接口地址
设置接口标志
获取接口标志
设置点到点地址
获取点到点地址
获取广播地址
设置广播地址
获取子网掩码
设置子网掩码
获取接口的测度
设置接口的测度
获取接口MTU
(还有很多取决于系统的实现)
struct ifconf
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
struct ifreq
创建/ 修改ARP 表项
获取ARP 表项
删除ARP 表项
struct arpreq
struct arpreq
struct arpreq
获取路由表
struct rtentry
struct rtentry
struct rtentry
    套接口操作:
明确用于套接口操作的ioctl请求有三个, 它们都要求ioctl的第三个参数是指向某个整数的一个指针。
SIOCATMARK: 如果本套接口的的度指针当前位于带外标记,那就通过由第三个参数指向的整数返回一个非0 值;否则返回一个0 值。POSIX 以函数sockatmark 替换本请求。
SIOCGPGRP : 通过第三个参数指向的整数返回本套接口的进程ID 或进程组ID ,该ID 指定针对本套接口的SIGIO 或SIGURG 信号的接收进程。本请求和fcntl 的F_GETOWN 命令等效,POSIX 标准化的是fcntl 函数。
SIOCSPGRP : 把本套接口的进程ID 或者进程组ID 设置成第三个参数指向的整数,该ID 指定针对本套接口的SIGIO 或SIGURG 信号的接收进程,本请求和fcntl 的F_SETOWN 命令等效,POSIX 标准化的是fcntl 操作。
文件操作:
以下5 个请求都要求ioctl的第三个参数指向一个整数。
FIONBIO : 根据ioctl的第三个参数指向一个0 或非0 值分别清除或设置本套接口的非阻塞标志。本请求和O_NONBLOCK 文件状态标志等效,而该标志通过fcntl 的F_SETFL 命令清除或设置。
FIOASYNC : 根据ioctl 的第三个参数指向一个0 值或非0 值分别清除或设置针对本套接口的信号驱动异步I/O 标志,它决定是否收取针对本套接口的异步I/O 信号(SIGIO )。本请求和O_ASYNC 文件状态标志等效,而该标志可以通过fcntl 的F_SETFL 命令清除或设置。
FIONREAD : 通过由ioctl的第三个参数指向的整数返回当前在本套接口接收缓冲区中的字节数。本特性同样适用于文件,管道和终端。
FIOSETOWN : 对于套接口和SIOCSPGRP 等效。
FIOGETOWN : 对于套接口和SIOCGPGRP 等效。
ioctl必要性
如果不用IOCTL的话,也能实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可以在驱动程式中实现WRITE的时候检查一下是否有特别约定的数据流通过,如果有的话,那么后面就跟着控制命令(一般在SOCKET编程中常常这样做)。不过如果这样做的话,会导致代码分工不明,程式结构混乱,程式员自己也会头昏眼花的。所以,我们就使用IOCTL来实现控制的功能。要记住,用户程式所作的只是通过命令码告诉驱动程式他想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程式要做的事情。
ioctl实现操作
读者只要把write换成ioctl,就知道用户程式的ioctl是怎么和驱动程式中的ioctl实现联系在一起的了。我这里说一个大概思路,因为我觉得《Linux设备驱动程序》这本书已说的非常清晰了,不过得花一些时间来看。在驱动程式中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程式员自己的事情,因为设备都是特定的,这里也没法说。关键在于怎么样组织命令码,因为在ioctl中命令码是唯一联系用户程式命令和驱动程式支持的途径。命令码的组织是有一些讲究的,因为我们一定要做到命令和设备是一一对应的,这样才不会将正确的命令发给错误的设备,或是把错误的命令发给正确的设备,或是把错误的命令发给错误的设备。这些错误都会导致不可预料的事情发生,而当程式员发现了这些奇怪的事情的时候,再来调试程式查找错误,那将是非常困难的事情。所以在Linux核心中是这样定义一个命令码的:
____________________________________
| 设备类型 | 序列号 | 方向 |数据尺寸|
|----------|--------|------|--------|
| 8 bit | 8 bit |2 bit |8~14 bit|
|----------|--------|------|-------|
这样一来,一个命令就变成了一个整数形式的命令码。不过命令码非常的不直观,所以Linux Kernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或是从命令码得到一些用户能理解的字符串以标明这个命令对应的设备类型、设备序列号、数据传送方向和数据传输尺寸。这些宏我就不在这里解释了,具体的形式请读者察看Linux核心原始码中的和,文件里给除了这些宏完整的定义。这里我只多说一个地方,那就是&幻数&。幻数是个字母,数据长度也是8,所以就用一个特定的字母来标明设备类型,这和用一个数字是相同的,只是更加利于记忆和理解。就是这样,再没有更复杂的了。更多的说了也没有,读者还是看一看原始码吧,推荐各位阅读《Linux 设备驱动程序》所带原始码中的short一例,因为他比较短小,功能比较简单,能看明白ioctl的功能和细节。
ioctl其他信息
cmd参数怎么得出?
这里确实要说一说,cmd参数在用户程式端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过传递到内核中的驱动程式,再由驱动程式使用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过switch{case}结构进行相应的操作。要透彻理解,只能是通过阅读原始码,我这篇文章实际上只是个引子。Cmd参数的组织还是比较复杂的,我认为要搞熟他还是得花不少时间的,不过这是值得的,驱动程式中最难的是对中断的理解。
ioctl其实没有什么非常难的东西需要理解,关键是理解cmd命令码是怎么在用户程序里生成并在驱动程序里解析的,程序员最主要的工作量在switch{case}结构中,因为对设备的I/O控制都是通过这一部分的代码实现的。
清除历史记录关闭ioctl实现网卡的开关
用ioctl实现打开和关闭网卡
//启动网卡接口
int SetEtherStatusUP(const char *ethNum)
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) & 0)
printf("Create socket fails!\n");
return -1;
strcpy(ifr.ifr_name, ethNum);
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) & 0)
printf("ioctl SIOCGIFFLAGS fails!\n");
close(sockfd);
return -1;
ifr.ifr_flags |= IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) & 0)
printf("ioctl SIOCSIFFLAGS fails!\n");
close(sockfd);
return -1;
close(sockfd);
//关闭网卡接口
int SetEtherStatusDOWN(const char *ethNum)
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) & 0)
printf("Create socket fails!\n");
return -1;
strcpy(ifr.ifr_name, ethNum);
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) & 0)
printf("ioctl SIOCGIFFLAGS fails!\n");
close(sockfd);
return -1;
ifr.ifr_flags &= ~IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) & 0)
printf("ioctl SIOCSIFFLAGS fails!\n");
close(sockfd);
return -1;
close(sockfd);
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!请教一个关于在linux下使用ioctl函数获取网卡的地址的问题。
[问题点数:20分,结帖人linwendong1982]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:3983
本版专家分:0
结帖率 100%
本版专家分:389555
2017年 总版技术专家分年内排行榜第一
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本版专家分:0
结帖率 100%
本版专家分:1892
本版专家分:1892
本版专家分:0
结帖率 100%
本版专家分:0
本版专家分:0
匿名用户不能发表回复!|
CSDN今日推荐

我要回帖

更多关于 ip地址子网掩码计算 的文章

 

随机推荐