如何在 POSIX C 中枚举连接到一台机器的所有 IP 地址?

2023-11-24

背景:

我正在编写一个建立传出 TCP/IP 连接的守护程序。它将在具有多个(非环回)IP 地址的计算机上运行。我希望用户能够在守护程序的配置文件中指定用于传出连接的 IP 地址,或者*使用全部。

这些地址将轮流使用,每个连接都从最近最少使用的 IP 地址发出。这种行为很重要,因为*作为“all”的替代,因此在多台计算机上运行的守护程序可以指向文件共享上的同一个配置文件,并且每个守护程序都使用自己的一组 IP 地址。

Problem:

如何获取计算机可以进行传出(即到任何其他计算机)连接的所有 IP 地址的列表?给定所有 IP 地址的列表,我如何过滤掉环回地址?

我使用 C,如果可能的话,我只想使用 POSIX,但守护进程可能只在 Linux 机器上运行,所以我接受以 Linux 为中心的答案。

每个 IP 地址将在一个(可能是虚拟的)网络设备上可用,反之亦然,因此一种枚举网络设备并获取关联 IP 地址的方法也足够了,尽管我对此并不满意。 (附带问题:是否有可能将多个 IP 地址与单个设备相关联?多个设备下的同一个 IP 怎么样?并不重要。)

解决方案不足:

  • gethostname()/gethostbyname() (as 这个问题)。使用该方法,我只能返回 127.0.0.1(或 Debian 中的 .1.1)。我怀疑这是因为机器的主机名位于hosts文件,就这样gethostbyname()检查。 (我相信这就是为什么在 Debian 中我总是得到 127.0.1.1:Debian 默认将 localhost 添加为 127.0.0.1,将机器的主机名添加为 127.0.1.1hosts文件,对吧?)我想要一个忽略的解决方案hosts并给了我实际存在的一切。
  • 我再也没有运气了getaddrinfo() than gethostname()/gethostbyname()。它似乎受到同样的问题的束缚。我测试了这个传递机器的主机名和NULL服务(端口)进入其中;文档说通过NULL主机名和NULL服务是非法的,这是有测试支持的。不知道如何向它询问机器上的所有内容,但我愿意接受这方面的建议。
  • EDIT: 这个答案显示如何从设备名称获取 IP 地址,但不显示如何枚举设备名称。有任何想法吗?

最终编辑:我已经接受卡斯基的回答感谢他为我指明了如何完成这件事的方向。我已经发布了我的自己的答案列出了具体如何执行此操作的源代码,以防其他人需要它。


这是我使用的概念验证代码卡斯基接受的答案,为了后代:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.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>


static const char * flags(int sd, const char * name)
{
    static char buf[1024];

    static struct ifreq ifreq;
    strcpy(ifreq.ifr_name, name);

    int r = ioctl(sd, SIOCGIFFLAGS, (char *)&ifreq);
    assert(r == 0);

    int l = 0;
#define FLAG(b) if(ifreq.ifr_flags & b) l += snprintf(buf + l, sizeof(buf) - l, #b " ")
    FLAG(IFF_UP);
    FLAG(IFF_BROADCAST);
    FLAG(IFF_DEBUG);
    FLAG(IFF_LOOPBACK);
    FLAG(IFF_POINTOPOINT);
    FLAG(IFF_RUNNING);
    FLAG(IFF_NOARP);
    FLAG(IFF_PROMISC);
    FLAG(IFF_NOTRAILERS);
    FLAG(IFF_ALLMULTI);
    FLAG(IFF_MASTER);
    FLAG(IFF_SLAVE);
    FLAG(IFF_MULTICAST);
    FLAG(IFF_PORTSEL);
    FLAG(IFF_AUTOMEDIA);
    FLAG(IFF_DYNAMIC);
#undef FLAG

    return buf;
}

int main(void)
{
    static struct ifreq ifreqs[32];
    struct ifconf ifconf;
    memset(&ifconf, 0, sizeof(ifconf));
    ifconf.ifc_req = ifreqs;
    ifconf.ifc_len = sizeof(ifreqs);

    int sd = socket(PF_INET, SOCK_STREAM, 0);
    assert(sd >= 0);

    int r = ioctl(sd, SIOCGIFCONF, (char *)&ifconf);
    assert(r == 0);

    for(int i = 0; i < ifconf.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));
        printf(" flags: %s\n", flags(sd, ifreqs[i].ifr_name));
    }

    close(sd);

    return 0;
}

奇迹般有效!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 POSIX C 中枚举连接到一台机器的所有 IP 地址? 的相关文章

  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • 如何让 Swagger 插件在自托管服务堆栈中工作

    我已经用 github 上提供的示例重新提出了这个问题 并为任何想要自己运行代码的人提供了一个下拉框下载链接 Swagger 无法在自托管 ServiceStack 服务上工作 https stackoverflow com questio
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 按 Esc 按键关闭 Ajax Modal 弹出窗口

    我已经使用 Ajax 显示了一个面板弹出窗口 我要做的是当用户按 Esc 键时关闭该窗口 这可能吗 如果有人知道这一点或以前做过这一点 请帮助我 Thanks 通过以下链接 您可以通过按退出按钮轻松关闭窗口 http www codepro
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没
  • 当我使用 OpenSSL1.1.0g 根据固定的 p 和 g 值创建 Diffie Hellman 密钥协议密钥时,应该执行哪些检查?

    您好 我尝试通过这段代码使用修复 p 和 g 参数来制作 Diffie Hellman Keysanswer https stackoverflow com a 54538811 4706711 include

随机推荐

  • 在节目中跳入 Python 交互式会话?

    嘿 我想知道 我正在将 pydev 与 eclipse 一起使用 我真的很喜欢强大的调试功能 但我想知道 是否可以在eclipse中设置断点并在执行过程中跳转到交互式python解释器 我认为这会非常方便 edit 我想强调 我的目标不是跳
  • Symfony 2 注销(UserInterface::eraseCredentials)

    我想eraseCredentials是用来注销的吗 如果是这样 我如何清除教义实体的会话 No eraseCredentials 用于在持久化令牌之前擦除敏感数据 无论是序列化还是数据库 要以编程方式注销用户 您可以使用以下命令 this
  • JavaMail检查邮件内容 gmail IMAP

    我正在尝试阅读我的消息 我可以让它打印标题 但发件人和内容显示得很有趣 这是我用来显示消息的代码 int j message length 1 for int i j i gt 0 i System out println Message
  • 有什么方法可以知道流星订阅何时“有效”?

    如果我改变一个Sessionvar 并通过以下方式触发重新订阅autosubscribe 是否有任何回调机制可以等待 最新 数据从服务器上下来 1 如果你看一下这个要点您将看到一些代码 这些代码随着订阅的变化而记录集合的内容 输出的相关部分
  • 计算字符串在字符串中出现的次数[重复]

    这个问题在这里已经有答案了 我只是有一个看起来像这样的字符串 7 真 NA 假 67 假 NA 假 5 假 NA 假 5 假 NA 假 我想做的就是计算字符串出现了多少次 true 出现在该字符串中 我感觉答案是这样的String Coun
  • Python - 如何使用模块的别名来导入其子模块?

    我的模块名称很长 我想避免在文档中多次输入它 我可以简单地做import long ass module name as lamn并这样称呼它 但是 该模块有许多我也希望导入和使用的子模块 在这种情况下我将无法写import lamn su
  • max() 函数如何处理 python 中的字符串列表?

    我有一个清单 list1 123 xyz zara abc print Max value element max list1 它给 Max value element zara 另请解释它如何对字符串列表和数字列表进行比较 This is
  • 使用 ExcelDataReader 和 Epplus 访问受保护的 Excel 文件

    标题几乎说明了一切 寻找一种使用 ExcelDataReader 和 Epplus 访问受密码保护的 Excel 文件的方法 找不到正确的答案 如果使用 ExcelDataReader 我的代码如下所示 excelStream File O
  • 如何在 SOLR 中索引文档?

    我在 Ubuntu 10 04 上运行 Solr 1 4 通过 apt get solr tomcat 安装 它似乎工作正常 不过 我很难找到有关如何索引文档的任何连贯信息 我是 SOLR 新手 所以请耐心等待 我有一个已安装的 Windo
  • 天蓝色资源管理器服务总线提供商?

    有 ServiceBus 提供商这样的东西吗 作为我的应用程序的一部分 我想包含 SB 命名空间 主题和订阅 您是否期望使用 ARM 部署网站 并使用服务接口来编写其他支持功能的脚本 现在有一个服务总线提供商 样本模板 apiVersion
  • 如果“&String”没有实现“Into”,为什么这些实现会发生冲突?

    我问了一个相关问题关于为什么没有实施From lt String gt for String 我现在想创建自己的特质 如下所示 derive Debug struct MyStruct String impl MyStruct fn new
  • 如何知道谷歌帐户是否在谷歌应用程序域下?

    我正在开发一个应用程序 允许用户将他们的云端硬盘文件分享给朋友 但是Google App帐户存在问题 例如 email protected 其中的文件不能与不在该域下的人共享 尽管共享策略可以由管理员更改somedomain com 但我不
  • 设置 Java 编译器合规级别

    我需要在命令行上编译一个Java程序 并且我试图将编译器级别设置为较低的级别 1 6 我尝试过这样但没有成功 javac 1 6 Hello java Use source and target选项 javac target 1 6 sou
  • 如何从对象数组中删除所有重复项?

    我有一个包含对象数组的对象 obj obj arr new Array obj arr push place here name stuff obj arr push place there name morestuff obj arr p
  • 无法在 Rider 中使用 .NET Standard 2.0 Lib 加载 Xamarin Forms 项目

    TL DR Rider 是否支持具有 NET Standard 库 2 0 的 Xamarin Forms 项目 我使用空白表单应用程序多平台向导在 Visual Studio 2017 3 Windows 中创建了一个小型 Xamarin
  • 将数字转换为日期[重复]

    这个问题在这里已经有答案了 我有一张表 其中一列的日期格式为20130109或无空格的 YearMonday 我正在尝试绘制这些点的图表 由于这种奇怪的间距 最终在图表中出现很大的间隙 因此想要将这些数字转换为日期 我一直在尝试使用as D
  • 从 nlme 摘要中提取随机效应

    我可以使用以下命令从 nlme 摘要中提取固定效果summary fm1 却苦于如何获得Random effects 部分 fm1 lt lme distance age Orthodont random age Subject summa
  • 如何在布局中使用自己的视图?

    我创建了一个这样的类 public final class MyView extends View public MyView Context context AttributeSet attrs super context attrs 然
  • 蟒蛇 |异步IO |类型错误:需要一个协程

    我正在尝试使用 asyncio 进行 python 协程编程 这是我的代码 import asyncio async def coro function return 2 2 async def get return await coro
  • 如何在 POSIX C 中枚举连接到一台机器的所有 IP 地址?

    背景 我正在编写一个建立传出 TCP IP 连接的守护程序 它将在具有多个 非环回 IP 地址的计算机上运行 我希望用户能够在守护程序的配置文件中指定用于传出连接的 IP 地址 或者 使用全部 这些地址将轮流使用 每个连接都从最近最少使用的