mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-10-04 15:58:29 +00:00
kvm tools: Add ICMP support for uip
- Introduce struct uip_icmp to present ICMP package - Implement uip_csum_icmp() to calculate ICMP checksum - Current ICMP implementation in uip does not really send ICMP package to remote host in question, instead it just fake a ICMP reply to fool guest. Signed-off-by: Asias He <asias.hejun@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
@@ -46,6 +46,7 @@ OBJS += disk/raw.o
|
||||
OBJS += ioeventfd.o
|
||||
OBJS += irq.o
|
||||
OBJS += uip/arp.o
|
||||
OBJS += uip/icmp.o
|
||||
OBJS += uip/ipv4.o
|
||||
OBJS += uip/buf.o
|
||||
OBJS += uip/csum.o
|
||||
|
||||
@@ -51,6 +51,15 @@ struct uip_ip {
|
||||
u32 dip;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct uip_icmp {
|
||||
struct uip_ip ip;
|
||||
u8 type;
|
||||
u8 code;
|
||||
u16 csum;
|
||||
u16 id;
|
||||
u16 seq;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct uip_info {
|
||||
struct list_head udp_socket_head;
|
||||
struct list_head tcp_socket_head;
|
||||
@@ -100,9 +109,11 @@ static inline u16 uip_ip_len(struct uip_ip *ip)
|
||||
return htons(ip->len);
|
||||
}
|
||||
|
||||
int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
|
||||
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_ip(struct uip_ip *ip);
|
||||
|
||||
struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
|
||||
|
||||
@@ -23,3 +23,11 @@ u16 uip_csum_ip(struct uip_ip *ip)
|
||||
{
|
||||
return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip));
|
||||
}
|
||||
|
||||
u16 uip_csum_icmp(struct uip_icmp *icmp)
|
||||
{
|
||||
struct uip_ip *ip;
|
||||
|
||||
ip = &icmp->ip;
|
||||
return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
#include "kvm/uip.h"
|
||||
|
||||
int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg)
|
||||
{
|
||||
struct uip_ip *ip, *ip2;
|
||||
struct uip_icmp *icmp2;
|
||||
struct uip_buf *buf;
|
||||
|
||||
buf = uip_buf_clone(arg);
|
||||
|
||||
icmp2 = (struct uip_icmp *)(buf->eth);
|
||||
ip2 = (struct uip_ip *)(buf->eth);
|
||||
ip = (struct uip_ip *)(arg->eth);
|
||||
|
||||
ip2->sip = ip->dip;
|
||||
ip2->dip = ip->sip;
|
||||
ip2->csum = 0;
|
||||
/*
|
||||
* ICMP reply: 0
|
||||
*/
|
||||
icmp2->type = 0;
|
||||
icmp2->csum = 0;
|
||||
ip2->csum = uip_csum_ip(ip2);
|
||||
icmp2->csum = uip_csum_icmp(icmp2);
|
||||
|
||||
uip_buf_set_used(arg->info, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -11,5 +11,13 @@ int uip_tx_do_ipv4(struct uip_tx_arg *arg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (ip->proto) {
|
||||
case 0x01: /* ICMP */
|
||||
uip_tx_do_ipv4_icmp(arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user