了解更多关于套接字 I/O 控制 (ioctl) 命令的内容,以及如何使用它们完成各种网络相关的操作.操作系统为套接字、路由表、ARP 表、全局网络参数和接口提供了相应的控制操作方式。本文适用于对 Internet Protocol Version 4 (IPv4) 和 Internet Protocol Version 6 (IPv6) 堆栈网络级操作感兴趣的 AIX® Version 5.3 开发人员。
AIX Version 5.3 提供了很多 ioctl 套接字控制选项,以提取各种有关网络接口的信息。这些 ioctl 命令用于查询接口的状态并对其属性进行操作。下面的部分中包含了一些有用的命令的代码段。有关 ioctl 命令的完整列表,请参见参考资料部分。
ioctl 命令所使用的结构
下面的清单介绍了一些最重要的结构,使用 ioctl 套接字命令时常常用到这些结构。
清单 1. struct ifreq (/usr/include/net/if.h)
/* Interface request structure used for socket * ioctl's. All interface ioctl's must have parameter * definitions which begin with ifr_name. The * remainder may be interface specific. */ struct ifreq { #ifndef IFNAMSIZ #define IFNAMSIZ 16 #endif char ifr_name[IFNAMSIZ]; union { struct sockaddr ifru_addr; struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; __ulong32_t ifru_flags; int ifru_metric; caddr_t ifru_data; u_short ifru_site6; __ulong32_t ifru_mtu; int ifru_baudrate; } ifr_ifru;
Following macros are provided for convenience
#define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ #define ifr_metric ifr_ifru.ifru_metric /* metric */ #define ifr_data ifr_ifru.ifru_data /* for use by interface */ #define ifr_site6 ifr_ifru.ifru_site6 /* IPv6 site index */ #define ifr_mtu ifr_ifru.ifru_mtu /* mtu of interface */ #define ifr_isno ifr_ifru.ifru_data /* pointer to if_netopts */ #define ifr_baudrate ifr_ifru.ifru_baudrate /* baudrate of interface */ };
清单 2. struct ifconf (/usr/include/net/if.h)
/* * Structure used in SIOCGIFCONF request. * Used to retrieve interface configuration * for machine (useful for programs which * must know all networks accessible). */ struct ifconf { int ifc_len; /* size of associated buffer */ union { caddr_t ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu;
Following macros are provided for convenience
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ };
/*Function to get the size needed to allocate for buffers*/ int get_interface_size(int sd){ int ret,size; ret=ioctl(sd,SIOCGSIZIFCONF,&size); if(ret==-1){ perror("Error getting size of interface :"); return ret; } return size; }
main { struct ifconf ifc; int sd; sd=socket(AF_INET6,SOCK_DGRAM,0); printf("Size of memory needed = %d\n",get_interface_size(sd)); }
/* This function prints all the configured IPs on the * system given the ifconf structure allocated previously*/ void print_ips(struct ifconf *ifc){ char *cp,*cplim,addr[INET6_ADDRSTRLEN]; struct ifreq *ifr=ifc->ifc_req; cp=(char *)ifc->ifc_req; cplim=cp+ifc->ifc_len; for(;cpifr_name) + SIZE(ifr->ifr_addr))){ /* NOTE: You cannot just increment cp with sizeof(struct ifreq) * as structures returned are of different length. */ ifr=(struct ifreq *)cp; printf("%s :",ifr->ifr_name); getip(ifr,addr); printf("%s\n",addr); } return ; } main { struct ifconf ifc; int sd; sd=socket(AF_INET6,SOCK_DGRAM,0); alloc_buffer_size(sd,&ifc); print_ips(&ifc); }
ret=ioctl(sd,SIOCGIFMTU,ifr); if(ret==-1){ perror("Error getting mtu for interface :"); return ; } printf(" %d\n",ifr->ifr_mtu);
SIOCGNETOPT1
SIOCGNETOPT1 给出当前值、缺省值和网络选项的范围。
清单 10. 从 optreq1 结构获取网络选项
/*Function to get the network options*/ int print_network_options(int sd){ int ret; struct optreq1 oreq; oreq.getnext=1; while((ioctl(sd,SIOCGNETOPT1,(caddr_t)&oreq))!=-1) printf("%s = %s\n",oreq.name,oreq.data); return 0; }