linux 利用ioctl函数获取IP地址、子网掩码、MAC地址和修改本机IP地址、子网掩码、网关

ioctl函数原型:

int ioctl(int fd, int request, ..../*void *arg*/)

int fd:为socket函数返回值

int request:SIOCSIFADDR 修改ip地址

                    SIOCSIFNETMASK 修改子网掩码

                    SIOCADDRT  修改网关

第三个参数:ip和子网掩码对应的结构体struct  ifreq;网关的结构体struct rtentry


//.h

#include <stdlib.h>
#include <string.h>
#include <pcap.h> 
#include <sys/types.h>
#include <sys/socket.h>  
#include <netinet/in.h> 
#include <netinet/ip.h>
#include <netinet/ether.h> 
#include <net/if.h>  
#include <arpa/inet.h> 
#include <net/if_arp.h>    
#include <sys/ioctl.h> 
#include <string.h>  
#include <errno.h> 
#include <unistd.h> 
#include <net/route.h>

//.cpp 修改ip地址

bool SetLocalIp(char *ipaddr)  
{  
    if (NULL == ipaddr)
    {
        printf("SetLocalIp: ipaddr is null\n");
        return false;
    }
  
    int sock_set_ip;  
      
    struct sockaddr_in sin_set_ip;  
    struct ifreq ifr_set_ip;  
  
    bzero( &ifr_set_ip,sizeof(ifr_set_ip));  
   
    if( ipaddr == NULL )  
        return false;  

    if(sock_set_ip = socket(PF_INET, SOCK_STREAM, 0 ) == -1);  
    {  
        perror("socket create failse...SetLocalIp!/n");  
        return false;  
    }  
  
    memset( &sin_set_ip, 0, sizeof(sin_set_ip));  
    strncpy(ifr_set_ip.ifr_name, "eth0", sizeof(ifr_set_ip.ifr_name)-1);     
      
    sin_set_ip.sin_family = AF_INET;  
    sin_set_ip.sin_addr.s_addr = inet_addr(ipaddr);  
    memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip));  
  
    if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < 0 )  
    {  
        perror( "Not setup interface/n");  
        return false;  
    }  
   
    ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING;  
  
    //get the status of the device  
    if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < 0 )  
    {  
         perror("SIOCSIFFLAGS");  
         return false;  
    }  
  
    close( sock_set_ip); 
   
    return true;  
}

//.cpp 修改子网掩码

bool SetLocalNetMask(char *netMask)
{
    int socketfd;
    
    if (NULL == netMask)
    {
        printf("SetLocalNetMask: netMask is null\n");
        return false;
    }

    if(socketfd = socket(PF_INET, SOCK_STREAM, 0 ) == -1);  
    {  
        perror("socket create failse...SetLocalNetMask!/n");  
        return false;  
    } 

    struct ifreq ifr_mask;
    struct sockaddr_in *sin_net_mask;

    memset(&ifr_mask, 0, sizeof(ifr_mask));
    strncpy(ifr_mask.ifr_name, "eth0", sizeof(ifr_mask.ifr_name) - 1);
    sin_net_mask = (struct sockaddr_in *)&ifr_mask.ifr_addr;
    sin_net_mask->sin_family = AF_INET;
    inet_pton(AF_INET, netMask, &sin_net_mask->sin_addr);

    if (ioctl(socketfd, SIOCSIFNETMASK, &ifr_mask) < 0)
    {
        printf("socket_netmask ioctl error!\n");
        return false;
    }

    close( socketfd );    
    return true;
}

//.cpp 修改网关

bool SetLocalRoute(char *szGateWay)
{
    int sockfd;
    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1)
    {
        return false;
    }

    struct rtentry rmten;
    struct sockaddr_in ic_gateway ;	// Gateway IP address 
    int err;
    
    memset(&rmten, 0, sizeof(rmten));
       
    ic_gateway.sin_family = AF_INET; 
    ic_gateway.sin_addr.s_addr = inet_addr(szGateWay);
    ic_gateway.sin_port = 0; 

    ((struct sockaddr_in*)&rmten.rt_dst)->sin_family = AF_INET;
    ((struct sockaddr_in*)&rmten.rt_dst)->sin_addr.s_addr = 0;
    ((struct sockaddr_in*)&rmten.rt_dst)->sin_port = 0;

    ((struct sockaddr_in*)&rmten.rt_genmask)->sin_family = AF_INET;
    ((struct sockaddr_in*)&rmten.rt_genmask)->sin_addr.s_addr = 0;
    ((struct sockaddr_in*)&rmten.rt_genmask)->sin_port = 0;

    memcpy((void *) &rmten.rt_gateway, &ic_gateway, sizeof(ic_gateway));
    rmten.rt_flags = RTF_UP | RTF_GATEWAY;
    
    if ((err = ioctl(sockfd, SIOCADDRT, &rmten)) < 0) 
    {
        printf("ioctl net error!\n");
        return false;
    }

    close( sockfd );
    return true;
}


//.cpp 获得IP地址、子网掩码、MAC物理地址

bool GetIpMacMaskAddress()
{
    unsigned char ipaddress[INET_MACADDRESSLEN];    
    unsigned char macaddress[INET_MACADDRESSLEN];
    unsigned char netmask[INET_MACADDRESSLEN];
    
    struct ifreq struReq;
    memset(&struReq, 0x00, sizeof(struct ifreq));
    strncpy(struReq.ifr_name, "eth0", sizeof(struReq.ifr_name));  
    
    socketfd = socket(PF_INET, SOCK_STREAM, 0);
    
    if (-1 == ioctl(socketfd, SIOCGIFHWADDR, &struReq))
    {
        printf("ioctl hwaddr error!\n");
        return false;
    }

    strcpy((char *)macaddress, ether_ntoa((ether_addr*)struReq.ifr_hwaddr.sa_data)); 

    if (-1 == ioctl(socketfd, SIOCGIFADDR, &struReq))
    {
        printf("ioctl ip address error!\n");
        return false;
    }

    strcpy((char *)ipaddress, inet_ntoa(((struct sockaddr_in *)&(struReq.ifr_addr))->sin_addr));

    if (-1 == ioctl(socketfd, SIOCGIFNETMASK, &struReq))
    {
        printf("ioctl net mask error!\n");
        exit(1);
    }

    strcpy((char *)netmask, inet_ntoa(((struct sockaddr_in *)&(struReq.ifr_netmask))->sin_addr));    

    printf("MacAddress: %s\n", macaddress);
    printf("IpAddress: %s\n", ipaddress);
    printf("NetMask: %s\n",netmask);

    close(socketfd);

    return true;   
}



     

好的,以下是一个使用getifaddrs函数获取网络接口信息的C程序,包括名称、MAC地址子网掩码IP地址网关信息。请注意,获取网关信息需要使用系统调用来实现,因此这个程序只能在类Unix系统上运行。 ```c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { struct ifaddrs *ifaddr, *ifa; int family, s, n; char host[NI_MAXHOST]; char gateway[NI_MAXHOST]; char mac[18]; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); return EXIT_FAILURE; } /* Walk through linked list, maintaining head pointer so we can free list later */ for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { if (ifa->ifa_addr == NULL) { continue; } family = ifa->ifa_addr->sa_family; /* Display interface name and family (including symbolic form of the latter for the common families) */ printf("%-8s %s (%d)\n", ifa->ifa_name, (family == AF_PACKET) ? "AF_PACKET" : (family == AF_INET) ? "AF_INET" : (family == AF_INET6) ? "AF_INET6" : "???", family); /* For an AF_PACKET interface, display the MAC address. */ if (family == AF_PACKET && ifa->ifa_data != NULL) { struct sockaddr_ll *s = (struct sockaddr_ll*)ifa->ifa_addr; sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x", s->sll_addr[0], s->sll_addr[1], s->sll_addr[2], s->sll_addr[3], s->sll_addr[4], s->sll_addr[5]); printf("\t\tAddress: %s\n", mac); } /* For an AF_INET or AF_INET6 interface, display the address and subnet mask */ else if (family == AF_INET || family == AF_INET6) { s = socket(family, SOCK_DGRAM, 0); if (s == -1) { perror("socket"); return EXIT_FAILURE; } if (getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) { printf("\t\tAddress: <%s>\n", host); } if (getnameinfo(ifa->ifa_netmask, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) { printf("\t\tNetmask: <%s>\n", host); } /*Get the gateway address*/ if (family == AF_INET) { struct rtentry *route; memset(&route, 0, sizeof(route)); route->rt_dst.sa_family = AF_INET; ((struct sockaddr_in *) &route->rt_dst)->sin_addr.s_addr = 0; route->rt_flags = RTF_UP; if (ioctl(s, SIOCADDRT, &route) < 0) { perror("SIOCADDRT failed"); return EXIT_FAILURE; } struct sockaddr_in *addr; for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { addr = (struct sockaddr_in *) ifa->ifa_addr; if (ifa->ifa_flags & IFF_LOOPBACK) { continue; } if (addr->sin_addr.s_addr == ((struct sockaddr_in *) &route->rt_dst)->sin_addr.s_addr) { continue; } if (ioctl(s, SIOCGIFHWADDR, ifa) == -1) { perror("ioctl failed"); return EXIT_FAILURE; } if (ifa->ifa_addr) { inet_ntop(AF_INET, &addr->sin_addr, gateway, NI_MAXHOST); printf("\t\tGateway: %s\n", gateway); } } } if (ioctl(s, SIOCDELRT, &route) < 0) { perror("SIOCDELRT failed"); return EXIT_FAILURE; } } close(s); } } freeifaddrs(ifaddr); return EXIT_SUCCESS; } ``` 这个程序将会打印出每个网络接口的名称、MAC地址IP地址子网掩码网关信息。如果某个接口没有网关,它将不会打印网关信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值