我正在使用以下代码:
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
被#define
d 为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/