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, (unsignedshort *)udp_data, sizeof(udp)+sizeof(data)); // if I comment this line, no segmentation fault!
// I get segmentation fault on the next line:
memcpy(packet + 20, &udp, sizeof(udp));
so the problem is the cksum_udp() function
the in_cksum_udp() function is as below, I don't see any problems:
To assume the problem is in that function based on this alone is probably not the best move. That's what's so nasty about memory corruption issues.
You're lucky, though, in that the crash is easy and consistent to reproduce.
Start with the memcpy call itself. For memcpy to call a segfault, you must be stepping out of bounds either during the read or the write. The write is more likely.
Put breakpoints after the initialization of packet and on the memcpy line. Look at the contents of the pointer (ie: the address it's pointing to) to make sure it's the same at both times.
If it's different, it's likely that memory corruption is causing your pointer to point to somewhere else, making it a bad pointer. This is very likely to cause a segfault. If that's the case, step through your code, keeping an eye on that pointer to see where it gets changed. Or better yet, if your IDE/Debugger supports it, set a "memory breakpoint" to trigger when that variable changes.
If the pointer is correct at the time of the memcpy... then that means either the memory it points to is either no longer allocated (you're accidentally free'ing it prematurely)... or it's a problem with the source buffer.
I don't think it's the latter since udp looks like a local variable.. so there's no way the pointer to it could be corrupted.