diff mbox

[v2,05/31] kvm tools: Add ICMP support for uip

Message ID 1309423279-3093-6-git-send-email-asias.hejun@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Asias He June 30, 2011, 8:40 a.m. UTC
- 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>
---
 tools/kvm/Makefile          |    1 +
 tools/kvm/include/kvm/uip.h |   11 +++++++++++
 tools/kvm/uip/csum.c        |    8 ++++++++
 tools/kvm/uip/icmp.c        |   29 +++++++++++++++++++++++++++++
 tools/kvm/uip/ipv4.c        |    8 ++++++++
 5 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 tools/kvm/uip/icmp.c
diff mbox

Patch

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index ece542c..9ad09a4 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -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
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
index 00100e1..b9fa932 100644
--- a/tools/kvm/include/kvm/uip.h
+++ b/tools/kvm/include/kvm/uip.h
@@ -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);
diff --git a/tools/kvm/uip/csum.c b/tools/kvm/uip/csum.c
index 8023ddb..c86bfdf 100644
--- a/tools/kvm/uip/csum.c
+++ b/tools/kvm/uip/csum.c
@@ -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 */
+}
diff --git a/tools/kvm/uip/icmp.c b/tools/kvm/uip/icmp.c
new file mode 100644
index 0000000..233297c
--- /dev/null
+++ b/tools/kvm/uip/icmp.c
@@ -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;
+}
diff --git a/tools/kvm/uip/ipv4.c b/tools/kvm/uip/ipv4.c
index da53fec..6175992 100644
--- a/tools/kvm/uip/ipv4.c
+++ b/tools/kvm/uip/ipv4.c
@@ -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;
 }