TCP/UDP checksum (MIPS)

閱讀時間約 3 分鐘
由於在網路找到的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);
}
    Jy Lin
    Jy Lin
    留言0
    查看全部
    發表第一個留言支持創作者!
    從 Google News 追蹤更多 vocus 的最新精選內容