【问题标题】:Get source address of UDP datagram sent from INADDR_ANY获取从 INADDR_ANY 发送的 UDP 数据报的源地址
【发布时间】:2016-08-18 15:09:44
【问题描述】:

当我从绑定到 INADDR_ANY 的 UDP 套接字发送数据包时,如何找出操作系统选择使用的 IP 地址?

int s = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in src;
src.sin_family = AF_INET;
src.sin_port = 12345;
src.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr*)&src, sizeof(src));

char msg[] = "Hello";
sockaddr_in dest;
dest.sin_family = AF_INET;
dest.sin_port = 12345;
dest.sin_addr.s_addr = (in_addr_t)0xdeadbeef;
sendto(s, msg, sizeof(msg), 0, (struct sockaddr*)&dest, sizeof(dest));

使用什么源地址发送数据包?理想情况下会有一个sendtofrom() 函数,如recvfrom(),它返回内核选择的地址。

在我的应用程序中,我绑定到 INADDR_ANY 并向 STUN 服务器发送一个数据包(我不想使用路由表来选择源地址:内核的选择很好)。但是,要执行 ICE,我需要获取“服务器自反地址”的“基地址”,即。我需要知道使用哪个本地地址发送 STUN 请求。我会接受 Windows 或 POSIX 特定的答案,建议从路由表中查找地址。

【问题讨论】:

标签: sockets winapi routing udp posix


【解决方案1】:

很遗憾,无法查询使用了哪个源 IP 地址。例如,在 Windows 上,您必须编写一个低级 NDIS 驱动程序来获取该信息。但是,如果您使用WSASendMsg()/sendmsg() 而不是sendto(),则可以传入in_pktinfo 结构来指定要用于传出数据包的源IP 地址。

【讨论】:

  • 这很有帮助。我也一直在阅读IP_PKTINFO/IP_RECVDSTADDR (stackoverflow.com/questions/3062205/…),它可以让您找出传入数据包的目标地址。很遗憾,我无法以简单的方式获得一点信息。我想我会使用主机默认路由的接口发送数据包。
【解决方案2】:

我最近遇到了同样的问题。

我解决这个问题的方法是

  1. 从收到的数据包中获取接口名称
  2. 将套接字绑定到特定接口
  3. 解除绑定套接字

例子:

  struct ifreq ifr;
  ...
  recvmsg(fd, &msg...)
  ...
  //
  if (msg.msg_controllen >= sizeof(struct cmsghdr))
    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
      if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
      {
        iface_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
      }
  if_indextoname(iface_index , ifr.ifr_name);
  mret=setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));

  sendmsg(...);

  memset(&ifr, 0, sizeof(ifr));
  snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "");
  mret=setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多