iotcl函数与网络接口

来源:互联网 发布:300036 超图软件 编辑:程序博客网 时间:2024/05/21 06:16

viewplaincopy to clipboardprint?
#include<stdio.h>           //printf()  
#include<unistd.h>          //ioctl()  
#include <sys/ioctl.h>       //ioctl  
#include <sys/socket.h>      //socket()  
#include<net/if.h>          //struct ifconf{} & struct ifreq{}  
#include<string.h>          //strcpy()  
#include <arpa/inet.h>       //inet_ntoa()  
#include<stdlib.h>          //malloc() & free()  

int print_if_addr(int fd, char *interface_name);    //打印接口的ip地址  
int print_if_mac(int fd, char *interface_name); //打印接口的mac地址  
int print_if_broadaddr(int fd, char *interface_name);   //打印接口的广播地址  
int print_if_mask(int fd, char *interface_name);    //打印接口的掩码  
int print_if_mtu(int fd, char *interface_name); //打印接口的mtu  
int print_all_interface(); //打印所有接口的基本信息  
int print_if_addr6(char *interface_name);   //打印接口的ipv6地址  
int print_interface_info(char *interface_name); //打印接口的以上所有信息  
int set_if_up(char *interface_name);       //启动接口  
int set_if_down(char *interface_name);      //关闭接口  
int set_if_ip(char *interface_name, char *ip_str); //设置接口的ip地址  
void usage();   //打印该程序的使用手册  

int main(int argc, char **argv)  
{  
    int sockfd;  

    printf("\n **********funway:用ioctl函数来实现ifconfig命令的效果**********\n");  

    switch(argc)  
    {  
    case 1:  
       print_all_interface();        
        break;  
    case 2:  
       print_interface_info(argv[1]);  
        break;  
    case 3:  
        if(strcmp(argv[2], "up")== 0)  
           set_if_up(argv[1]);  
        else if(strcmp(argv[2],"down") == 0)  
           set_if_down(argv[1]);  
        else   
           set_if_ip(argv[1], argv[2]);  
        break;  
    default:  
        usage();  
        break;  
    }  

    return 0;  
}  

void usage()  
{  
    printf("usage: ./myifconfig [interface[down|up|ip]]\n");  
}  

int print_if_addr(int fd, char *if_name)  
{  
    struct sockaddr_in *ip;  
    struct ifreq ifr;  

    strcpy(ifr.ifr_name, if_name);  

    if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFADDRerror");  
        return -1;  
    }  
      
    ip = (struct sockaddr_in*)&ifr.ifr_addr;       //获得ipv4地址  
    printf("    IP: %s\n",inet_ntoa(ip->sin_addr)); //将ipv4地址转换为主机字节序的字符串并输出  
    return 0;  
}  

int print_if_broadaddr(int fd, char *if_name)  
{  
    struct sockaddr_in *ip;  
    struct ifreq ifr;  

    strcpy(ifr.ifr_name, if_name);  

    if(ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFBRDADDRerror");  
        return -1;  
    }  
      
    ip = (struct sockaddr_in *)&ifr.ifr_broadaddr; //获得广播地址  
    printf("    Broadcast: %s\n", inet_ntoa(ip->sin_addr));  
    return 0;  
}  

int print_if_mask(int fd, char *if_name)  
{  
    struct sockaddr_in *ip;  
    struct ifreq ifr;  

    strcpy(ifr.ifr_name, if_name);  

    if(ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFNETMASKerror");  
        return -1;  
    }  
      
    ip = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_netmask;//获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回  
    printf("    Mask: %s\n",inet_ntoa(ip->sin_addr));  
    return 0;  
}  

int print_if_mac(int fd, char *if_name)  
{  
    unsigned char *p;   //注意! 这里要用unsigned char,而不是char!因为char要对[1xxx xxxx]这样的数进行补码运算的。  
                   //但我们等下要打印的mac地址是不需要符号的数值  
    struct ifreq ifr;  

    strcpy(ifr.ifr_name, if_name);  

    if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFHWADDRerror");  
        return -1;  
    }  
      
    p = (char*)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];   //获得接口的MAC地址,用字符串指针返回  
    printf("    MAC:%02x:%02x:%02x:%02x:%02x:%02x\n", *p, *(p+1), *(p+2), *(p+3), *(p+4),*(p+5));  
    //printf(" MAC:%02x:%02x:%02x:%02x:%02x:%02x\n",*p++, *p++, *p++, *p++, *p++, *p++);  
        //这么写会导致输出为倒序。这并不是p指针有什么问题,不信你可以用  
        // for(;;)   
        // printf(p++);  
        //来试验就是正确的,我猜倒序的原因是编译器的优化问题吧  
    return 0;  
}  

int print_if_mtu(int fd, char *if_name)  
{  
    unsigned int mtu;  
    struct ifreq ifr;  

    strcpy(ifr.ifr_name, if_name);  

    if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFMTUerror");  
        return -1;  
    }  
      
    mtu = ifr.ifr_ifru.ifru_mtu;    //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回  
    printf("    MTU: %d\n",mtu);  
    return 0;  
}  

int print_if_addr6(char *if_name)  
{  
    unsigned int mtu;  
    struct ifreq ifr;  
    int sockfd;  
      
    if((sockfd = socket(AF_INET6, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socketerror");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  

/* strcpy(ifr.ifr_name, if_name);

    if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)
    {
        perror("ioctl SIOCGIFMTUerror");
        return -1;
    }
     
    mtu = ifr.ifr_ifru.ifru_mtu;    //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回
    printf("    ipv6: %d\n", mtu);
*/
//未写完,不知道怎么获得ipv6地址。。。  
    return 0;  
}  

int print_all_interface()  
{  
    struct ifconf ifc;  
    struct ifreq *ifr_p;  
    int sockfd, len, old_len = 0, i;  
    char *buf;  

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socketerror");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  
      
    len = 10 * sizeof(struct ifreq);  
    for( ; ; )  
    {  
        if((buf = malloc(len)) ==NULL)  
        {  
           perror("malloc error");  
            return-1;  
        }  
        ifc.ifc_len = len;  
        ifc.ifc_buf = buf;  
        if(ioctl(sockfd, SIOCGIFCONF,&ifc) < 0)  
        {  
           perror("ioctl SIOCGIFCONF error");  
            return-1;  
        }     
        if(ifc.ifc_len ==old_len)  
           break;  
        old_len = ifc.ifc_len;  
        len += 10 * sizeof(structifreq);  
        free(buf);  
    }     
    printf("we have %d interfaces\n", ifc.ifc_len /sizeof(struct ifreq));  
      
    for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq);i++)  
    {  
        ifr_p =&ifc.ifc_req[i];  
        printf("\ninterface[%s]:\n", ifr_p->ifr_name);  

        print_if_addr(sockfd,ifr_p->ifr_name);  
        print_if_broadaddr(sockfd,ifr_p->ifr_name);  
        print_if_mask(sockfd,ifr_p->ifr_name);  
        print_if_mac(sockfd,ifr_p->ifr_name);  
        print_if_mtu(sockfd,ifr_p->ifr_name);  
    }  
    close(sockfd);  
    return 0;  
}  

int print_interface_info(char *if_name)  
{  
    int sockfd;  
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socketerror");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  

    printf("%s:\n", if_name);  
    print_if_addr(sockfd, if_name);  
    print_if_broadaddr(sockfd, if_name);  
    print_if_mask(sockfd, if_name);  
    print_if_mac(sockfd, if_name);  
    print_if_mtu(sockfd, if_name);    
    close(sockfd);  
    return 0;  
}  

int set_if_up(char *if_name)        //启动接口  
{  
    struct ifreq ifr;  
    int sockfd;  

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socketerror");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  

    strcpy(ifr.ifr_name, if_name);  
    if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFFLAGSerror");  
        return -1;  
    }  
    ifr.ifr_flags |= IFF_UP;  
    if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)  
    {  
        perror("ioctl SIOCSIFFLAGSerror");  
        return -1;  
    }  
    return 0;  
}  

int set_if_down(char *if_name)      //关闭接口  
{  
    struct ifreq ifr;  
    int sockfd;  

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socketerror");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  

    strcpy(ifr.ifr_name, if_name);  
    if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)  
    {  
        perror("ioctl SIOCGIFFLAGSerror");  
        return -1;  
    }  
    ifr.ifr_flags &= ~IFF_UP;   //将IIF_UP取反后与原来的标志进行 与运算。  
    if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)  
    {  
        perror("ioctl SIOCSIFFLAGSerror");  
        return -1;  
    }  
    return 0;  
}  

int set_if_ip(char *if_name, char *ip_str) //设置接口的ip地址  
{  
    struct ifreq ifr;  
    struct sockaddr_in ip_addr;  
    int sockfd;  

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) <0)  
    {  
        perror("Socket error");  
        return -1;  
    }   // 创建用来检查网络接口的套接字  
      
    ip_addr.sin_family = AF_INET;     
    if(inet_pton(AF_INET, ip_str, &ip_addr.sin_addr) <1)  
    {  
        perror("error ipv4addr:");  
        return -1;  
    }     
      
    strcpy(ifr.ifr_name, if_name);  
    memcpy(&ifr.ifr_addr, &ip_addr, sizeof(structsockaddr_in));      
    if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)  
    {  
        perror("ioctl SIOCSIFADDRerror");  
        return -1;  
    }  
    return 0;     
}
#include <stdio.h>    //printf()
#include <unistd.h>    //ioctl()
#include <sys/ioctl.h>   //ioctl
#include <sys/socket.h>   //socket()
#include <net/if.h>    //struct ifconf{} & structifreq{}
#include <string.h>    //strcpy()
#include <arpa/inet.h>   //inet_ntoa()
#include <stdlib.h>    //malloc() & free()

intprint_if_addr(int fd, char *interface_name); //打印接口的ip地址
int print_if_mac(int fd, char *interface_name); //打印接口的mac地址
int print_if_broadaddr(int fd, char *interface_name); //打印接口的广播地址
int print_if_mask(int fd, char *interface_name); //打印接口的掩码
int print_if_mtu(int fd, char *interface_name); //打印接口的mtu
int print_all_interface(); //打印所有接口的基本信息
int print_if_addr6(char *interface_name); //打印接口的ipv6地址
int print_interface_info(char *interface_name); //打印接口的以上所有信息
int set_if_up(char *interface_name);   //启动接口
int set_if_down(char *interface_name);   //关闭接口
int set_if_ip(char *interface_name, char *ip_str); //设置接口的ip地址
void usage(); //打印该程序的使用手册

intmain(int argc, char **argv)
{
int sockfd;

printf("\n**********funway:用ioctl函数来实现ifconfig命令的效果**********\n");

switch(argc)
{
case 1:
   print_all_interface();  
   break;
case 2:
   print_interface_info(argv[1]);
   break;
case 3:
   if(strcmp(argv[2], "up") == 0)
    set_if_up(argv[1]);
   else if(strcmp(argv[2], "down") == 0)
    set_if_down(argv[1]);
   else
    set_if_ip(argv[1], argv[2]);
   break;
default:
   usage();
   break;
}

return0;
}

voidusage()
{
printf("usage: ./myifconfig [interface [down|up|ip]]\n");
}

intprint_if_addr(int fd, char *if_name)
{
struct sockaddr_in *ip;
struct ifreq ifr;

strcpy(ifr.ifr_name,if_name);

if(ioctl(fd,SIOCGIFADDR, &ifr) < 0)
{
   perror("ioctl SIOCGIFADDR error");
   return -1;
}

ip = (struct sockaddr_in *)&ifr.ifr_addr;   //获得ipv4地址
printf(" IP: %s\n", inet_ntoa(ip->sin_addr)); //将ipv4地址转换为主机字节序的字符串并输出
return 0;
}

intprint_if_broadaddr(int fd, char *if_name)
{
struct sockaddr_in *ip;
struct ifreq ifr;

strcpy(ifr.ifr_name,if_name);

if(ioctl(fd,SIOCGIFBRDADDR, &ifr) < 0)
{
   perror("ioctl SIOCGIFBRDADDR error");
   return -1;
}

ip = (struct sockaddr_in *)&ifr.ifr_broadaddr; //获得广播地址
printf(" Broadcast: %s\n", inet_ntoa(ip->sin_addr));
return 0;
}

intprint_if_mask(int fd, char *if_name)
{
struct sockaddr_in *ip;
struct ifreq ifr;

strcpy(ifr.ifr_name,if_name);

if(ioctl(fd,SIOCGIFNETMASK, &ifr) < 0)
{
   perror("ioctl SIOCGIFNETMASK error");
   return -1;
}

ip = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_netmask; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回
printf(" Mask: %s\n", inet_ntoa(ip->sin_addr));
return 0;
}

intprint_if_mac(int fd, char *if_name)
{
unsigned char *p; //注意! 这里要用unsigned char,而不是char!因为char要对[1xxxxxxx]这样的数进行补码运算的。
      //但我们等下要打印的mac地址是不需要符号的数值
struct ifreq ifr;

strcpy(ifr.ifr_name,if_name);

if(ioctl(fd,SIOCGIFHWADDR, &ifr) < 0)
{
   perror("ioctl SIOCGIFHWADDR error");
   return -1;
}

p = (char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0]; //获得接口的MAC地址,用字符串指针返回
printf(" MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", *p, *(p+1), *(p+2),*(p+3), *(p+4), *(p+5));
//printf(" MAC:%02x:%02x:%02x:%02x:%02x:%02x\n", *p++, *p++, *p++,*p++, *p++, *p++);
   //这么写会导致输出为倒序。这并不是p指针有什么问题,不信你可以用
   // for(;;)
   // printf(p++);
   //来试验就是正确的,我猜倒序的原因是编译器的优化问题吧
return 0;
}

intprint_if_mtu(int fd, char *if_name)
{
unsigned int mtu;
struct ifreq ifr;

strcpy(ifr.ifr_name,if_name);

if(ioctl(fd,SIOCGIFMTU, &ifr) < 0)
{
   perror("ioctl SIOCGIFMTU error");
   return -1;
}

mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在structaockaddr_in结构中返回
printf(" MTU: %d\n", mtu);
return 0;
}

intprint_if_addr6(char *if_name)
{
unsigned int mtu;
struct ifreq ifr;
int sockfd;

if((sockfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

/*strcpy(ifr.ifr_name, if_name);

if(ioctl(fd,SIOCGIFMTU, &ifr) < 0)
{
   perror("ioctl SIOCGIFMTU error");
   return -1;
}

mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在structaockaddr_in结构中返回
printf(" ipv6: %d\n", mtu);
*/
//未写完,不知道怎么获得ipv6地址。。。
return 0;
}

intprint_all_interface()
{
struct ifconf ifc;
struct ifreq *ifr_p;
int sockfd, len, old_len = 0, i;
char *buf;

if((sockfd= socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

len = 10 * sizeof(struct ifreq);
for( ; ; )
{
   if((buf = malloc(len)) == NULL)
   {
    perror("malloc error");
    return -1;
   }
   ifc.ifc_len = len;
   ifc.ifc_buf = buf;
   if(ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
   {
    perror("ioctl SIOCGIFCONF error");
    return -1;
   }
   if(ifc.ifc_len == old_len)
    break;
   old_len = ifc.ifc_len;
   len += 10 * sizeof(struct ifreq);
   free(buf);
}
printf("we have %d interfaces\n", ifc.ifc_len / sizeof(structifreq));

for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++)
{
   ifr_p = &ifc.ifc_req[i];
   printf("\ninterface [%s]:\n", ifr_p->ifr_name);

  print_if_addr(sockfd, ifr_p->ifr_name);
   print_if_broadaddr(sockfd, ifr_p->ifr_name);
   print_if_mask(sockfd, ifr_p->ifr_name);
   print_if_mac(sockfd, ifr_p->ifr_name);
   print_if_mtu(sockfd, ifr_p->ifr_name);
}
close(sockfd);
return 0;
}

intprint_interface_info(char *if_name)
{
int sockfd;
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

printf("%s:\n",if_name);
print_if_addr(sockfd, if_name);
print_if_broadaddr(sockfd, if_name);
print_if_mask(sockfd, if_name);
print_if_mac(sockfd, if_name);
print_if_mtu(sockfd, if_name);
close(sockfd);
return 0;
}

intset_if_up(char *if_name)   //启动接口
{
struct ifreq ifr;
int sockfd;

if((sockfd= socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

strcpy(ifr.ifr_name,if_name);
if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
{
   perror("ioctl SIOCGIFFLAGS error");
   return -1;
}
ifr.ifr_flags |= IFF_UP;
if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
{
   perror("ioctl SIOCSIFFLAGS error");
   return -1;
}
return 0;
}

intset_if_down(char *if_name)   //关闭接口
{
struct ifreq ifr;
int sockfd;

if((sockfd= socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

strcpy(ifr.ifr_name,if_name);
if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
{
   perror("ioctl SIOCGIFFLAGS error");
   return -1;
}
ifr.ifr_flags &= ~IFF_UP; //将IIF_UP取反后与原来的标志进行与运算。
if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
{
   perror("ioctl SIOCSIFFLAGS error");
   return -1;
}
return 0;
}

intset_if_ip(char *if_name, char *ip_str) //设置接口的ip地址
{
struct ifreq ifr;
struct sockaddr_in ip_addr;
int sockfd;

if((sockfd = socket(AF_INET, SOCK_DGRAM,0)) < 0)
{
   perror("Socket error");
   return -1;
} // 创建用来检查网络接口的套接字

ip_addr.sin_family = AF_INET;
if(inet_pton(AF_INET, ip_str, &ip_addr.sin_addr) < 1)
{
   perror("error ipv4 addr:");
   return -1;
}

strcpy(ifr.ifr_name, if_name);
memcpy(&ifr.ifr_addr, &ip_addr, sizeof(struct sockaddr_in));
if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)
{
   perror("ioctl SIOCSIFADDR error");
   return -1;
}
return 0;
}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小区移动4g差怎么办 梵妮印台干了怎么办 贴了膏药后过敏怎么办 贴药膏后皮肤痒怎么办 贴完膏药过敏了怎么办 骨折后骨密度低怎么办 食品经营许可证过期了怎么办 40年的产权满后怎么办 五证合一后税务怎么办 互联业务登录页怎么办 vivo音量键坏了怎么办 琴岛通学生卡怎么办 云卡会员删除了怎么办 办健康证没空腹怎么办 办健康证吃饭了怎么办 发票盖了财务章怎么办 发票盖成公章了怎么办 发票上盖了公章怎么办 进京证怎么办在哪里办 去北京没进京证怎么办 单位的车怎么办进京证 房贷合同丢了怎么办 农合医疗卡丢失怎么办 手指断了怎么办能好吗? 被劳务派遣公司骗了怎么办 餐饮服务许可证过期了怎么办 中行u盾证书过期怎么办 84消毒液吸多了怎么办 八四消毒液烧手怎么办 怀孕了下身痒怎么办啊 4s店态度差怎么办 小区的卡丢了怎么办 开老板的车撞了怎么办 车后保险杠撞裂怎么办 车到期了忘了审怎么办 改过气的车费油怎么办 车内容易进灰尘怎么办 东风天龙油耗高怎么办 国六出来了国五怎么办 手动挡有7个档位怎么办 东风天锦160没劲怎么办