К счастью, struct ifreq
объявляется содержащим адреса в объединении в конце структуры:
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
.
Это означает, что технически вы можете выделить байты за пределами структуры для хранения адреса.
На мой взгляд, это очень небрежно. Должно быть объявлено, что объединение содержит значение типа sockaddr_storage
вместе со всем остальным. Тогда размер структуры будет достаточно большим, чтобы вместить любой адрес.
Если вы хотите объявить свою собственную структуру правильного размера, которую вы можете использовать довольно легко, просто сделайте это:
union my_ifreq {
struct ifreq sys_ifreq;
struct {
char name_pad[IFNAMSIZ];
struct sockaddr_storage addr;
} padding;
};
Тогда у вас будет структура, в которой всегда будет достаточно памяти, чтобы вы могли вставить любой действительный адрес в sys_ifreq.ifr_addr
и заставить его работать.