首页 > 解决方案 > 我看不懂inet/netinet/in.h 的宏

问题描述

我正在使用 C 中的软件驱动程序的 IPv6 迁移,我想了解IN6ADDR_ANY_INITIN6ADDR_LOOPBACK_INIT的以下宏。请帮忙:

/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#ifndef        _NETINET_IN_H
#define        _NETINET_IN_H        1
#include <features.h>
#include <bits/stdint-uintn.h>
#include <sys/socket.h>
#include <bits/types.h>

.
.
.

#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }

标签: cmacros

解决方案


这些是struct in6_addr. 该标准要求struct in6_addr至少有一个成员s6_addr,它必须是一个uint8_t[16].

然而,大多数时候,struct in6_addr它被实现为包含 8、16 和 32 位整数数组的嵌套联合,以优化访问。例如,glibc 有

struct in6_addr {
  union {
    uint8_t __u6_addr8[16];
    uint16_t __u6_addr16[8];
    uint32_t __u6_addr32[4];
  } __in6_u;
};

和一个访问器定义

#define s6_addr                 __in6_u.__u6_addr8

请记住,联合初始化器需要它们自己的一组大括号并在联合的第一个成员上进行操作。结构需要最外层,联合{}需要下一层,数组初始化器{}需要最内层{}

因此

#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }

这是

0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0 

#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }

这是

::1

推荐阅读