由於在網路找到的sample都難直接拿來用,可能是因為MIPS很少人用,而MIPS因為byte order跟network byte order一樣所以被排擠,所以我把最後集各家之大成試出來可以用的sample放在這邊
struct pseudoHeader {
uint32_t ip_src;
uint32_t ip_dst;
uint8_t zero;//always zero
uint8_t protocol;
uint16_t len;
};
static inline uint16_t
checksum (uint16_t *data, int len)
{
uint16_t ret = 0;
uint32_t sum = 0;
while (len > 1) {
sum += *data++;
len -= 2;
}
if (len > 0) {
sum += ((*data)&0xFF00);
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
ret = ~sum;
return ret;
}
uint16_t
tcp_udp_checksum(struct ip *iph, uint8_t *header, int header_size, uint8_t protocol, uint8_t *data, int size)
{
struct pseudoHeader psd_header;
psd_header.ip_dst = (uint32_t)iph->ip_dst.s_addr;
psd_header.ip_src = (uint32_t)iph->ip_src.s_addr;
psd_header.zero = 0;
psd_header.protocol = protocol;
psd_header.len = header_size+size;
uint8_t buf[4096];
memcpy(buf, &psd_header, sizeof(struct pseudoHeader));
memcpy(buf+sizeof(struct pseudoHeader), header, header_size);
memcpy(buf+sizeof(struct pseudoHeader)+header_size, data, size);
return checksum((uint16_t *)buf, sizeof(struct pseudoHeader)+header_size+size);
}
void
test(void)
{
tcph->chksum = 0
tcph->chksum = tcp_udp_checksum (iphdr, (uint8_t *)tcph, 20, 6, payload, payload_size);
udph->check = 0;
udph->check = tcp_udp_checksum (iphdr, (uint8_t *)udph, sizeof(struct udphdr) , 17, payload, payload_size);
}