summaryrefslogtreecommitdiffstats
path: root/qemu/slirp/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/slirp/udp.c')
-rw-r--r--qemu/slirp/udp.c90
1 files changed, 30 insertions, 60 deletions
diff --git a/qemu/slirp/udp.c b/qemu/slirp/udp.c
index f77e00f5a..247024fd8 100644
--- a/qemu/slirp/udp.c
+++ b/qemu/slirp/udp.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include "ip_icmp.h"
@@ -70,9 +71,11 @@ udp_input(register struct mbuf *m, int iphlen)
int len;
struct ip save_ip;
struct socket *so;
+ struct sockaddr_storage lhost;
+ struct sockaddr_in *lhost4;
DEBUG_CALL("udp_input");
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("m = %p", m);
DEBUG_ARG("iphlen = %d", iphlen);
/*
@@ -125,6 +128,11 @@ udp_input(register struct mbuf *m, int iphlen)
}
}
+ lhost.ss_family = AF_INET;
+ lhost4 = (struct sockaddr_in *) &lhost;
+ lhost4->sin_addr = ip->ip_src;
+ lhost4->sin_port = uh->uh_sport;
+
/*
* handle DHCP/BOOTP
*/
@@ -140,7 +148,11 @@ udp_input(register struct mbuf *m, int iphlen)
*/
if (ntohs(uh->uh_dport) == TFTP_SERVER &&
ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
- tftp_input(m);
+ m->m_data += iphlen;
+ m->m_len -= iphlen;
+ tftp_input(&lhost, m);
+ m->m_data -= iphlen;
+ m->m_len += iphlen;
goto bad;
}
@@ -151,25 +163,7 @@ udp_input(register struct mbuf *m, int iphlen)
/*
* Locate pcb for datagram.
*/
- so = slirp->udp_last_so;
- if (so == &slirp->udb || so->so_lport != uh->uh_sport ||
- so->so_laddr.s_addr != ip->ip_src.s_addr) {
- struct socket *tmp;
-
- for (tmp = slirp->udb.so_next; tmp != &slirp->udb;
- tmp = tmp->so_next) {
- if (tmp->so_lport == uh->uh_sport &&
- tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
- so = tmp;
- break;
- }
- }
- if (tmp == &slirp->udb) {
- so = NULL;
- } else {
- slirp->udp_last_so = so;
- }
- }
+ so = solookup(&slirp->udp_last_so, &slirp->udb, &lhost, NULL);
if (so == NULL) {
/*
@@ -180,7 +174,7 @@ udp_input(register struct mbuf *m, int iphlen)
if (!so) {
goto bad;
}
- if(udp_attach(so) == -1) {
+ if (udp_attach(so, AF_INET) == -1) {
DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
errno,strerror(errno)));
sofree(so);
@@ -190,6 +184,7 @@ udp_input(register struct mbuf *m, int iphlen)
/*
* Setup fields
*/
+ so->so_lfamily = AF_INET;
so->so_laddr = ip->ip_src;
so->so_lport = uh->uh_sport;
@@ -202,6 +197,7 @@ udp_input(register struct mbuf *m, int iphlen)
*/
}
+ so->so_ffamily = AF_INET;
so->so_faddr = ip->ip_dst; /* XXX */
so->so_fport = uh->uh_dport; /* XXX */
@@ -217,7 +213,9 @@ udp_input(register struct mbuf *m, int iphlen)
m->m_data -= iphlen;
*ip=save_ip;
DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
- icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+ icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0,
+ strerror(errno));
+ goto bad;
}
m_free(so->so_m); /* used for ICMP if error on sorecvfrom */
@@ -233,7 +231,7 @@ bad:
m_free(m);
}
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos)
{
@@ -241,8 +239,8 @@ int udp_output2(struct socket *so, struct mbuf *m,
int error = 0;
DEBUG_CALL("udp_output");
- DEBUG_ARG("so = %lx", (long)so);
- DEBUG_ARG("m = %lx", (long)m);
+ DEBUG_ARG("so = %p", so);
+ DEBUG_ARG("m = %p", m);
DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr);
DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr);
@@ -284,35 +282,11 @@ int udp_output2(struct socket *so, struct mbuf *m,
return (error);
}
-int udp_output(struct socket *so, struct mbuf *m,
- struct sockaddr_in *addr)
-
-{
- Slirp *slirp = so->slirp;
- struct sockaddr_in saddr, daddr;
-
- saddr = *addr;
- if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
- slirp->vnetwork_addr.s_addr) {
- uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
-
- if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
- saddr.sin_addr = slirp->vhost_addr;
- } else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
- so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
- saddr.sin_addr = so->so_faddr;
- }
- }
- daddr.sin_addr = so->so_laddr;
- daddr.sin_port = so->so_lport;
-
- return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
-}
-
int
-udp_attach(struct socket *so)
+udp_attach(struct socket *so, unsigned short af)
{
- if((so->s = qemu_socket(AF_INET,SOCK_DGRAM,0)) != -1) {
+ so->s = qemu_socket(af, SOCK_DGRAM, 0);
+ if (so->s != -1) {
so->so_expire = curtime + SO_EXPIRE;
insque(so, &so->slirp->udb);
}
@@ -375,13 +349,9 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
socket_set_fast_reuse(so->s);
getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
- so->so_fport = addr.sin_port;
- if (addr.sin_addr.s_addr == 0 ||
- addr.sin_addr.s_addr == loopback_addr.s_addr) {
- so->so_faddr = slirp->vhost_addr;
- } else {
- so->so_faddr = addr.sin_addr;
- }
+ so->fhost.sin = addr;
+ sotranslate_accept(so);
+ so->so_lfamily = AF_INET;
so->so_lport = lport;
so->so_laddr.s_addr = laddr;
if (flags != SS_FACCEPTONCE)