c-将指针传递给函数的分段错误



因此,分段错误发生在从parseEther方法调用parseIP函数时
我真的不知道为什么会出现分段错误,我只是取了我的数据包指针,并添加了以太网标头的长度(14)
打印地址的输出给我的是相隔14的十六进制地址,所以我知道指针指向内存中的正确位置。尽管如此,我在通过它时仍然会遇到分割错误
我是不是错过了一些显而易见的东西
输出示例:https://s1.postimg.org/96owsptn8v/seg_fault.png
edit
我刚刚从parseIP中取出代码,并将其放入调用它的if语句中,它运行得非常好。真奇怪。有人知道吗?

void parseIP(const unsigned char *packet)
{
printf("before we cast ip header");
struct ip *ip_header = (struct ip*) *packet;
printf("Before we initialise length");
short length = ip_header -> ip_len;
printf("Before we initialise headerlength");
int headerlength = ntohs(ip_header-> ip_hl); //iphdr points to header of network packet
printf("No segmentation fault here! n");
printf("n Source Ip address n");
printf("%s", inet_ntoa(ip_header -> ip_src));
printf("n Destination Ip address n");
printf("%s", inet_ntoa(ip_header -> ip_dst));
int data_bytes = length - headerlength;
const unsigned char *payload = packet + headerlength;
}
void parseEther(const unsigned char *packet, int length)
{
int i;
int pcount = 0;
struct ether_header *eth_header = (struct ether_header *) packet;
printf("nn === PACKET %ld HEADER ===", pcount);
printf("nSource MAC: ");
for (i = 0; i < 6; ++i)
{
printf("%02x", eth_header->ether_shost[i]);
if (i < 5)
{
printf(":");
}
}
printf("nDestination MAC: ");
for (i = 0; i < 6; ++i)
{
printf("%02x", eth_header->ether_dhost[i]);
if (i < 5)
{
printf(":");
}   
}
int data_bytes = length - ETH_HLEN;
printf(" n total length - %d -- length of header - %d -- remaining length - %d n", length, ETH_HLEN, data_bytes);
printf("Packet address - %pn", packet);
const unsigned char *payload = packet + ETH_HLEN;
printf("Payload address - %pn", payload);
//payload pointer now points to start of the network header
printf("nType: %dn", ntohs(eth_header->ether_type));
if(ntohs(eth_header->ether_type) == 0x0806)
{
printf("ARP detected n");
// parseARP(payload);
}
else if(ntohs(eth_header->ether_type) == 0x0800)
{
printf("nIP detectedn");
parseIP(payload);
}
}

我是不是遗漏了一些显而易见的东西?

我想这取决于你的显而易见的标准,但这肯定是错误的:

struct ip *ip_header = (struct ip*) *packet;

函数参数packet是一个const unsigned char *,因此该语句将其指向的单个unsigned char的值转换为指针,然后将其用作指向struct ip的指针。这几乎肯定会产生未定义的行为,因为这违反了严格的别名规则,而且它产生您真正想要的行为的可能性基本为零。改为:

struct ip *ip_header = (struct ip*) packet;

然而,也要注意,将结构类型映射到原始字节数组是一项棘手的业务。获得正确的成员顺序和数据类型通常并不困难,但C允许结构布局在结构成员之间(和之后)包含任意填充。特别是,尽管大多数C实现提供了避免这种情况的机制,但没有标准的机制

在这种情况下,你会遇到双重问题。不仅您的struct ipstruct ether_header受其约束,系统的struct in_addr也受其约束。尽管您可以控制自己结构的声明,但假设您可以将struct in_addr映射到原始数据包数据上是危险的,就像您为inet_ntoa生成参数一样。

相关内容

  • 没有找到相关文章

最新更新