ioctl在socket中的一些用法及示例

来源:互联网 发布:天津seo整站优化方案 编辑:程序博客网 时间:2024/06/01 13:39
函数 : ioctl(int fd, int request, void * arg)
定义 : <sys/ioctl.h>
功能 : 控制I/O设备, 提供了一种获得设备信息和向设备发送控制参数的手段.
参数 : int  fd      文件句柄. 用于socket时, 是socket套接字.
       int  request 函数定义的所有操作. 关于socket的操作, 定义在<linux/sockios.h>文件中.

       void *arg    指针的类型依赖于request参数.




下面是程序:

#include "stdio.h"#include "stdlib.h"#include "string.h"#include "net/if.h"#include "arpa/inet.h"#include "linux/sockios.h"int main(int argc,char *argv[]){    struct sockaddr_in *addr;    struct ifreq ifr;    char*address;    int sockfd;    char *name = "eth0";    if( strlen(name) >= IFNAMSIZ)        printf("device name is error.\n"), exit(0);            strcpy( ifr.ifr_name, name);            sockfd = socket(AF_INET,SOCK_DGRAM,0);    //get inet addr    if( ioctl( sockfd, SIOCGIFADDR, &ifr) == -1)        printf("ioctl error.\n"), exit(0);    addr = (struct sockaddr_in *)&(ifr.ifr_addr);    address = inet_ntoa(addr->sin_addr);    printf("inet addr: %s\n",address);    //get Mask    if( ioctl( sockfd, SIOCGIFNETMASK, &ifr) == -1)        printf("ioctl error.\n"), exit(0);    addr = (struct sockaddr_in *)&ifr.ifr_addr;    address = inet_ntoa(addr->sin_addr);    printf("Mask: %s\n",address);    //get HWaddr     u_int8_t hd[6];    if(ioctl(sockfd, SIOCGIFHWADDR, &ifr) == -1)        printf("hwaddr error.\n"), exit(0);    memcpy( hd, ifr.ifr_hwaddr.sa_data, sizeof(hd));    printf("HWaddr: %02X:%02X:%02X:%02X:%02X:%02X\n", hd[0], hd[1], hd[2], hd[3], hd[4], hd[5]);        exit(0);}


 二、设置

以下例程设置eth0的IP地址.

#include "stdio.h"#include "stdlib.h"#include "string.h"#include "net/if.h"#include "arpa/inet.h"#include "linux/sockios.h"int main(int argc,char *argv[]){    char *dev = "eth0";    char *ip = "192.168.1.252";        struct ifreq ifr;    if( strlen(dev) >= IFNAMSIZ)        printf("device name error.\n"), exit(0);    else        strcpy( ifr.ifr_name, dev);        int sockfd = socket(AF_INET,SOCK_DGRAM,0);    //get inet addr    if( ioctl( sockfd, SIOCGIFADDR, &ifr) == -1)        printf("ioctl error.\n"), exit(0);        struct sockaddr_in *addr = (struct sockaddr_in *)&(ifr.ifr_addr);    char * address = inet_ntoa(addr->sin_addr);    printf("current inet addr: %s\n",address);    //set inet addr    struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);    p->sin_family = AF_INET;    inet_aton( ip, &(p->sin_addr));    if( ioctl( sockfd, SIOCSIFADDR, &ifr) == -1)     printf("ioctl error.\n"), exit(0);    else            printf("change inet addr to: %s\n", ip);    //any OS need active dev.    /*ifr.ifr_flags |= IFF_UP;    if( ioctl( sockfd, SIOCSIFFLAGS, &ifr) == -1)        printf("active fault.\n"), exit(0);    else        printf("%s[%s] is working...\n", dev, ip);    */            close(sockfd);    exit(1);    //end}

屏蔽的代码用于设置IP后, 激活新设置. 多数系统不需要这步操作. 
而且这步仅作演示. 真实使用的时候, 至少应该
1. 获取当前ifr.ifr_flags
2. ifr.ifr_flags |= IFF_UP;

以上是ioctl的一些示例, 实战中灵活使用、举一反三.

结构原型:
struct ifreq
{
#define IFHWADDRLEN 6
 union
 {
  char ifrn_name[IFNAMSIZ];  
 } ifr_ifrn;
 
 union {
  struct sockaddr ifru_addr;
  struct sockaddr ifru_dstaddr;
  struct sockaddr ifru_broadaddr;
  struct sockaddr ifru_netmask;
  struct  sockaddr ifru_hwaddr;
  short ifru_flags;
  int ifru_ivalue;
  int ifru_mtu;
  struct  ifmap ifru_map;
  char ifru_slave[IFNAMSIZ]; 
  char ifru_newname[IFNAMSIZ];
  void __user * ifru_data;
  struct if_settings ifru_settings;
 } ifr_ifru;
};
#define ifr_name ifr_ifrn.ifrn_name 
#define ifr_hwaddr ifr_ifru.ifru_hwaddr 
#define ifr_addr ifr_ifru.ifru_addr 
#define ifr_dstaddr ifr_ifru.ifru_dstaddr 
#define ifr_broadaddr ifr_ifru.ifru_broadaddr 
#define ifr_netmask ifr_ifru.ifru_netmask 
#define ifr_flags ifr_ifru.ifru_flags 
#define ifr_metric ifr_ifru.ifru_ivalue 
#define ifr_mtu  ifr_ifru.ifru_mtu 
#define ifr_map  ifr_ifru.ifru_map 
#define ifr_slave ifr_ifru.ifru_slave 
#define ifr_data ifr_ifru.ifru_data 
#define ifr_ifindex ifr_ifru.ifru_ivalue 
#define ifr_bandwidth ifr_ifru.ifru_ivalue    
#define ifr_qlen ifr_ifru.ifru_ivalue 
#define ifr_newname ifr_ifru.ifru_newname 
#define ifr_settings ifr_ifru.ifru_settings 
 
基本介绍: 
ifreq结构定义在/usr/include/net/if.h,用来配置ip地址,激活接口,配置MTU等接口信息的。其中包含了一个接口的名 字和具体内容——(是个共用体,有可能是IP地址,广播地址,子网掩码,MAC号,MTU或其他内容)。ifreq包含在ifconf结构中。而 ifconf结构通常是用来保存所有接口的信息的。
 
举例说明:
在Linux系统中,ifconfig命令是通过ioctl接口与内核通信,例如,当系统管理员输入如下命令来改变接口eth0的MTU大小:
    ifconfig eth0 mtu 1250
ifconfig命令首先打开一个socket,然后通过系统管理员输入的参数初始化一个数据结构,并通过ioctl调用将数据传送到内核。SIOCSIFMTU是命令标识符。
    struct ifreq data;
    fd = socket(PF_INET, SOCK_DGRAM, 0);
    < ... initialize "data" ...>
    err = ioctl(fd, SIOCSIFMTU, &data);




转载于:http://blog.chinaunix.net/uid-20692625-id-3172833.html

http://blog.sina.com.cn/s/blog_62ec2916010196c3.html

原创粉丝点击