已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
揭开unix网络之纱8- ioctl获得网络接口1 概述需处理网络接口的许多程序沿用的初始步骤之一就是从内核获取配置在系统中的所有接口。本任务由SIOCGIFCONF请求完成,它使用ifconf结构,ifconf又使用ifreq结构。1.1 Ifconfig结构struct ifconfint ifc_len;unioncaddr_t ifcu_buf;struct ifreq* ifcu_req;ifc_ifcu;#define ifc_buf ifc_ifcu.ifcu_buf#define ifc_req ifc_ifcu.ifcu_req#define IFNAMSIZ 16Struct ifreqChar ifr_nameIFNAMSIZ;UnionStruct sockaddr ifru_addr;Struct sockaddr ifru_dstaddr;Struct sockaddr ifru_broadaddr;Short ifru_flags;Int ifru_metric;Caddr_t ifru_data;ifr_ifru;#define ifr_addr ifr_ifru.ifru_addr#define ifr_dstaddr ifr_ifru.ifru_dstaddr#define ifr_broadaddr ifr_ifru.ifru_broadaddr#define ifr_flags ifr_ifru.ifru_flags#define ifr_metric ifr_ifru.ifru_metric#define ifr_data ifr_ifru.ifru_data2 Unp_ifi.h#ifndef _UNP_IFI_H#define _UNP_IFI_H#include #define IFI_NAME 16 /*same as IFNAMSIZ in */#define IFI_HADDR 8 /*allow for 64-bit EUI-64 in future*/struct ifi_infochar ifi_nameIFI_NAME; /*interface name,null-terminated*/short ifi_index; /*interface index*/short ifi_mtu; /*interface MTU*/u_char ifi_haddrIFI_HADDR; /*hardware address*/u_short ifi_hlen; /*#bytes in hardware address: 0,6,8*/short ifi_flags; /*IFF_XXX constants from */short ifi_myflags; /*our own IFI_XXX flags*/struct sockaddr *ifi_addr; /*primary address*/struct sockaddr *ifi_brdaddr; /*broadcast address*/struct sockaddr *ifi_dstaddr; /*destination address*/struct ifi_info *ifi_next; /*next of these structures*/;#define IFI_ALIAS 1 /*ifi_addr is an alias*/*function prototypes*/struct ifi_info *get_ifi_info(int,int);void free_ifi_info(struct ifi_info *);#endif3 get_ifi_info#include #include #include #include #include #include #include #include #include #include #include #include #define max(a,b)using namespace std;/将地址转换为字符串,不在这里讨论char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen) static char str128;/* Unix domain is largest */switch (sa-sa_family) case AF_INET: struct sockaddr_in*sin = (struct sockaddr_in *) sa;if (inet_ntop(AF_INET, &sin-sin_addr, str, sizeof(str) = NULL)return(NULL);return(str);#ifdefIPV6case AF_INET6: struct sockaddr_in6*sin6 = (struct sockaddr_in6 *) sa;if (inet_ntop(AF_INET6, &sin6-sin6_addr, str, sizeof(str) = NULL)return(NULL);return(str);#endif#ifdefAF_UNIXcase AF_UNIX: struct sockaddr_un*unp = (struct sockaddr_un *) sa;/* OK to have no pathname bound to the socket: happens on * every connect() unless client calls bind() first. */if (unp-sun_path0 = 0)strcpy(str, (no pathname bound);elsesnprintf(str, sizeof(str), %s, unp-sun_path);return(str);#endif#ifdefHAVE_SOCKADDR_DL_STRUCTcase AF_LINK: struct sockaddr_dl*sdl = (struct sockaddr_dl *) sa;if (sdl-sdl_nlen 0)snprintf(str, sizeof(str), %*s, sdl-sdl_nlen, &sdl-sdl_data0);elsesnprintf(str, sizeof(str), AF_LINK, index=%d, sdl-sdl_index);return(str);#endifdefault:snprintf(str, sizeof(str), sock_ntop_host: unknown AF_xxx: %d, len %d, sa-sa_family, salen);return(str); return (NULL);/关键struct ifi_info* get_ifi_info(int family,int doaliases)/unp_ifi.h文件中定义struct ifi_info *ifi,*ifihead,*ifipnext;int sockfd,len,lastlen,flags,myflags,idx=0,hlen=0;char *ptr,*buf,lastnameIFNAMSIZ,*cptr,*haddr,*sdlname;/中定义struct ifconf ifc;struct ifreq *ifr,ifrcopy;/地址struct sockaddr_in *sinptr;struct sockaddr_in6 *sin6ptr;/创建socket套接字,数据报sockfd = socket(AF_INET,SOCK_DGRAM,0);lastlen=0;len=100*sizeof(struct ifreq);/取出网络接口信息for(;)/开辟100 fireq的空间buf=(char*)malloc(len);ifc.ifc_len=len;ifc.ifc_buf=buf;if(ioctl(sockfd,SIOCGIFCONF,&ifc)0)if(errno != EINVAL | lastlen != 0)coutioctl errorendl;exit(0);elseif(ifc.ifc_len = lastlen);break;lastlen=ifc.ifc_len;len+=10*(sizeof(struct ifreq);free(buf);ifihead=NULL;ifipnext=&ifihead;lastname0=0;sdlname=NULL;for(ptr=buf;ptrifr_addr.sa_len);#elseswitch(ifr-ifr_addr.sa_family)#ifdefIPV6case AF_INET6:len=sizeof(struct sockaddr_in6);break;#endifcase AF_INET:default:len=sizeof(struct sockaddr);break;#endifptr+=sizeof(ifr-ifr_name)+len;#ifdef HAVE_SOCKADDR_DL_STRUCTif(ifr-ifr_addr.sa_family=AF_LINE)struct sockaddr_dl *sdl=(struct sockaddr_dl*)&ifr-ifr_addr;sdlname=ifr-ifr_name;idx=sdl-sdl_index;haddr=sdl-sdl_data + sdl-sdl_nlen;hlen=sdl-sdl_alen;#endifif(ifr-ifr_addr.sa_family != family)continue;myflags=0;if(cptr=strchr(ifr-ifr_name,:)!=NULL)*cptr=0;if(strncmp(lastname,ifr-ifr_name,IFNAMSIZ) =0)if(doaliases=0)continue;myflags=IFI_ALIAS;memcpy(lastname,ifr-ifr_name,IFNAMSIZ);ifrcopy = *ifr;ioctl(sockfd,SIOCGIFFLAGS,&ifrcopy);flags=ifrcopy.ifr_flags;if(flags & IFF_UP)=0)continue;ifi=(ifi_info*)calloc(1,sizeof(struct ifi_info);*ifipnext=ifi;ifipnext=&ifi-ifi_next;ifi-ifi_flags=flags;ifi-ifi_myflags=myflags;#if defined(SIOCGIFMTU) & defined(HAVE_STRUCT_IFREQ_IFR_MTU)ioctl(sockfd,SIOCGIFMTU,&ifrcopy);ifi-ifi_mtu=ifrcopy.ifr_mtu;#else ifi-ifi_mtu=0;#endifmemcpy(ifi-ifi_name,ifr-ifr_name,IFI_NAME);ifi-ifi_nameIFI_NAME-1=0;if(sdlname=NULL | strcmp(sdlname,ifr-ifr_name) != 0)idx=hlen=0;ifi-ifi_index=idx;ifi-ifi_hlen=hlen;if(ifi-ifi_hlen IFI_HADDR)ifi-ifi_hlen=IFI_HADDR;if(hlen)memcpy(ifi-ifi_haddr,haddr,ifi-ifi_hlen);switch(ifr-ifr_addr.sa_family)case AF_INET:sinptr=(struct sockaddr_in*)&ifr-ifr_addr;ifi-ifi_addr=(struct sockaddr*)calloc(1,sizeof(struct sockaddr_in);memcpy(ifi-ifi_addr,sinptr,sizeof(struct sockaddr_in);#ifdef SIOCGIFBRDADDRif(flags & IFF_BROADCAST)ioctl(sockfd,SIOCGIFBRDADDR,&ifrcopy);sinptr=(struct sockaddr_in*)&ifrcopy.ifr_broadaddr;ifi-ifi_brdaddr=(struct sockaddr*)calloc(1,sizeof(struct sockaddr_in);memcpy(ifi-ifi_brdaddr,sinptr,sizeof(struct sockaddr_in);#endif#ifdefSIOCGIFDSTADDRif(flags & IFF_POINTOPOINT)ioctl(sockfd,SIOCGIFDSTADDR,&ifrcopy);sin6ptr=(struct sockaddr_in6*)&ifrcopy.ifr_dstaddr;ifi-ifi_dstaddr=(struct sockaddr*)calloc(1,sizeof(struct sockaddr_in6);memcpy(ifi-ifi_dstaddr,sin6ptr,sizeof(struct sockaddr_in6);#endifbreak;default:break;free(buf);return(ifihead);void free_ifi_info(struct ifi_info *ifihead)struct ifi_info *ifi,*ifinext;for(ifi = ifihead;ifi != NULL;ifi=ifinext)if(ifi-ifi_addr != NULL)free(ifi-ifi_addr);if(ifi-ifi_dstaddr != NULL)free(ifi-ifi_brdaddr);if(ifi-ifi_dstaddr != NULL)free(ifi-ifi_dstaddr);ifinext=ifi-ifi_next;free(ifi);int main(int argc,char* argv)struct ifi_info *ifi,*ifihead;struct sockaddr* sa;u_char *ptr;int i,family,doaliases;if(argc != 3)coutusage: prifinfo endl;exit(0);if(strcmp(argv1,inet4)=0)family=AF_INET;else if(strcmp(argv1,inet6)=0)family=AF_INET6;elsecoutinvalid ifi_next)printf(%s: ,ifi-ifi_name);if(ifi-ifi_index != 0)printf(%d) ,ifi-ifi_index);printf(ifi_flags & IFF_UP) printf(UP );if(ifi-ifi_flags & IFF_BROADCAST) printf(BCAST );if(ifi-ifi_flags & IFF_MULTICAST) printf(MCAST );if(ifi-ifi_flags & IFF_LOOPBACK) printf(LOOP );if(ifi-ifi_flags & IFF_POINTOPOINT) printf(P2P );printf(n);if(i=ifi-ifi_hlen) 0)ptr=ifi-ifi_haddr;doprintf(%s%x, (i = ifi-ifi_hlen) ? : :,*ptr+);while(-i0);printf(n);if(ifi-ifi_mtu != 0)printf( MTU: %dn,ifi-ifi_mtu);if(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 进口产品合作合同范本
- 租场地存放合同协议书
- 2025年高中三年级化学上学期专项练习
- 酒店包房租赁合同范本
- 物业管理业务合同范本
- 社区团购物流合同范本
- 眼科视力矫正合同范本
- 监理公司出资合同范本
- 行政合同拆迁补偿协议
- 华师大版七年级上册1 有理数的乘法法则教学设计
- 建筑塔式起重机安全规程
- 信息安全意识培训课件
- 《城市轨道交通车载轨道高速巡检系统技术规范》
- 房地产 -JGJT46-2024《施工现场临时用电安全技术标准》条文解读
- 部编高教版2023·职业模块 中职语文 品质
- 2024年勘察劳务分包合同
- 2025届重庆市康德卷物理高二第一学期期中达标检测试题含解析
- (人教版2024)数学三年级上册第6单元《多位数乘一位数》大单元教学课件
- 公路工程标准施工招标文件(2018年版)
- DL∕T 1098-2016 间隔捧技术条件和试验方法
- Q-CR 838-2021 系列2集装箱 40英尺35t通.用集装箱
评论
0/150
提交评论