實現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)
- {
- S8 *interface="eth0";
-
- struct in_addr ipaddr;
- struct in_addr netmaskaddr;
- struct in_addr gwaddr;
-
- inet_aton("192.168.2.18",&ipaddr);
- inet_aton("255.240.0.0",&netmaskaddr);
- inet_aton("192.168.2.3",&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));
- while(1){
- 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;
-
- }
歡迎關注本站公眾號,獲取更多信息