全部博文(73)
分类: LINUX
2009-04-30 14:11:24
ifconfig
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAC_LEN 6
#define name_len 16
typedef struct ifaddr_s
{
char
if_name[IFNAMSIZ]; //The
name of interface
short
if_flags; //device
flags: AFF_XXX
unsigned char if_haddr[MAC_LEN]; //MAC ADDRESS
struct sockaddr
*if_addr;
//ip address
struct sockaddr *if_broadaddr; //broadcast address
struct sockaddr *if_detaddr;
struct sockaddr *if_maskaddr;
struct ifaddr_s *next;
}ifaddr_t;
struct ifconf *
getMacConf()
{
struct ifconf *ifc;
int sockfd;
int len, last_len;
char *buf;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
ifc = (struct ifconf *)malloc(sizeof(struct ifconf));
len = 10 * sizeof(struct ifreq);
last_len = 0;
while(1){
buf = (char *)malloc(len);
ifc->ifc_len = len;
ifc->ifc_buf = buf;
if(ioctl(sockfd, SIOCGIFCONF, ifc) < 0)
{
if(errno != EINVAL || last_len != 0)
{
printf("ioctl error\n");
free(ifc);
free(buf);
return NULL;
}
}
else{
if(last_len == ifc->ifc_len)
break;
last_len = ifc->ifc_len;
}
len += 10 * sizeof(struct ifreq);
free(buf);
}
close(sockfd);
return ifc;
}
struct ifaddr_s *
get_ifaddr(struct ifconf *ifc)
{
char *ptr, *buf, *cptr;
ifaddr_t *ifa=NULL, *ifa_next;
struct ifreq *ifr;
char lastname[name_len];
int sockfd;
int flags;
int len;
struct sockaddr_in *sin_addr;
if(ifc == NULL)
{
printf("ifc is NULL\n");
return NULL;
}
lastname[0] = 0;
buf = ifc->ifc_buf;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
for(ptr = buf; ptr < buf + ifc->ifc_len;)
{
ifr = (struct ifreq *)ptr;
//ioctl(sockfd, SIOCGIFADDR, ifr);
#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_in);
break;
}
#endif
ptr += sizeof(ifr->ifr_name) + len;
//ignore IPV6
if(ifr->ifr_addr.sa_family != AF_INET)
continue;
if((cptr = strchr(ifr->ifr_name, ':')) != NULL)
*cptr = 0;
if(strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
{
continue;
}
strncpy(lastname, ifr->ifr_name, sizeof(lastname));
ioctl(sockfd, SIOCGIFFLAGS, ifr);
flags = ifr->ifr_flags;
if((flags&IFF_UP) == 0)
continue;
ifa_next = calloc(1, sizeof(ifaddr_t));
ifa_next->next = ifa;
ifa = ifa_next;
strncpy(ifa->if_name, ifr->ifr_name,
sizeof(ifa->if_name));
ifa->if_flags = flags;
ioctl(sockfd, SIOCGIFADDR, ifr);
switch(ifr->ifr_addr.sa_family)
{
case AF_INET:
sin_addr = (struct sockaddr_in
*)&ifr->ifr_addr;
if(ifa->if_addr != NULL)
break;
ifa->if_addr = calloc(1, sizeof(struct
sockaddr_in));
memcpy(ifa->if_addr, sin_addr, sizeof(struct
sockaddr));
#ifdef SIOCGIFBRDADDR
if(flags&IFF_BROADCAST)
{
ioctl(sockfd, SIOCGIFBRDADDR, ifr);
sin_addr = (struct sockaddr_in
*)&ifr->ifr_broadaddr;
ifa->if_broadaddr = calloc(1, sizeof(struct
sockaddr_in));
memcpy(ifa->if_broadaddr, sin_addr, sizeof(struct
sockaddr_in));
}
#endif
#ifdef SIOCGIFDSTADDR
if(flags&IFF_POINTOPOINT)
{
ioctl(sockfd, SIOCGIFDSTADDR, ifr);
sin_addr = (struct sockaddr_in
*)&ifr->ifr_dstaddr;
ifa->if_detaddr = calloc(1, sizeof(struct
sockaddr_in));
memcpy(ifa->if_detaddr, sin_addr, sizeof(struct
sockaddr_in));
}
#endif
#ifdef SIOCGIFHWADDR
if((flags&IFF_LOOPBACK) == 0)
{
ioctl(sockfd, SIOCGIFHWADDR, ifr);
memcpy(ifa->if_haddr, ifr->ifr_hwaddr.sa_data,
MAC_LEN);
}
#endif
#ifdef SIOCGIFNETMASK
if((flags&IFF_LOOPBACK) == 0)
{
ioctl(sockfd, SIOCGIFNETMASK, ifr);
sin_addr = (struct sockaddr_in
*)&ifr->ifr_netmask;
ifa->if_maskaddr = calloc(1, sizeof(struct
sockaddr_in));
memcpy(ifa->if_maskaddr, sin_addr, sizeof(struct
sockaddr_in));
}
#endif
}
}
close(sockfd);
return ifa;
}
阅读(26) 评论(0) 发表时间: