2016-08-16 96 views
-1

這是我第一次發佈堆棧溢出,所以要溫和。我正在編寫一個網絡程序在Linux上運行。我的程序的目標是能夠捕獲發送給它的數據包,更改源ip和hw地址,使用新信息重建數據包並將其發送回線路。我的問題涉及重建過程。我有一些結構用於保存我的程序中各種標題的信息。這裏詳細將多個結構強制轉換爲char字符串

struct my_ip 
{ 
    u_int8_t ip_vhl;  /* header length, version */ 
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) 
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) 
    u_int8_t ip_tos;  /* type of service */ 
    u_int16_t ip_len;  /* total length */ 
    u_int16_t ip_id;  /* identification */ 
    u_int16_t ip_off;  /* fragment offset field */ 
#define IP_DF 0x4000   /* dont fragment flag */ 
#define IP_MF 0x2000   /* more fragments flag */ 
#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */ 
    u_int8_t ip_ttl;  /* time to live */ 
    u_int8_t ip_p;  /* protocol */ 
    u_int16_t ip_sum;  /* checksum */ 
    struct in_addr ip_src,ip_dst; /* source and dest address */ 
}; 
/* UDP header */ 

struct sniff_udp 
{ 
     u_short uh_sport;    /* source port */ 
     u_short uh_dport;    /* destination port */ 
     u_short uh_ulen;    /* udp length */ 
     u_short uh_sum;     /* udp checksum */ 

}; 

#define SIZE_UDP  8    /* length of UDP header */ 
#define SIZE_ETHERNET 14 

以及從pcap庫(如ether_header)的一些其他結構。我投的u_char *這些結構像這樣

struct my_ip* ip = (struct my_ip*)(packet + sizeof(struct ether_header)); 
    struct ether_header* eptr = (struct ether_header *) packet; 

packet是一個u_char拿着包 我的問題是,一旦我有這些結構怎麼辦我投我所有的stucts回內修改數據的全部成一個單一的u_char字符串?我試圖用結構相同的方式來施放每個結構來填充不同的字符串段 這是我迄今爲止的代碼。

void buildPacket(sniff_udp *udp, ether_header *ethh, my_ip *ip, u_char *payload, u_char *buffer) 
{ 
    memset(buffer,0, (sizeof(udp)+sizeof(ethh)+sizeof(ip)+sizeof(payload))); 
    buffer=(u_char *)(ethh); // adds layer 2 header 
    (buffer+SIZE_ETHERNET)= (u_char *)ip; // adds layer 3 header 
    (buffer+SIZE_ETHERNET+sizeof(ip))=(u_char *) udp; // adds protocol header 
    (buffer+SIZE_ETHERNET+sizeof(ip)+SIZE_UDP)=(u_char *)payload; // adds payload 
} 

這不是從我收集到的正確方法。我怎樣才能投多個結構到同一個字符串?

+1

1)正確設置代碼的格式。 2)見[問]。 3)使用正確的(反)序列化,而不是強制轉換等。你的代碼可能(我們不能肯定地說沒有[mcve])調用未定義的行爲。 – Olaf

+0

你真的認爲'packet'的類型是'u_char'?是不是'u_char *'? – MikeCAT

回答

0

喜歡的東西

(buffer+SIZE_ETHERNET)= (u_char *)ip; // adds layer 3 header 

是無效的,因爲=左手操作不會有(modifable)左值。

您可以使用memcpy()複製內存的內容。正確的代碼應該是這樣:

void buildPacket(sniff_udp *udp, ether_header *ethh, my_ip *ip, u_char *payload, u_char *buffer) 
{ 
    memset(buffer,0, (sizeof(udp)+sizeof(ethh)+sizeof(ip)+sizeof(payload))); 
    memcpy(buffer, ethh, SIZE_ETHERNET); // adds layer 2 header 
    memcpy(buffer+SIZE_ETHERNET, ip, sizeof(ip)); // adds layer 3 header 
    memcpy(buffer+SIZE_ETHERNET+sizeof(ip), udp, SIZE_UDP); // adds protocol header 
    memcpy(buffer+SIZE_ETHERNET+sizeof(ip)+SIZE_UDP, payload, sizeof(payload)); // adds payload 
} 

此代碼似乎並不正確,因爲sizeof(udp)sizeof(ethh)sizeof(ip)sizeof(payload)將返回大小指針的,不是指出,和我不不要以爲這是你想要的。使用正確的大小而不是它們。