Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4534429
  • 博文数量: 252
  • 博客积分: 5347
  • 博客等级: 大校
  • 技术积分: 13838
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-30 10:13
文章分类
文章存档

2022年(12)

2017年(11)

2016年(7)

2015年(14)

2014年(20)

2012年(9)

2011年(20)

2010年(153)

2009年(6)

分类: LINUX

2010-01-20 16:49:24

    在Linux下获得本机的IP地址,有以下几种方法,现终结如下:其中主要用到的,数据结构有以下几个。
struct ifreq 其定义在 /usr/include/net/if.h中。主要用来配置ip,激活接口信息。通常会和ifconf结合起来使用。这里有篇介绍这两个数据结构比较好的文章,链接如下:

   网上有介绍可以使用gethostname函数和gethostbyname函数获得本机的IP地址,其实获得的是127.0.0.1,是一个回环的地址。而不是真正的本机IP地址。

 
struct hostent *ent;
  gethostname(host_name,200);
  ent = gethostbyname(host_name);
  printf("****************************************\n");
  printf("The local host ip address: %s\n",inet_ntoa(*(struct in_addr *)ent->h_addr));


struct ifreq
  {
# define IFHWADDRLEN    6
# define IFNAMSIZ    IF_NAMESIZE
    union
      {
    char ifrn_name[IFNAMSIZ];    /* Interface name, e.g. "en0".

                                  这个参数是经常使用的,也就是接口的名字

                                 通常第一个网卡的名字是 “eth0” */
      } ifr_ifrn;

    union
      {
    struct sockaddr ifru_addr;
    struct sockaddr ifru_dstaddr;
    struct sockaddr ifru_broadaddr;
    struct sockaddr ifru_netmask;
    struct sockaddr ifru_hwaddr;
    short int ifru_flags;
    int ifru_ivalue;
    int ifru_mtu;
    struct ifmap ifru_map;
    char ifru_slave[IFNAMSIZ];    /* Just fits the size */
    char ifru_newname[IFNAMSIZ];
    __caddr_t ifru_data;
      } ifr_ifru;
  };
# define ifr_name    ifr_ifrn.ifrn_name    /* interface name     */
# define ifr_hwaddr    ifr_ifru.ifru_hwaddr    /* MAC address         */
# define ifr_addr    ifr_ifru.ifru_addr    /* address        */
# define ifr_dstaddr    ifr_ifru.ifru_dstaddr    /* other end of p-p lnk    */
# define ifr_broadaddr    ifr_ifru.ifru_broadaddr    /* broadcast address    */
# define ifr_netmask    ifr_ifru.ifru_netmask    /* interface net mask    */
# define ifr_flags    ifr_ifru.ifru_flags    /* flags        */
# define ifr_metric    ifr_ifru.ifru_ivalue    /* metric        */
# define ifr_mtu    ifr_ifru.ifru_mtu    /* mtu            */
# define ifr_map    ifr_ifru.ifru_map    /* device map        */
# define ifr_slave    ifr_ifru.ifru_slave    /* slave device        */
# define ifr_data    ifr_ifru.ifru_data    /* for use by interface    */
# define ifr_ifindex    ifr_ifru.ifru_ivalue /* interface index */
# define ifr_bandwidth    ifr_ifru.ifru_ivalue    /* link bandwidth    */
# define ifr_qlen    ifr_ifru.ifru_ivalue    /* queue length        */
# define ifr_newname    ifr_ifru.ifru_newname    /* New name        */
# define _IOT_ifreq    _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
# define _IOT_ifreq_int    _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)


struct ifconf
  {
    int    ifc_len;            /* Size of buffer. */
    union
      {
    __caddr_t ifcu_buf;
    struct ifreq *ifcu_req;
      } ifc_ifcu;
  };
# define ifc_buf    ifc_ifcu.ifcu_buf    /* Buffer address. */
# define ifc_req    ifc_ifcu.ifcu_req    /* Array of structures. */
# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */


void GetIP(void)

{

  int socket_fd;
  struct sockaddr_in *sin;
  struct ifreq *ifr;
  struct ifconf conf;
  char buff[BUFSIZ];
  int num;
  int i;
  socket_fd = socket(AF_INET,SOCK_DGRAM,0);
  conf.ifc_len = BUFSIZ;
  conf.ifc_buf = buff;
  ioctl(socket_fd,SIOCGIFCONF,&conf);
  num = conf.ifc_len / sizeof(struct ifreq);
  ifr = conf.ifc_req;
  printf("num=%d\n",num);
  for(i=0;i<num;i++)
  {
    struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);

    ioctl(socket_fd,SIOCGIFFLAGS,ifr);
    if(((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
    {
      printf("%s(%s)\n",ifr->ifr_name,inet_ntoa(sin->sin_addr));
    }
    ifr++;
  }

}


void GetIP2(void)

{

  int socket_fd;
  struct sockaddr_in *sin;
  struct ifreq ifr;
  struct ifconf conf;
  char buff[BUFSIZ];
  int num;
  int i;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
   if(socket_fd ==-1)
  {
     perror("socket error!\n");
    return -1;
  }

   strcpy(ifr.ifr_name,"eth1");

//这里要特别的注意,根据自己的系统的不同会有所差异有可能会是“eth0“。 如果出现错误提示 No such device 可能是这里的问题
  
  if(ioctl(socket_fd,SIOCGIFADDR,&ifr) < 0)
  {
    perror("ioctl error\n");
    return -1;
  }
  else
  {
    sin = (struct sockaddr_in *)&(ifr.ifr_addr);
    printf("current IP = %s\n",inet_ntoa(sin->sin_addr));

  }

}

还有一种IPv4和IPv6都通用的,主要参考网上的资料:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#define ETH_NAME "eth0"
#include <linux/sockios.h>
#include <ifaddrs.h>

int GetIP_v4_and_v6_linux(int family,char *address,int size)
{
  struct ifaddrs *ifap0,*ifap;
  char buf[NI_MAXHOST];
  char *interface = "eth1";
  struct sockaddr_in *addr4;
  struct sockaddr_in6 *addr6;
  int ret;
  if(NULL == address)
  {
  printf("in address"); 
  return -1;
 }
  if(getifaddrs(&ifap0))
  {
    return -1;
  }
  for(ifap = ifap0;ifap!=NULL;ifap=ifap->ifa_next)
  {
  
    
    if(strcmp(interface,ifap->ifa_name)!=0) continue;
    if(ifap->ifa_addr == NULL) continue;
    if((ifap->ifa_flags & IFF_UP) == 0) continue;
    if(family!=ifap->ifa_addr->sa_family) continue;

    if(AF_INET == ifap->ifa_addr->sa_family)
    {
      
      addr4 = (struct sockaddr_in *)ifap->ifa_addr;
      if(NULL != inet_ntop(ifap->ifa_addr->sa_family,(void *)&(addr4->sin_addr),buf,NI_MAXHOST))
      {
        if(size <=strlen(buf)) break;
        strcpy(address,buf);
        printf("address %s\n",address);
        freeifaddrs(ifap0);
        return 0;
      }
      else break;
    }
    else if(AF_INET6 == ifap->ifa_addr->sa_family)
    {
      addr6 = (struct sockaddr_in6*) ifap->ifa_addr;
      if(IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
      {
        continue;
      }
      if(IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr))
      {
        continue;
      }
      if(IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr))
      {
        continue;
      }
      if(IN6_IS_ADDR_UNSPECIFIED(&addr6->sin6_addr))
      {
        continue;
      }
      if(IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr))
      {
        continue;
      }
      if(NULL != inet_ntop(ifap->ifa_addr->sa_family,(void *)&(addr6->sin6_addr),buf,NI_MAXHOST))
      {
        if(size <= strlen(buf)) break;
        strcpy(address,buf);
        freeifaddrs(ifap0);
        return 0;
      }
      else break;
    }
  }
  freeifaddrs(ifap0);
  return -1;
}
int main(void)
{
  char ip_addr[16];
  char *ip ;
  ip= ip_addr;
  
  GetIP_v4_and_v6_linux(AF_INET,ip,16);

  printf("ip addrss %s\n", ip);
  }




阅读(25243) | 评论(0) | 转发(4) |
给主人留下些什么吧!~~