kvm tools: Implement uip_csum_udp() to calculate UDP checksum

Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
Asias He
2011-06-29 16:47:16 +08:00
committed by Will Deacon
parent 39b72fd01d
commit 07197967df
2 changed files with 30 additions and 0 deletions
+1
View File
@@ -161,6 +161,7 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg);
int uip_tx_do_arp(struct uip_tx_arg *arg);
u16 uip_csum_icmp(struct uip_icmp *icmp);
u16 uip_csum_udp(struct uip_udp *udp);
u16 uip_csum_ip(struct uip_ip *ip);
struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
+29
View File
@@ -31,3 +31,32 @@ u16 uip_csum_icmp(struct uip_icmp *icmp)
ip = &icmp->ip;
return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
}
u16 uip_csum_udp(struct uip_udp *udp)
{
struct uip_pseudo_hdr hdr;
struct uip_ip *ip;
int udp_len;
u8 *pad;
ip = &udp->ip;
hdr.sip = ip->sip;
hdr.dip = ip->dip;
hdr.zero = 0;
hdr.proto = ip->proto;
hdr.len = udp->len;
udp_len = uip_udp_len(udp);
if (udp_len % 2) {
pad = (u8 *)&udp->sport + udp_len;
*pad = 0;
memcpy((u8 *)&udp->sport + udp_len + 1, &hdr, sizeof(hdr));
return uip_csum(0, (u8 *)&udp->sport, udp_len + 1 + sizeof(hdr));
} else {
memcpy((u8 *)&udp->sport + udp_len, &hdr, sizeof(hdr));
return uip_csum(0, (u8 *)&udp->sport, udp_len + sizeof(hdr));
}
}