尝试写入 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.
找到该文件的版本
我尝试使用原始套接字在 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.
找到该文件的版本