尝试写入 struct ip 时出现错误“取消引用指向不完整类型的指针”

Error “dereferencing pointer to incomplete type” when trying to write to a struct ip

我尝试使用原始套接字在 C 中为 Linux 编写一个简短的自己的 traceroute 程序, 但是当我编译时,我收到错误消息“取消引用指向不完整类型的指针”struct ip

这些是我包括的 header:

#include <netinet/ip.h>         
#include <netinet/ip_icmp.h>        
#include <sys/socket.h>         
#include <stdlib.h>             
#include <stdio.h>              
#include <sys/types.h>
#include <errno.h>
#include <netdb.h> 
#include <arpa/inet.h>
#include <ifaddrs.h>

然后我如何使用 ip header

struct ip *myIpHeader = (struct ip*)buffr;

接着是一堆东西...然后:

myIpHeader->ip_v = 4;                           
myIpHeader->ip_hl = 5;                      
myIpHeader->ip_tos = 0;                                             
myIpHeader->ip_len = 20+8;                  
myIpHeader->ip_off = 0;                     
myIpHeader->ip_p = IPPROTO_ICMP;                
inet_pton(AF_INET, argv[1], &(myIpHeader->ip_dst)); 
inet_pton(AF_INET, ownip->h_name, &(myIpHeader->ip_src));
myIpHeader->ip_sum = 0;                      
myIpHeader->ip_id = htonl(12345);                    
myIpHeader->ip_ttl = ttl;   

然后我用它来发送:

sendto(mysock, buffr, sizeof myIpHeader + sizeof myicmphead, 0, (struct sockaddr*)&cliAddr, sizeof cliAddr);

正在将评论转为答案。

在 Mac 上,header <netinet/ip.h> 确实包含 struct ip — 但那不是 POSIX 标准化的 header .它也存在于 Linux (Ubuntu 16.04) 中。因此,看起来当您进行取消引用时,您没有包含 header,或者 header 的内容是 'invisible'.

您是使用 -std=gnu11 还是 -std=c11 进行编译?如果是后者,您可能需要启用 POSIX(或 GNU)定义。改用 -std=gnu11 最容易解决这个问题。或者,在命令行上使用 -D_GNU_SOURCE-D_XOPEN_SOURCE=700 或类似的方法,或者在源代码中使用等效的 #define

无论好坏,我使用 home-brew header posixver.h:

/*
@(#)File:           $RCSfile: posixver.h,v $
@(#)Version:        $Revision: 1.4 $
@(#)Last changed:   $Date: 2017/06/18 00:15:42 $
@(#)Purpose:        Request appropriate POSIX and X/Open Support
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 2010-2017
*/

/*TABSTOP=4*/

#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H

/*
** Include this file before including system headers.  By default, with
** C99 support from the compiler, it requests POSIX 2008 support.  With
** C89 support only, it requests POSIX 1997 support.  Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/

/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */

#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if defined(__cplusplus)
#define _XOPEN_SOURCE 700   /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#elif __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 700   /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#else
#define _XOPEN_SOURCE 500   /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */

#endif /* JLSS_ID_POSIXVER_H */

您可以根据需要使用它,无论是否注明出处。您可以在 https://github.com/jleffler/soq/tree/master/src/libsoq.

找到该文件的版本