* [Qemu-devel] [PATCH] Make ping work for -net user
@ 2007-08-16 3:37 jbrown105
2007-08-16 15:12 ` Luke -Jr
0 siblings, 1 reply; 2+ messages in thread
From: jbrown105 @ 2007-08-16 3:37 UTC (permalink / raw)
To: qemu-devel
[-- 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
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-08-16 15:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-16 3:37 [Qemu-devel] [PATCH] Make ping work for -net user jbrown105
2007-08-16 15:12 ` Luke -Jr
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).