c++ - `ifreq` 结构中的 IPv6 地址问题

标签 c++ c sockets network-programming ipv6

我正在使用以下代码:

struct sockaddr_in6 *sin;
struct ifreq ifr;
sin = (struct sockaddr_in6 *)&ifr.ifr_addr;

ifr_addr 的类型为 struct sockaddr,为方便起见,在此处报告:

struct sockaddr {
        sa_family_t     sa_family;      /* address family, AF_xxx       */
        char            sa_data[14];    /* 14 bytes of protocol address */
};

鉴于只有 14 个字节可用,我该如何将 IPv6 地址(通过 sin->sin6_addr.s6_addr)放入 ifr_addr 字段中?

我哪里出错了?

TIA, 克里斯

最佳答案

幸运的是,struct ifreq 被声明为在结构末尾的 union 中包含地址:

struct ifreq
  {


    union
      {
 char ifrn_name[16];
      } ifr_ifrn;

    union
      {
 struct sockaddr ifru_addr;
 struct sockaddr ifru_dstaddr;
 struct sockaddr ifru_broadaddr;
 struct sockaddr ifru_netmask;
 struct sockaddr ifru_hwaddr;
 short int ifru_flags;
 int ifru_ivalue;
 int ifru_mtu;
 struct ifmap ifru_map;
 char ifru_slave[16];
 char ifru_newname[16];
 __caddr_t ifru_data;
      } ifr_ifru;
  };

请注意,上面是 gcc -E 的结果,因此所有预处理器内容都已扩展。另请注意,ifr_addr#defined 为ifr_ifru.ifru_addr

这意味着从技术上讲,您可以在结构末尾分配字节来保存地址。

在我看来,这是极其草率的。应声明 union 来保存 sockaddr_storage 类型的值以及其他所有内容。那么结构体大小将足够大以容纳任何地址。

如果您想声明自己可以轻松使用的大小合适的结构,只需执行以下操作:

union my_ifreq {
    struct ifreq sys_ifreq;
    struct {
        char name_pad[IFNAMSIZ];
        struct sockaddr_storage addr;
    } padding;
};

然后,您将拥有一个始终具有足够存储空间的结构,您可以将任何有效地址填充到 sys_ifreq.ifr_addr 中并使其正常工作。

关于c++ - `ifreq` 结构中的 IPv6 地址问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5516500/

相关文章:

c - SEH、访问冲突和堆栈保护页面

c - 代理需要非阻塞套接字吗?

sockets - Arduino Ethernet Shield 连接到套接字服务器

c++ - 在 Linux 上,为什么析构函数在 C++ 中的全局变量共享实例上运行两次?

c++ - OpenMP 与 C++11 线程

c - 链表,以错误的顺序存储?

html - 从查询字符串中提取整数

c++ - 非阻塞套接字多线程接收模型

c++ - 如何将 c++/opengl 中的对象移动到新位置并删除旧对象

c++ - 定义 < 比较器时按降序对对象排序?