[英]segmentation fault passing pointer to function
因此,從parseEther方法調用parseIP函數時會發生分段錯誤。
我真的不知道為什么會出現分段錯誤,我只是獲取數據包指針並添加了以太網報頭的長度(14)。
打印地址的輸出為我提供了十六進制的地址,它們相距14,因此我知道指針指向內存中的正確位置。 盡管如此,通過時我仍然遇到分段錯誤?
我錯過了令人眼花obvious亂的明顯東西嗎?
輸出示例: https : //s1.postimg.org/96owsptn8v/seg_fault.png
編輯
我只是從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("\n\n === 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 - %p\n", packet);
const unsigned char *payload = packet + ETH_HLEN;
printf("Payload address - %p\n", payload);
//payload pointer now points to start of the network header
printf("\nType: %d\n", 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 detected\n");
parseIP(payload);
}
}
我錯過了令人眼花obvious亂的明顯東西嗎?
我想這取決於您的明顯性標准,但是肯定這是錯誤的:
struct ip *ip_header = (struct ip*) *packet;
函數參數packet
是一個const unsigned char *
,因此該語句將其指向的單個unsigned char
的值轉換為指針,然后將其用作指向struct ip
的struct ip
。 這幾乎可以肯定會產生未定義的行為,這違反了嚴格的別名規則,並且基本上沒有機會產生您實際想要的行為。 改為這樣做:
struct ip *ip_header = (struct ip*) packet;
但是也要注意,將結構類型映射到原始字節數組是一件棘手的事情。 獲取正確的成員順序和數據類型通常並不難,但是C允許結構布局在結構成員之間(和之后)包含任意填充。 特別是,盡管大多數C實現都提供了避免這種情況的機制,但沒有標准的機制。
在這種情況下,您會雙重遇到該問題。 您的struct ip
和struct ether_header
不僅要服從它,系統的struct in_addr
struct ether_header
服從它。 盡管您可以控制自己的結構的聲明,但是假設您可以像為inet_ntoa
生成參數那樣將struct in_addr
映射到原始數據包數據上,這實在是一件很危險的inet_ntoa
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.