'struct in6_addr'没有使用-ansi命名为's6_addr32'的成员

时间:2016-03-25 12:53:51

标签: c linux ipv6 ansi

在使用 ol 构建OpenSSL时,我正在解决一些编译错误。我抓住了这个错误:

no-asm -ansi

我在$ ./config no-asm -ansi ... $ make ... gcc -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_THREADS -DOPENSSL_NO_STATIC_ENGINE -DOPENSSL_PIC -DOPENSSLDIR="\"/usr/local/ssl\"" -DENGINESDIR="\"/usr/local/lib/engines\"" -Wall -O3 -pthread -m64 -DL_ENDIAN -ansi -fPIC -Iinclude -I. -Icrypto/include -MMD -MF crypto/bio/bss_dgram.d.tmp -MT crypto/bio/bss_dgram.o -c -o crypto/bio/bss_dgram.o crypto/bio/bss_dgram.c In file included from /usr/include/netdb.h:27:0, from ./e_os.h:443, from crypto/bio/bio_lcl.h:2, from crypto/bio/bss_dgram.c:62: crypto/bio/bss_dgram.c: In function ‘dgram_get_mtu_overhead’: crypto/bio/bss_dgram.c:433:20: error: ‘const struct in6_addr’ has no member named ‘s6_addr32’ && IN6_IS_ADDR_V4MAPPED(&tmp_addr)) ^ 中找到了结构:

/usr/include/linux/in6.h

我不记得过去需要定义#if __UAPI_DEF_IN6_ADDR struct in6_addr { union { __u8 u6_addr8[16]; #if __UAPI_DEF_IN6_ADDR_ALT __be16 u6_addr16[8]; __be32 u6_addr32[4]; #endif } in6_u; #define s6_addr in6_u.u6_addr8 #if __UAPI_DEF_IN6_ADDR_ALT #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 #endif }; #endif /* __UAPI_DEF_IN6_ADDR */ 。搜索它会从内核的libc-compat.h,第95行左右显示以下内容(如果我正确解析它):

__UAPI_DEF_IN6_ADDR_ALT

我应该如何定义备用符号?

系统是Ubuntu 14.04(x86_64):

#define __UAPI_DEF_IN6_ADDR             1
/* We unconditionally define the in6_addr macros and glibc must coordinate. */
#define __UAPI_DEF_IN6_ADDR_ALT         1
#define __UAPI_DEF_SOCKADDR_IN6         1
#define __UAPI_DEF_IPV6_MREQ            1
#define __UAPI_DEF_IPPROTO_V6           1
#define __UAPI_DEF_IPV6_OPTIONS         1
#define __UAPI_DEF_IN6_PKTINFO          1
#define __UAPI_DEF_IP6_MTUINFO          1
海湾合作委员会是:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.4 LTS
Release:    14.04
Codename:   trusty

1 个答案:

答案 0 :(得分:1)

结果证明这很有趣......缺点是我需要添加-ansi-D_DEFAULT_SOURCE=1。但是,-D_DEFAULT_SOURCE=1类似于-ansi试图完成的任务,因此需要包含它。

首先,/usr/include/linux/in6.h是错误的标题。我通过struct in6_addr的grep找到了它,而不是跟踪包含需要完成的事情。

下一步...... -D_DEFAULT_SOURCE=1间接来自/usr/include/netinet/in.h

#ifndef __USE_KERNEL_IPV6_DEFS
/* IPv6 address */
struct in6_addr
  {
    union
      {
    uint8_t __u6_addr8[16];
#ifdef __USE_MISC
    uint16_t __u6_addr16[8];
    uint32_t __u6_addr32[4];
#endif
      } __in6_u;
#define s6_addr         __in6_u.__u6_addr8
#ifdef __USE_MISC
# define s6_addr16      __in6_u.__u6_addr16
# define s6_addr32      __in6_u.__u6_addr32
#endif
  };
#endif /* !__USE_KERNEL_IPV6_DEFS */

手动启用__USE_MISC无效。在__USE_MISC中跟踪/usr/include/features.h的内容:

/*
...
   __USE_MISC       Define things from 4.3BSD or System V Unix.
...
*/

#undef __USE_MISC
...

#if defined _DEFAULT_SOURCE
# define __USE_MISC 1
#endif

最后,来自/usr/include/features.h的评论:

_DEFAULT_SOURCE The default set of features (taking precedence over __STRICT_ANSI__).

虽然_DEFAULT_SOURCE=1-ansi不同,但影响可能仅限于受IN6_IS_ADDR_V4MAPPED影响的一个源文件。也就是说,对于C源文件 crypto/bio/bss_dgram.c

/* OpenSSL copyright ... */

#ifndef _DEFAULT_SOURCE
# define _DEFAULT_SOURCE 1
#endif

#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
...

摆弄__USE_KERNEL_IPV6_DEFS使事情变得更糟。我相信它启用了/usr/include/linux/in6.h,其成员名称与<netinet/in.h>相似(但完全不同)。