|
|

楼主 |
发表于 2006-1-10 23:11:03
|
显示全部楼层
查了一下ifconfig的源码,终于搞定了
修改后的文件:
[PHP]/* file: proc_iface.c */
// Obtain all IPs of local machine
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <net/if.h>
#include <netdb.h>
#include <sys/ioctl.h>
int
main()
{
struct if_nameindex * ifni, *p;
int fd, numreqs = 30, n, err = -1;
struct ifconf ifc;
struct ifreq *ifr;
if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0){
perror ("socket");
exit (1);
}
ifc.ifc_buf = NULL;
for (;;) {
ifc.ifc_len = sizeof (struct ifreq) * numreqs;
ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len);
if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
perror ("SIOCGIFCONF");
goto out;
}
if (ifc.ifc_len == sizeof (struct ifreq) *numreqs) {
/* assume it overflowed and try again */
numreqs += 10;
continue;
}
break;
}
close (fd);
uint32_t ip;
int i;
char ip_str[INET_ADDRSTRLEN];
ifr = ifc.ifc_req;
for (i = 0, n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
if (getifaddr (AF_INET, ++i, ifr->ifr_name, &ip) == -1){
perror ("getifaddr failed");
exit (2);
}
printf ("Index: %d,\tInterface: %s,\tIP: %s\n", i,
ifr->ifr_name, inet_ntop (AF_INET, &ip, ip_str, sizeof (ip_str)));
ifr++;
}
out:
free(ifc.ifc_buf);
return 0;
}[/PHP]
同时,getip.c也要改一下,要注释掉tatic int __getifaddr_ipv4()中的开始的if语句,否则eth0:1等就显示不出来了,还是if_indextoname()的问题
[PHP]/* file: getip.c */
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
inline static int __getifaddr_ipv4(int ifindex, const char *ifname,
struct in_addr *ifaddr)
{
struct ifreq ifreq;
int sockfd;
int ret = -1;
char ifn[IFNAMSIZ];
/*
if (ifindex > 0)
{
if (!(ifname = if_indextoname(ifindex, ifn)))
{
errno = ENXIO;
return -1;
}
}
*/
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
{
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
if ((ret = ioctl(sockfd, SIOCGIFADDR, &ifreq)) >= 0)
*ifaddr = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
close(sockfd);
}
return ret;
}
#ifdef IPV6
#define PROC_IFINET6_PATH "/proc/net/if_inet6"
inline static int __getifaddr_ipv6(unsigned int ifindex, const char *ifname,
struct in6_addr *ifaddr)
{
FILE *fp = fopen(PROC_IFINET6_PATH, "r");
char addrstr[INET6_ADDRSTRLEN];
char seg[8][5];
int index, plen, scope, flags;
char ifn[IFNAMSIZ];
int ret = -1;
if (fp)
{
while (fscanf(fp, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %s\n"
seg[0], seg[1], seg[2], seg[3], seg[4], seg[5], seg[6],
seg[7], &index, &plen, &scope, &flags, ifn) != EOF)
{
if (ifindex == index || ifindex == 0 && strcmp(ifn, ifname) == 0)
{
sprintf(addrstr, "%s:%s:%s:%s:%s:%s:%s:%s", seg[0], seg[1],
seg[2], seg[3], seg[4], seg[5], seg[6], seg[7]);
ret = inet_pton(AF_INET6, addrstr, ifaddr);
goto out;
}
}
errno = ENXIO;
out:
fclose(fp);
}
return ret;
}
#endif
int getifaddr(int family, unsigned int ifindex, const char *ifname,
void *ifaddr)
{
switch (family)
{
case AF_INET:
return __getifaddr_ipv4(ifindex, ifname, (struct in_addr *)ifaddr);
#ifdef IPV6
case AF_INET6:
return __getifaddr_ipv6(ifindex, ifname, (struct in6_addr *)ifaddr);
#endif
default:
errno = EAFNOSUPPORT;
return -1;
}
}[/PHP]
这样就可以顺利看到所有的ip了  |
|