简体   繁体   English

如何在基于 Debian 的系统上以编程方式获取 IP 地址?

[英]How to get IP address programmatically on Debian based system?

I'm trying to retrieve the IP Address of the local machine in my program.我正在尝试在我的程序中检索本地计算机的IP Address The Operating System is Ubuntu 8.10 .操作系统是Ubuntu 8.10 I tried using gethostname() and gethostbyname() to retrieve the IP Address .我尝试使用gethostname()gethostbyname()来检索IP Address The answer I received is 127.0.1.1 .我收到的答案是127.0.1.1 I learned that it seems to be a Debian thing: The document linked here explained the idea.我了解到这似乎是Debian的事情: 此处链接的文档解释了这个想法。

The content of my /etc/hosts file is:我的/etc/hosts文件的内容是:

127.0.0.1 localhost 127.0.0.1 本地主机
127.0.1.1 mymachine 127.0.1.1 我的机器

In this case, is there any other way to programmatically (prefer C or C++) to get the IP Address without modifying the system file on the machine?在这种情况下,是否有任何其他方式可以在不修改机器上的系统文件的情况下以编程方式(首选 C 或 C++)获取 IP 地址?

Here's some quick and dirty code that demonstrates SIOCGIFCONF:这是一些演示 SIOCGIFCONF 的快速而肮脏的代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    int sock, i;
    struct ifreq ifreqs[20];
    struct ifconf ic;

    ic.ifc_len = sizeof ifreqs;
    ic.ifc_req = ifreqs;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        perror("socket");
        exit(1);
    }

    if (ioctl(sock, SIOCGIFCONF, &ic) < 0) {
        perror("SIOCGIFCONF");
        exit(1);
    }

    for (i = 0; i < ic.ifc_len/sizeof(struct ifreq); ++i)
        printf("%s: %s\n", ifreqs[i].ifr_name,
                inet_ntoa(((struct sockaddr_in*)&ifreqs[i].ifr_addr)->sin_addr));

    return 0;
}

I get the following output on my Linux machine.我在我的 Linux 机器上得到以下 output。

lo: 127.0.0.1
br0: 192.168.0.42
dummy1: 10.0.0.2

So, as per Ken's point:所以,根据肯的观点:

ip addr show scope global | grep inet | cut -d' ' -f6 | cut -d/ -f1

Shame that when the Debian gods made the "ip" command they didn't think to add a simple command to get just the ip address.遗憾的是,当 Debian 大神发出“ip”命令时,他们并没有想到添加一个简单的命令来获取 ip 地址。

See "netdevice", through man netdevice or on the web .通过man netdeviceweb参见“netdevice”。
SIOCGIFCONF can then be used to get an enumeration of all transport layer addresses.然后可以使用 SIOCGIFCONF 来获取所有传输层地址的枚举。

Edit (on manpages): man is a very useful command on Linux (or other UNIX-like systems as well).编辑(在手册页上): man在 Linux(或其他类似 UNIX 的系统)上是一个非常有用的命令。 It shows a brief description of most commands, library functions, programs, etc. Open a shell prompt and type man ls or man netdevice , and you'll see what I mean.它显示了大多数命令、库函数、程序等的简要说明。打开 shell 提示符并键入man lsman netdevice ,您就会明白我的意思了。

Edit (on general retrieving of IP): The easiest way, if you think the C way is too messy, is a simple shell script like (just from the top of my head):编辑(关于 IP 的一般检索):最简单的方法,如果您认为 C 方式太乱,是一个简单的 shell 脚本,例如(只是从我的头顶):
ifconfig|grep 'inet addr'|awk '{print $2}'|sed 's/addr://g'

Edit (on the Brain solution): What he does is using the if_nameindex() function for finding all network device names, and then the SIOCFIFCONF ioctl on each of these names for finding their IP.编辑(关于大脑解决方案):他所做的是使用if_nameindex() function 来查找所有网络设备名称,然后在每个名称上使用 SIOCFIFCONF ioctl 来查找它们的 IP。 As he says, it only lists one IP per device.正如他所说,它只列出了每个设备一个 IP。

Thanks all for the shares!谢谢大家的分享!

For a bash solution, this what I ended up going with:对于 bash 解决方案,这就是我最终的结果:

#!/bin/bash

/sbin/ifconfig|fgrep 'inet addr:'|fgrep -v '127'|cut -d: -f2|awk '{print $1}'|head -n1

The head ensures the primary ip is returned, as multi homed and/or logical interfaces will also be returned without the head.头确保返回主要的 ip,因为多宿主和/或逻辑接口也将在没有头的情况下返回。

So if the script was located at /sbin/get_primary_ip, you could do stuff like:因此,如果脚本位于 /sbin/get_primary_ip,您可以执行以下操作:

foo=$(get_primary_ip)

ifconfig is deprecated and old. ifconfig 已过时且已弃用。 iproute2 is the new stack, use the ip command: iproute2 是新堆栈,使用 ip 命令:

ip addr, and parse from there. ip 地址,然后从那里解析。

Take a look at the netdevice man page.查看netdevice手册页。 Call SIOCGIFCONF to obtain a list of all the interfaces and their addresses.调用 SIOCGIFCONF 以获取所有接口及其地址的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM