c - Wget 中的 --bind-address 将覆盖路由数据包的接口(interface)的 IP 地址

标签 c sockets networking network-programming wget

我正在尝试模拟在计算机(笔记本电脑/PC)上运行的网络客户端(最好是 C 代码)。启动时,它通过 DHCP 从计算机所属网络的路由器协商一个新的 IP 地址。获取 IP 地址后,假设根据配置文件发出 http 请求(下载/上传)。

该设置主要是为了对路由器进行压力测试而生成多个此类客户端。

我遇到了https://github.com/saravana815/dhtest它负责 DHCP 协商的部分。它创建一个随机 MAC 地址并从路由器获取相同的 IP。

下一步是扩展客户端以进行 http 调用。我开始研究https://github.com/jay/wget & 标志 --bind-address 引起了我的注意

 --bind-address=ADDRESS    bind to ADDRESS (hostname or IP) on local host.\n"),

我的理解是 - 该标志的目的是在机器上选择适当的接口(interface)。在仔细查看源代码时,我发现下面的代码片段被踢入标志

static bool
resolve_bind_address (struct sockaddr *sa)
{
  struct address_list *al;

  /* Make sure this is called only once.  opt.bind_address doesn't
     change during a Wget run.  */
  static bool called, should_bind;
  static ip_address ip;
  if (called)
    {
      if (should_bind)
        sockaddr_set_data (sa, &ip, 0);
      return should_bind;
    }
  called = true;

  al = lookup_host (opt.bind_address, LH_BIND | LH_SILENT);
  if (!al)
    {
      /* #### We should be able to print the error message here. */
      logprintf (LOG_NOTQUIET,
                 _("%s: unable to resolve bind address %s; disabling bind.\n"),
                 exec_name, quote (opt.bind_address));
      should_bind = false;
      return false;
    }

  /* Pick the first address in the list and use it as bind address.
     Perhaps we should try multiple addresses in succession, but I
     don't think that's necessary in practice.  */
  ip = *address_list_address_at (al, 0);
  address_list_release (al);

  sockaddr_set_data (sa, &ip, 0);
  should_bind = true;
  return true;
}

函数sockaddr_set_data (sa, &ip, 0);如下所示

static void
sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
{
  switch (ip->family)
    {
    case AF_INET:
      {
        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
        xzero (*sin);
        sin->sin_family = AF_INET;
        sin->sin_port = htons (port);
        sin->sin_addr = ip->data.d4;
        break;
      }
#ifdef ENABLE_IPV6
    case AF_INET6:
      {
        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
        xzero (*sin6);
        sin6->sin6_family = AF_INET6;
        sin6->sin6_port = htons (port);
        sin6->sin6_addr = ip->data.d6;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
        sin6->sin6_scope_id = ip->ipv6_scope;
#endif
        break;
      }
#endif /* ENABLE_IPV6 */
    default:
      abort ();
    }
}

我不完全是网络/套接字专家。我想确认的是 - 向 Wget 发送的数据包显式添加 IP 地址是否会覆盖操作系统在这些数据包离开特定接口(interface)时为这些数据包设置的 IP 地址?

这个问题的答案将帮助我决定是否应该为我想要模拟的每个网络客户端创建一个单独的逻辑接口(interface),或者我是否可以完全取消它(我更喜欢后者)。

最佳答案

数据包将通过套接字绑定(bind)的接口(interface)进行路由。 IP 地址可以是虚拟地址,也可以是以太网接口(interface)的主 IP 地址。 IP决定了使用哪个物理接口(interface)进行通信。

您可以在给定的物理接口(interface)上创建多个虚拟 IP 地址,并生成每个绑定(bind)到不同 IP 的客户端。这呈现了路由器(模拟)的不同来源的情况,尽管所有来源都将使用相同的物理接口(interface)。

关于c - Wget 中的 --bind-address 将覆盖路由数据包的接口(interface)的 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40157381/

相关文章:

c - C 中的随机数生成器

c - 向指针添加变量不同于向常量添加

sockets - 检查端口是否在 ANT 中打开

java - Android:AndroidHttpClient - 如何设置超时?

node.js - docker桥接本地主机端口

c - 如何使用 FILE* 参数对 C 函数进行单元测试

c - 在 OSX 10.12 上使用 mmap() 时出现 'cannot allocate memory' 错误

java - 向多个客户端广播消息时如何排除或跳过发送者(多线程java套接字)

php - 将文件上传并发布到 PHP 页面

linux - 了解 netfilter REDIRECT 目标