qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: jbrown105@speedymail.org
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Make ping work for -net user
Date: Wed, 15 Aug 2007 23:37:16 -0400	[thread overview]
Message-ID: <1187235436.20746.1205640329@webmail.messagingengine.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 690 bytes --]

This is a very simple proof-of-concept patch that fakes ICMP well enough
for ping to work.

Basically, when the slirp code gets a ping request for an ip outside of
the
slirp network, it runs /bin/ping and reports the results back to the
guest
accordingly.

Right now it uses vfork() and then exec() to run ping on the host, as
for
some reason fork() causes qemu to freeze. I'm still trying to figure out
why.

As a consequence I don't close ping's output or error stream so you see
output
from it on the terminal window that qemu is running on.

Tested on a linux host and a linux guest.
-- 
  
  jbrown105@speedymail.org

-- 
http://www.fastmail.fm - Does exactly what it says on the tin


[-- Attachment #2: slirp-ping.patch --]
[-- Type: application/octet-stream, Size: 2936 bytes --]

diff -ur qemu/slirp/ip_icmp.c qemu.new/slirp/ip_icmp.c
--- qemu/slirp/ip_icmp.c	2006-05-03 15:58:17.000000000 -0400
+++ qemu/slirp/ip_icmp.c	2007-08-15 23:23:50.000000000 -0400
@@ -77,7 +77,9 @@
   register struct icmp *icp;
   register struct ip *ip=mtod(m, struct ip *);
   int icmplen=ip->ip_len;
-  /* int code; */
+  int cpid;
+  char * string_dst_ip;
+  int code;
 	
   DEBUG_CALL("icmp_input");
   DEBUG_ARG("m = %lx", (long )m);
@@ -117,48 +119,43 @@
     if (ip->ip_dst.s_addr == alias_addr.s_addr) {
       icmp_reflect(m);
     } else {
-      struct socket *so;
-      struct sockaddr_in addr;
-      if ((so = socreate()) == NULL) goto freeit;
-      if(udp_attach(so) == -1) {
-	DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", 
-		    errno,strerror(errno)));
-	sofree(so);
-	m_free(m);
-	goto end_error;
+      string_dst_ip = inet_ntoa(ip->ip_dst);
+      cpid = vfork();
+      if (cpid == 0)
+      {
+      	execl("/bin/ping", "ping", "-c", "1", string_dst_ip, NULL);
+	_exit(2);
       }
-      so->so_m = m;
-      so->so_faddr = ip->ip_dst;
-      so->so_fport = htons(7);
-      so->so_laddr = ip->ip_src;
-      so->so_lport = htons(9);
-      so->so_iptos = ip->ip_tos;
-      so->so_type = IPPROTO_ICMP;
-      so->so_state = SS_ISFCONNECTED;
-      
-      /* Send the packet */
-      addr.sin_family = AF_INET;
-      if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
-	/* It's an alias */
-	switch(ntohl(so->so_faddr.s_addr) & 0xff) {
-	case CTL_DNS:
-	  addr.sin_addr = dns_addr;
-	  break;
-	case CTL_ALIAS:
-	default:
-	  addr.sin_addr = loopback_addr;
-	  break;
-	}
-      } else {
-	addr.sin_addr = so->so_faddr;
+      else if (cpid == -1)
+      {
+	icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,"exec failed"); 
       }
-      addr.sin_port = so->so_fport;
-      if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
-		(struct sockaddr *)&addr, sizeof(addr)) == -1) {
-	DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
-		    errno,strerror(errno)));
-	icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); 
-	udp_detach(so);
+      else
+      {
+	int x;
+	while ((x = waitpid(cpid, &code, WNOHANG)) != cpid)
+	{
+		if (x != 0)
+		{
+		break;
+		}
+	}
+
+	int i1, i2;
+	i1 = WIFEXITED(code);
+	if (i1)
+	  i2 = WEXITSTATUS(code);
+	else
+	  i2 = 1;
+
+	if (i1 && (i2 == 0))
+	{
+           icmp_reflect(m);
+	}
+	else
+	{
+	   icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,"ping failed"); 
+	}
       }
     } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
     break;
diff -ur qemu/slirp/ip_icmp.h qemu.new/slirp/ip_icmp.h
--- qemu/slirp/ip_icmp.h	2005-06-05 13:11:42.000000000 -0400
+++ qemu.new/slirp/ip_icmp.h	2007-08-15 21:42:17.000000000 -0400
@@ -161,4 +161,7 @@
 void icmp_error _P((struct mbuf *, u_char, u_char, int, char *));
 void icmp_reflect _P((struct mbuf *));
 
+#include <sys/wait.h>
+#include <unistd.h>
+
 #endif

             reply	other threads:[~2007-08-16  3:37 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-16  3:37 jbrown105 [this message]
2007-08-16 15:12 ` [Qemu-devel] [PATCH] Make ping work for -net user Luke -Jr

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1187235436.20746.1205640329@webmail.messagingengine.com \
    --to=jbrown105@speedymail.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).