完整的代码在
http://docs.google.com/file/d/0B09y_TWqTtwlaHNjdjYybHVIcjA/edit?usp=sharing
char data[]="just for a try";
u_char *packet=(u_char *)malloc(28+sizeof(data));
...
...
u_char *udp_data=(u_char *)malloc(8+sizeof(data));
if(udp_data == NULL )
perror("allocating space for udp_data fails\n");
memcpy(udp_data, &udp, sizeof(udp));
memcpy(udp_data+8, data, sizeof(data));
udp.check = in_cksum_udp(ip.ip_src.s_addr, ip.ip_dst.s_addr, (unsigned short *)udp_data, sizeof(udp)+sizeof(data)); // if I comment this line, no segmentation fault!
free(udp_data);
udp_data=NULL;
// I get segmentation fault on the next line:
memcpy(packet + 20, &udp, sizeof(udp));
问题是 cksum_udp() 函数错误是
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a2b in run (arg=0x0) at raw_udp_client.c:115
115 memcpy(packet + 20, &udp, sizeof(udp));
in_cksum_udp() 之前的核心转储 https://docs.google.com/file/d/0B09y_TWqTtwldFI5UGdfc01RU28/edit?usp=sharing
ip = {ip_hl = 5, ip_v = 4, ip_tos = 0 '\000', ip_len = 10752, ip_id = 0,
ip_off = 0, ip_ttl = 64 '@', ip_p = 17 '\021', ip_sum = 32808, ip_src = {
s_addr = 1825136778}, ip_dst = {s_addr = 376725642}}
udp = {source = 51377, dest = 125, len = 5632, check = 0}
sd = 0
on = 1
sin = {sin_family = 1, sin_port = 0, sin_addr = {s_addr = 0},
sin_zero = "ݲ\360\000\000\000\000"}
packet = 0x602010 "E"
data = "I'm not here!"
udp_data = 0x602050 "\261\310}"
在 in_cksum_udp() 之后
ip = {ip_hl = 0, ip_v = 0, ip_tos = 0 '\000', ip_len = 0, ip_id = 0,
ip_off = 0, ip_ttl = 0 '\000', ip_p = 0 '\000', ip_sum = 0, ip_src = {
s_addr = 0}, ip_dst = {s_addr = 0}}
udp = {source = 0, dest = 0, len = 0, check = 4842}
sd = 0
on = 0
sin = {sin_family = 0, sin_port = 0, sin_addr = {s_addr = 0},
sin_zero = "\000\000\000\000\000\000\000"}
packet = 0x0
data = '\000' <repeats 13 times>
udp_data = 0x0
in_cksum_udp() 函数如下,我没有发现任何问题:
struct psd_udp {
struct in_addr src;
struct in_addr dst;
unsigned char pad;
unsigned char proto;
unsigned short udp_len;
struct udphdr udp;
};
unsigned short in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
unsigned short in_cksum_udp(int src, int dst, unsigned short *addr, int len)
{
struct psd_udp buf;
memset(&buf, 0, sizeof(buf));
buf.src.s_addr = src;
buf.dst.s_addr = dst;
buf.pad = 0;
buf.proto = IPPROTO_UDP;
buf.udp_len = htons(len);
memcpy(&(buf.udp), addr, len);
return in_cksum((unsigned short *)&buf, 12 + len);
}
似乎该函数与指针数据包指向的内存无关有什么潜在问题?