2016-08-16 91 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)将返回大小指针的,不是指出,和我不不要以为这是你想要的。使用正确的大小而不是它们。