简体   繁体   中英

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

I tried to write a short own traceroute program in C for Linux using raw sockets, but when I compile I get the error message “dereferencing pointer to incomplete type” struct ip .

These are the headers I include:

#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>

and then how I use the ip header

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

followed by a bunch of stuff...then:

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;   

And then I use it for sending:

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

Transferring a comment into an answer.

On a Mac, the header <netinet/ip.h> does contain a struct ip — but that is not a header standardized by POSIX. It's also there in Linux (Ubuntu 16.04). So, it appears that when you do the dereferencing, you don't have the header included, or the contents of the header are 'invisible'.

Are you compiling with -std=gnu11 or -std=c11 ? If the latter, you probably need to enable POSIX (or GNU) definitions. That's most easily fixed by using -std=gnu11 instead. Alternatively, use -D_GNU_SOURCE or -D_XOPEN_SOURCE=700 or similar on the command line, or the equivalent #define in the source code.

For better or worse, I use a 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 */

You may use that if you wish, with or without attribution. You can find a version of the file at https://github.com/jleffler/soq/tree/master/src/libsoq .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM