C 语言实现linux读取和修改IP地址

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <errno.h>
#include <features.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/route.h>
#include <stdio.h>
 
#define   FAILURE   0
#define   SUCCESS   1
typedef unsigned char           UNS8; /* 8-bit */
typedef unsigned short          UNS16;  /* 16-bit */
typedef unsigned int            UNS32;  /* 32-bit */  
typedef unsigned long long int  UNS64;  /* 64-bit */
typedef char                    S8;   /* 8-bit */
typedef short                   S16;  /* 16-bit */
typedef int                     S32;  /* 32-bit */  
typedef long long int           S64;  /* 64-bit */
typedef enum {
    FALSE,
    TRUE
} BOOL;
#define m_MSG(format, args...)  printf(format, ## args)
#define m_ERROR(terminal,format, args...)  fprintf(terminal,format, ## args)
#define m_DEBUG(format, args...)  printf(format, ## args)
 
 
typedef struct _rt {
    UNS32 dst;
    UNS32 mask;
    UNS32 gw;
    S32   flags;
}RT;
S32 setDefaultRoute( S32 fd, S8 *interface, UNS32 *route_addr )
{
    struct  rtentry     rtent;
    struct  sockaddr_in *p;
 
    memset( &rtent,0,sizeof( struct rtentry ) );
    p = ( struct sockaddr_in * ) &rtent.rt_dst;
    p->sin_family = AF_INET;
    p->sin_addr.s_addr = 0;
    p = ( struct sockaddr_in * ) &rtent.rt_gateway;
    p->sin_family = AF_INET;
    p->sin_addr.s_addr = *route_addr;
    p = ( struct sockaddr_in * ) &rtent.rt_genmask;
    p->sin_family = AF_INET;
    p->sin_addr.s_addr = 0;
 
    rtent.rt_dev = interface;
 
    rtent.rt_metric = 1;
    rtent.rt_window = 0;
    rtent.rt_flags = RTF_UP | RTF_GATEWAY;
    if ( ioctl( fd,SIOCADDRT,&rtent ) == -1 ) {
        if ( errno == ENETUNREACH )    /* possibly gateway is over the bridge */ {
            /* try adding a route to gateway first */
            memset( &rtent,0,sizeof( struct rtentry ) );
            p = ( struct sockaddr_in * ) &rtent.rt_dst;
            p->sin_family = AF_INET;
            p->sin_addr.s_addr = *route_addr;
            p = ( struct sockaddr_in * ) &rtent.rt_gateway;
            p->sin_family = AF_INET;
            p->sin_addr.s_addr = 0;
            p = ( struct sockaddr_in * ) &rtent.rt_genmask;
            p->sin_family = AF_INET;
            p->sin_addr.s_addr = 0xffffffff;
 
 
            rtent.rt_dev = interface;
            rtent.rt_metric = 0;
            rtent.rt_flags = RTF_UP | RTF_HOST;
            if ( ioctl( fd,SIOCADDRT,&rtent ) == 0 ) {
                memset( &rtent,0,sizeof( struct rtentry ) );
                p = ( struct sockaddr_in * ) &rtent.rt_dst;
                p->sin_family = AF_INET;
                p->sin_addr.s_addr = 0;
                p = ( struct sockaddr_in * ) &rtent.rt_gateway;
                p->sin_family = AF_INET;
                p->sin_addr.s_addr = *route_addr;
                p = ( struct sockaddr_in * ) &rtent.rt_genmask;
                p->sin_family = AF_INET;
                p->sin_addr.s_addr = 0;
 
 
                rtent.rt_dev = interface;
 
                rtent.rt_metric = 1;
                rtent.rt_window = 0;
                rtent.rt_flags = RTF_UP | RTF_GATEWAY ;
                if ( ioctl( fd,SIOCADDRT,&rtent ) == -1 ) {
                    m_ERROR(stderr,"ioctl SIOCADDRT: %m\n");
                    return FAILURE;
                }
            }
        } else {
            m_ERROR(stderr,"ioctl SIOCADDRT: %m\n" );
            return FAILURE;
        }
    }
    return SUCCESS;
}
//Íš¹ý¶ÁÈ¡ /proc/net/route»ñȡ·Óɱí
S32 get_route( FILE *fp,RT *rt )
{
    S8          devname[64] ;
    UNS32       d, g, m;
    S32         flgs,ref,use,metric,mtu,win,ir;
    S32         r;
 
    if ( fp == NULL ) {
        m_DEBUG("I am here 1\n\n");
        return FAILURE;
    }
    r = fscanf( fp,"%63s%lx%lx%X%d%d%d%lx%d%d%d\n",devname,&d,&g,&flgs,&ref,&use,&metric,&m,&mtu,&win,&ir );
    if ( r != 11 ) {
        if ( ( r < 0 ) && feof( fp ) ) {
            /* EOF with no (nonspace) chars read. */
            m_DEBUG("I am here 3\n\n");
            return FAILURE;
        }
        m_DEBUG("I am here 4\n\n");
        return FAILURE;
    }
 
    if ( !( flgs & RTF_UP ) ) {
        /* Skip interfaces that are down. */
        m_DEBUG("I am here 5\n\n");
        return get_route( fp,rt );
    }
 
    rt->dst = d;
    rt->mask = m;
    rt->gw = g;
    rt->flags = flgs;
 
    return SUCCESS;
}
S32 read_interface( S8 *interface, UNS32 *ipaddr, UNS32 *netmaskaddr, UNS32 *gwaddr )
{
    S32               fd;
    struct ifreq      ifr;
    struct sockaddr_in*our_ip;
    RT                rt;
    S32               fret;
    FILE              *fp = NULL;
 
    *ipaddr = 0;
    *netmaskaddr = 0;
    *gwaddr = 0;
    memset( &ifr,0,sizeof( struct ifreq ) );
    if ( ( fd = socket( AF_INET,SOCK_RAW,IPPROTO_RAW ) ) >= 0 ) {
        ifr.ifr_addr.sa_family = AF_INET;
        strcpy( ifr.ifr_name,interface );
 
        if ( ipaddr ) {
                bzero(ipaddr,sizeof(UNS32));
            if ( ioctl( fd,SIOCGIFADDR,&ifr ) == 0 ) {
                our_ip = ( struct sockaddr_in * ) &ifr.ifr_addr;
                *ipaddr = our_ip->sin_addr.s_addr;
            } else {
                m_ERROR(stderr, "SIOCGIFADDR failed, is the interface up and configured?: %m" );
                close( fd );
                return FAILURE;
            }
        }
        if ( netmaskaddr ) {
                bzero(netmaskaddr,sizeof(UNS32));
            if ( ioctl( fd,SIOCGIFNETMASK,&ifr ) == 0 ) {
                our_ip = ( struct sockaddr_in * ) &ifr.ifr_netmask;
                *netmaskaddr = our_ip->sin_addr.s_addr;
            } else {
                m_ERROR(stderr,"SIOCGIFHWADDR failed!: %m" );
                close( fd );
                return FAILURE;
            }
        }
    } else {
        m_ERROR(stderr,"socket failed!: %m" );
        return FAILURE;
    }
    close( fd );
    if ( gwaddr ) {
        bzero(gwaddr,sizeof(UNS32));
        fp = fopen( "/proc/net/route","r" );
        if ( fp == NULL ) {
            return FAILURE;
        }else{
            if ( fscanf( fp,"%*[^\n]\n" ) < 0 ) {/* Skip the first line. */         
                /* Empty or missing line, or read error. */         
                m_DEBUG("I am here 2\n\n");
                return FAILURE;
            }
        }
        while ( ( fret = get_route( fp,&rt ) ) == SUCCESS ) {
            m_DEBUG("DST:0x%08x,FLAGS:0x%08x,GW:0x%08x,MASK:0x%08x\n",rt.dst,rt.flags,rt.gw,rt.mask);
            if ( rt.flags & RTF_GATEWAY ) {
                *gwaddr = rt.gw;
                break;
            }
        }
        fclose(fp);
        if ( fret != SUCCESS ) {
            return FAILURE;
        }
    }
 
    return SUCCESS;
}
 
S32 write_interface( S8 *interface, UNS32 *ipaddr, UNS32 *netmaskaddr, UNS32 *gwaddr )
{
    S32               fd;
    struct ifreq      ifr;
    struct sockaddr_in*p  = ( struct sockaddr_in * ) &( ifr.ifr_addr );
 
    memset( &ifr,0,sizeof( struct ifreq ) );
    if ( interface ) {
        strcpy( ifr.ifr_name,interface );
    } else {
        return FAILURE;
    }
 
 
    if ( ( fd = socket( AF_INET,SOCK_STREAM,0 ) ) >= 0 ) {
        ifr.ifr_addr.sa_family = AF_INET;
        if ( ipaddr ) {
            p->sin_addr.s_addr = *ipaddr;
            if ( ioctl( fd,SIOCSIFADDR,&ifr ) == -1 ) { /* setting IP address */  
                m_ERROR(stderr,"ioctl SIOCSIFADDR: %m\n" );
                return FAILURE;
            }
        }
        if ( netmaskaddr ) {
            p->sin_addr.s_addr = *netmaskaddr;
            if ( ioctl( fd,SIOCSIFNETMASK,&ifr ) == -1 ) { /* setting netmask */  
                p->sin_addr.s_addr = 0xffffffff; /* try 255.255.255.255 */
                if ( ioctl( fd,SIOCSIFNETMASK,&ifr ) == -1 ) {
                    m_ERROR(stderr,"ioctl SIOCSIFNETMASK: %m\n" );
                    return FAILURE;
                }
            }
        }
        if (ipaddr && netmaskaddr){
            p->sin_addr.s_addr=*ipaddr|(~*netmaskaddr);
            if ( ioctl(fd,SIOCSIFBRDADDR,&ifr) == -1 ) {/* setting broadcast address */
                m_ERROR(stderr,"ioctl SIOCSIFBRDADDR: %m\n");
                return FAILURE;
            }
        }
        if ( gwaddr ) {
            return setDefaultRoute( fd,interface,gwaddr );
        }
        close( fd );
    } else {
        m_ERROR(stderr,"socket failed!: %m" );
        return FAILURE;
    }        
    
    return SUCCESS;
}
 
int main(void)
{
 
     char *interface="eth0";
 
     struct in_addr ipaddr;
     struct in_addr netmaskaddr;
     struct in_addr gwaddr;
 
     //inet_aton("192.168.1.164",&ipaddr);
     //inet_aton("255.255.255.0",&netmaskaddr);
     //inet_aton("192.168.1.1",&gwaddr);
 
    //write_interface(interface,(UNS32 *)&ipaddr,(UNS32 *)&netmaskaddr,(UNS32 *)&gwaddr);
    //bzero(&ipaddr,sizeof(struct in_addr));
    //bzero(&netmaskaddr,sizeof(struct in_addr));
    //bzero(&gwaddr,sizeof(struct in_addr));
 
    read_interface(interface,(UNS32 *)&ipaddr,(UNS32 *)&netmaskaddr,(UNS32 *)&gwaddr);
    
        
        m_DEBUG("ipaddr:%s\n", inet_ntoa(ipaddr));
    m_DEBUG("netmask:%s\n",inet_ntoa(netmaskaddr));
    m_DEBUG("gateway:%s\n",inet_ntoa(gwaddr));
    //usleep(500000);
 
 
    return SUCCESS;
    
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值