您的位置:首页 > 运维架构 > Linux

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

2013-08-06 16:11 525 查看
#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: