免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1131 | 回复: 0
打印 上一主题 下一主题

Linux/Unix下查看本机所有网络接口的C程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-30 14:10 |只看该作者 |倒序浏览

               
Linux/Unix下查看本机所有网络接口的C程序
代码基本上是摘自"Unix
网络编程"
头文件:
#ifndef __NET_INF_H
#define
__NET_INF_H
#include net/if.h>
#include stdio.h>
#include errno.h>
#include unistd.h>
#include netinet/in.h>
#include sys/ioctl.h>
#include stdlib.h>
#include string.h>
#include sys/types.h>
#include sys/socket.h>
#include arpa/inet.h>
#define
IFI_NAME 16
#define
IFI_HADDR 8
typedef struct ifi_info
{
  char ifi_name[IFI_NAME];
  u_char ifi_haddr[IFI_HADDR];
  u_short ifi_hlen;
  short ifi_flags;
  short ifi_myflags;
  struct sockaddr *ifi_addr;
  struct sockaddr *ifi_brdaddr;
  struct sockaddr *ifi_dstaddr;
  struct ifi_info *ifi_next;
}ifi_info;
#define
IFI_ALIAS 1
struct ifi_info *get_ifi_info(int, int);
void free_ifi_info(struct ifi_info *);
#endif
主程序:
#include "net_if.h"
ifi_info *get_ifi_info(int family, int doaliases)
{
  ifi_info *ifi, *ifihead, **ifipnext;
  int sockfd, len, lastlen, flags,
myflags;
  char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
  struct ifconf ifc;
  struct ifreq *ifr, ifrcopy;
  struct sockaddr_in *sinptr;
  if ((sockfd=socket(AF_INET, SOCK_DGRAM, 0))0)
  {
    printf("socket error.\n");
    exit(1);
  }
  lastlen = 0;
  len = 10*sizeof(struct ifreq);
  while (1)
  {
    buf = (char*)malloc(len);
    ifc.ifc_len = len;
    ifc.ifc_buf = buf;
    if (ioctl(sockfd, SIOCGIFCONF, &ifc)0)
    {
      if (errno!=EINVAL||lastlen!=0)
      {
        printf("ioctl
error.\n");
      }
    }
    else
    {
      if (ifc.ifc_len
==
lastlen)
        break;
      lastlen = ifc.ifc_len;
    }
    len += 10*sizeof(struct ifreq);
    free(buf);
  }
  ifihead = NULL;
  ifipnext = &ifihead;
  lastname[0] = 0;
  for (ptr = buf; ptrbuf+ifc.ifc_len;)
  {
    ifr = (struct ifreq*)ptr;
#ifdef
HAVE_SOCKADDR_SA_LEN
    len = sizeof(struct sockaddr)>ifr->ifr_addr.sa_len?sizeof(struct sockaddr):ifr->ifr_addr.sa_len;
#else
    switch (ifr->ifr_addr.sa_family)
    {
#ifdef IPV6
    case: AF_INET6:
      LEN = sizeof(struct sockaddr_in6);
      break;
#endif
    case AF_INET:
    default:
      len = sizeof(struct sockaddr);
      break;
    }
#endif
    ptr += sizeof(ifr->ifr_name) + len;
    if (ifr->ifr_addr.sa_family !=
family)
      continue;
    myflags = 0;
    if ((cptr=strchr(ifr->ifr_name, ':'))!=NULL)
      *cptr = 0;
    if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ)==0)
    {
      if (doaliases == 0)
        continue;
      myflags =
IFI_ALIAS;
    }
    memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
    ifrcopy = *ifr;
    ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
    flags = ifrcopy.ifr_flags;
    if ((flags&IFF_UP)==0)
      continue;
    /*
    if ((flags&IFF_BROADCAST)==0)
      continue;
    */
    ifi = calloc(1, sizeof(struct ifi_info));
    *ifipnext = ifi;
    ifipnext = &ifi->ifi_next;
    ifi->ifi_flags = flags;
    ifi->ifi_myflags =
myflags;
    memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
    ifi->ifi_name[IFI_NAME-1] = '\0';
    switch (ifr->ifr_addr.sa_family)
    {
    case AF_INET:
      sinptr = (struct sockaddr_in *)&ifr->ifr_addr;
      if (ifi->ifi_addr == NULL)
      {
        ifi->ifi_addr
= calloc(1, sizeof(struct sockaddr_in));
        memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
#ifdef SIOCGIFBRDADDR
        if (flags & IFF_BROADCAST)
        {
          ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);
          sinptr = (struct sockaddr_in *)&ifrcopy.ifr_broadaddr;
          ifi->ifi_brdaddr = calloc(1, sizeof(struct sockaddr_in));
          memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));
        }
#endif
#ifdef SIOCGIFDSTADDR
        if (flags & IFF_POINTOPOINT)
        {
          ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
          sinptr = (struct sockaddr_in*)&ifrcopy.ifr_dstaddr;
          ifi->ifi_dstaddr = calloc(1, sizeof(struct sockaddr_in));
          memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));
        }
#endif
      }
      break;
    default:
      break;
    }
  }
  free(buf);
  return(ifihead);
}
void free_ifi_info(ifi_info *ifihead)
{
  ifi_info *ifi, *ifinext;
  for (ifi=ifihead; ifi!=NULL; ifi=ifinext)
  {
    if (ifi->ifi_addr!=NULL)
      free(ifi->ifi_addr);
    if (ifi->ifi_brdaddr!=NULL)
      free(ifi->ifi_brdaddr);
    if (ifi->ifi_dstaddr!=NULL)
      free(ifi->ifi_dstaddr);
    ifinext = ifi->ifi_next;
    free(ifi);
  }
  
}
char *sock_ntop(const struct sockaddr *sa, socklen_t salen)
{
  char portstr[7];
  static char str[128];
  switch (sa->sa_family)
  {
  case AF_INET:
    {
      struct sockaddr_in *sin = (struct sockaddr_in *)sa;
      if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))==NULL)
        return NULL;
      if (ntohs(sin->sin_port)!=0)
      {
        snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin->sin_port));
        strcat(str, portstr);
      }
      return str;
    }
    break;
  case AF_INET6:
    {
      struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
      if (inet_ntop(AF_INET6, &sin->sin6_addr, str, sizeof(str))==NULL)
        return NULL;
      if (ntohs(sin->sin6_port)!=0)
      {
        snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin->sin6_port));
        strcat(str, portstr);
      }
      return str;
    }
    break;
  default:
    return NULL;
    break;
  }
  
}
int main(int argc, char *argv[])
{
  ifi_info *ifi, *ifihead;
  struct sockaddr *sa;
  u_char *ptr;
  int i, family, doaliases;
  if (argc!=3)
  {
    printf("usage: prifinfo  ");
    exit(1);
  }
  if (strcmp(argv[1], "inet4") == 0)
    family = AF_INET;
#ifdef IPV6
  else if (strcmp(argv[1], "inet6") == 0)
    family =AF_INET6;
#endif
  else
  {
    printf("invalid ");
    exit(1);
  }
  doaliases = atoi(argv[2]);
  for(ifihead = ifi =
get_ifi_info(family,
doaliases);
      ifi!=NULL;ifi=ifi->ifi_next)
  {
    printf("%s:, ifi->ifi_name);
    if (ifi->ifi_flags&IFF_UP) printf("UP");
    if (ifi->ifi_flags&IFF_BROADCAST) printf("BCAST");
    if (ifi->ifi_flags&IFF_MULTICAST) printf("MCAST");
    if (ifi->ifi_flags&IFF_LOOPBACK) printf("LOOP");
    if (ifi->ifi_flags&IFF_POINTOPOINT) printf("P2P");
    printf(">\n");
    if ((i=ifi->ifi_hlen)>0)
    {
      ptr = ifi->ifi_haddr;
      do
      {
        printf("%s%x", (i==ifi->ifi_hlen)?" ":":", *ptr++);
      }while(--i>0);
      
      printf("\n");
    }
    if ((sa=ifi->ifi_addr)!=NULL)
      printf(" IP addr: %s\n",
             sock_ntop(sa, sizeof(*sa)));
    if ((sa=ifi->ifi_brdaddr)!=NULL)
      printf(" broadcast addr: %s\n",
             sock_ntop(sa, sizeof(*sa)));
    if ((sa=ifi->ifi_dstaddr)!=NULL)
      printf(" destnation addr: %s\n",
             sock_ntop(sa, sizeof(*sa)));
  }
  free_ifi_info(ifihead);
  exit(0);
}
               
                #ifndef __NET_INF_H
#define __NET_INF_H
#include net/if.h>
#include stdio.h>
#include errno.h>
#include unistd.h>
#include netinet/in.h>
#include sys/ioctl.h>
#include stdlib.h>
#include string.h>
#include sys/types.h>
#include sys/socket.h>
#include arpa/inet.h>
#define IFI_NAME 16
#define IFI_HADDR 8
typedef struct ifi_info
{
  char ifi_name[IFI_NAME];
  u_char ifi_haddr[IFI_HADDR];
  u_short ifi_hlen;
  short ifi_flags;
  short ifi_myflags;
  struct sockaddr *ifi_addr;
  struct sockaddr *ifi_brdaddr;
  struct sockaddr *ifi_dstaddr;
  struct ifi_info *ifi_next;
}ifi_info;
#define IFI_ALIAS 1
struct ifi_info *get_ifi_info(int, int);
void free_ifi_info(struct ifi_info *);
#endif


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94916/showart_1915216.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP