获取linux内核所有ip(C语言)
经常遇到获取接口ip。记录一下,方便后续使用。
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef unsigned int sf_uint32_t;
typedef unsigned int in_addr_t;
static inline char* print_ip1(sf_uint32_t ip)
{
unsigned char* ip_tmp = (unsigned char*) &ip;
static char buff[20];
memset(buff ,0 ,sizeof(buff));
snprintf(buff, sizeof(buff), "%d.%d.%d.%d", ip_tmp[0], ip_tmp[1], ip_tmp[2],
ip_tmp[3]);
return buff;
}
in_addr_t
get_myaddr(void)
{
int sd, i, lastlen = 0;
struct ifconf ifc;
struct ifreq *ifrp = NULL;
in_addr_t addr;
char *buf = NULL;
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
return 0;
}
/*
* Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF on
* some platforms; see W. R. Stevens, ``Unix Network Programming Volume
* I‘‘, p.435.
*/
for (i = 8;; i += 8) {
buf = (char *) calloc(i, sizeof(struct ifreq));
if (buf == NULL) {
close(sd);
return 0;
}
ifc.ifc_len = i * sizeof(struct ifreq);
ifc.ifc_buf = (caddr_t) buf;
if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
if (errno != EINVAL || lastlen != 0) {
/*
* Something has gone genuinely wrong.
*/
free(buf);
close(sd);
return 0;
}
/*
* Otherwise, it could just be that the buffer is too small.
*/
} else {
if (ifc.ifc_len == lastlen) {
/*
* The length is the same as the last time; we‘re done.
*/
break;
}
lastlen = ifc.ifc_len;
}
free(buf);
}
for (ifrp = ifc.ifc_req;
(char *)ifrp < (char *)ifc.ifc_req + ifc.ifc_len;
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
ifrp = (struct ifreq *)(((char *) ifrp) +
sizeof(ifrp->ifr_name) +
ifrp->ifr_addr.sa_len)
#else
ifrp++
#endif
) {
if (ifrp->ifr_addr.sa_family != AF_INET) {
continue;
}
addr = ((struct sockaddr_in *) &(ifrp->ifr_addr))->sin_addr.s_addr;
if (ioctl(sd, SIOCGIFFLAGS, (char *) ifrp) < 0) {
continue;
}
if ((ifrp->ifr_flags & IFF_UP)
#ifdef IFF_RUNNING
&& (ifrp->ifr_flags & IFF_RUNNING)
#endif /* IFF_RUNNING */
/*&& !(ifrp->ifr_flags & IFF_LOOPBACK)
&& addr != LOOPBACK*/) {
/*
* I *really* don‘t understand why this is necessary. Perhaps for
* some broken platform? Leave it for now. JBPN
*/
#ifdef SYS_IOCTL_H_HAS_SIOCGIFADDR
if (ioctl(sd, SIOCGIFADDR, (char *) ifrp) < 0) {
continue;
}
addr =
((struct sockaddr_in *) &(ifrp->ifr_addr))->sin_addr.
s_addr;
#endif
printf("current ip : %s\n",print_ip1(addr));
}
}
free(buf);
close(sd);
return 0;
}
int main()
{
get_myaddr();
}
原文地址:http://blog.51cto.com/qiaopeng688/2166008
时间: 2024-10-10 04:29:04