我需要使用 C 语言显示本地计算机上的所有 IP 地址。如何才能做到这一点?
问问题
38495 次
8 回答
13
#include <stdio.h>
#include <stropts.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/netdevice.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
int print_addresses(const int domain)
{
int s;
struct ifconf ifconf;
struct ifreq ifr[50];
int ifs;
int i;
s = socket(domain, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
return 0;
}
ifconf.ifc_buf = (char *) ifr;
ifconf.ifc_len = sizeof ifr;
if (ioctl(s, SIOCGIFCONF, &ifconf) == -1) {
perror("ioctl");
return 0;
}
ifs = ifconf.ifc_len / sizeof(ifr[0]);
printf("interfaces = %d:\n", ifs);
for (i = 0; i < ifs; i++) {
char ip[INET_ADDRSTRLEN];
struct sockaddr_in *s_in = (struct sockaddr_in *) &ifr[i].ifr_addr;
if (!inet_ntop(domain, &s_in->sin_addr, ip, sizeof(ip))) {
perror("inet_ntop");
return 0;
}
printf("%s - %s\n", ifr[i].ifr_name, ip);
}
close(s);
return 1;
}
int main(int argc, char *argv[])
{
int domains[] = { AF_INET, AF_INET6 };
int i;
for (i = 0; i < sizeof(domains) / sizeof(domains[0]); i++)
if (!print_addresses(domains[i]))
return 1;
return 0;
}
于 2010-01-07T16:43:35.840 回答
10
您的问题可能不准确,但我不确定为什么每个人都在破坏您的排骨。
我想你是在问基础知识,在这种情况下你可能想要的是getifaddrs。手册页有一个小示例程序。
您还可以使用带有 ioctl() 的 SIOCGIFCONF 选项获得类似的信息。这里和网络上有一些示例代码。
如果您搜索这些和类似的术语,您会发现这个问题以前曾以各种形式提出过。你必须挖掘一下。
另请注意,如果您在 NAT 之后,这些不会为您提供网络的面向公众的 IP。
于 2010-01-07T16:46:15.227 回答
8
在 C 中实现它的另一种方法。不过我不得不说....有很多方法可以从 shell 中做到这一点,有什么意义呢?
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <errno.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
void show_address_info( struct ifaddrs *ifa ){
struct sockaddr_in *s4;
struct sockaddr_in6 *s6;
/* ipv6 addresses have to fit in this buffer */
char buf[64];
if (AF_INET == ifa->ifa_addr->sa_family){
s4 = (struct sockaddr_in *)(ifa->ifa_addr);
if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf))){
printf("%s: inet_ntop failed!\n", ifa->ifa_name);
} else {
printf("IPv4 addr %s: %s\n", ifa->ifa_name, buf);
}
}
else if (AF_INET6 == ifa->ifa_addr->sa_family) {
s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
if (NULL == inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s6->sin6_addr), buf, sizeof(buf))) {
printf("%s: inet_ntop failed!\n", ifa->ifa_name);
} else {
printf("IPv6 addr %s: %s\n", ifa->ifa_name, buf);
}
}
}
int main(int argc, char **argv){
struct ifaddrs *myaddrs, *ifa;
int status;
status = getifaddrs(&myaddrs);
if (status != 0){
perror("getifaddrs failed!");
exit(1);
}
for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next){
if (NULL == ifa->ifa_addr){
continue;
}
if ((ifa->ifa_flags & IFF_UP) == 0) {
continue;
}
show_address_info(ifa);
}
freeifaddrs(myaddrs);
return 0;
}
于 2010-01-07T18:31:08.353 回答
4
你干脆作弊看看源头/sbin/ifconfig/
怎么样?站在其他巨人的肩膀上没什么错……
于 2010-01-07T16:04:35.107 回答
3
还没有一个完整的解决方案,但看看/proc/net
!
dev
按名称列出可用的接口设备,route
列出一些路线,如ipv6_route
,arp
列出实际路由表中的设备(不包括本地主机)。
不像其他解决方案那样高科技,但可以通过简单的文件读取来完成。不过,特定于 Linux。
于 2010-01-07T16:00:43.523 回答
2
您需要 POSIX 函数getaddrinfo()
- 它返回所有 IP 地址的链接列表。
有关man getaddrinfo
详细信息和示例,请参阅。
于 2010-01-07T16:34:56.480 回答
-2
$ sudo ifconfig | grep 'inet 地址' | 剪切-d':' -f2 | 剪切-d''-f1 213.xx.xxx.xx 192.168.xx.x 127.0.0.1
你可以把它放进popen():
/* not tested */
ph = popen("sudo ifconfig | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1", "r");
while (fgets(buf, sizeof buf, ph)) {
/* ip address, in nul-terminated string format, is in `buf` */
}
pclose(ph);
于 2010-01-07T16:06:02.670 回答
-3
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
/*
* Who sez?
* http://blog.stackoverflow.com/2010/01/stack-overflow-where-we-hate-fun/
*/
int main(int argc, char *argv[])
{
int status;
const char * const cmd = /* die from END is too chatty */
"/sbin/ifconfig -a | \
perl -lne \
'print $1 if /inet6? addr:\\s*(\\S+)/; \
END { $. > 0 or \
warn(\"no output from ifconfig\\n\"), \
exit 1; }'";
status = system(cmd);
if (status < 0) {
perror("system");
return 1;
}
else if (status != 0) {
const char *extra;
status = WEXITSTATUS(status);
extra = status == 127 ? " (is /bin/sh ok?)" : "";
fprintf(stderr, "%s: command failed with status %d%s\n",
argv[0], status, extra);
}
return 0;
}
于 2010-01-07T16:02:02.180 回答