Revision 460fec67 slirp/udp.c
b/slirp/udp.c | ||
---|---|---|
41 | 41 |
#include <slirp.h> |
42 | 42 |
#include "ip_icmp.h" |
43 | 43 |
|
44 |
struct socket udb; |
|
45 |
|
|
46 | 44 |
static u_int8_t udp_tos(struct socket *so); |
47 | 45 |
static void udp_emu(struct socket *so, struct mbuf *m); |
48 | 46 |
|
49 |
struct socket *udp_last_so = &udb; |
|
50 |
|
|
51 | 47 |
void |
52 |
udp_init(void)
|
|
48 |
udp_init(Slirp *slirp)
|
|
53 | 49 |
{ |
54 |
udb.so_next = udb.so_prev = &udb; |
|
50 |
slirp->udb.so_next = slirp->udb.so_prev = &slirp->udb; |
|
51 |
slirp->udp_last_so = &slirp->udb; |
|
55 | 52 |
} |
56 | 53 |
/* m->m_data points at ip packet header |
57 | 54 |
* m->m_len length ip packet |
... | ... | |
60 | 57 |
void |
61 | 58 |
udp_input(register struct mbuf *m, int iphlen) |
62 | 59 |
{ |
60 |
Slirp *slirp = m->slirp; |
|
63 | 61 |
register struct ip *ip; |
64 | 62 |
register struct udphdr *uh; |
65 | 63 |
int len; |
... | ... | |
128 | 126 |
goto bad; |
129 | 127 |
} |
130 | 128 |
|
131 |
if (slirp_restrict)
|
|
129 |
if (slirp->restricted) {
|
|
132 | 130 |
goto bad; |
131 |
} |
|
133 | 132 |
|
134 | 133 |
/* |
135 | 134 |
* handle TFTP |
... | ... | |
142 | 141 |
/* |
143 | 142 |
* Locate pcb for datagram. |
144 | 143 |
*/ |
145 |
so = udp_last_so; |
|
144 |
so = slirp->udp_last_so;
|
|
146 | 145 |
if (so->so_lport != uh->uh_sport || |
147 | 146 |
so->so_laddr.s_addr != ip->ip_src.s_addr) { |
148 | 147 |
struct socket *tmp; |
149 | 148 |
|
150 |
for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { |
|
149 |
for (tmp = slirp->udb.so_next; tmp != &slirp->udb; |
|
150 |
tmp = tmp->so_next) { |
|
151 | 151 |
if (tmp->so_lport == uh->uh_sport && |
152 | 152 |
tmp->so_laddr.s_addr == ip->ip_src.s_addr) { |
153 | 153 |
so = tmp; |
154 | 154 |
break; |
155 | 155 |
} |
156 | 156 |
} |
157 |
if (tmp == &udb) { |
|
157 |
if (tmp == &slirp->udb) {
|
|
158 | 158 |
so = NULL; |
159 | 159 |
} else { |
160 |
udp_last_so = so; |
|
160 |
slirp->udp_last_so = so;
|
|
161 | 161 |
} |
162 | 162 |
} |
163 | 163 |
|
... | ... | |
166 | 166 |
* If there's no socket for this packet, |
167 | 167 |
* create one |
168 | 168 |
*/ |
169 |
if ((so = socreate()) == NULL) goto bad; |
|
169 |
so = socreate(slirp); |
|
170 |
if (!so) { |
|
171 |
goto bad; |
|
172 |
} |
|
170 | 173 |
if(udp_attach(so) == -1) { |
171 | 174 |
DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", |
172 | 175 |
errno,strerror(errno))); |
... | ... | |
279 | 282 |
struct sockaddr_in *addr) |
280 | 283 |
|
281 | 284 |
{ |
285 |
Slirp *slirp = so->slirp; |
|
282 | 286 |
struct sockaddr_in saddr, daddr; |
283 | 287 |
|
284 | 288 |
saddr = *addr; |
285 |
if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) { |
|
286 |
if ((so->so_faddr.s_addr & ~vnetwork_mask.s_addr) == |
|
287 |
~vnetwork_mask.s_addr) { |
|
288 |
saddr.sin_addr = vhost_addr; |
|
289 |
if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) == |
|
290 |
slirp->vnetwork_addr.s_addr) { |
|
291 |
uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr; |
|
292 |
|
|
293 |
if ((so->so_faddr.s_addr & inv_mask) == inv_mask) { |
|
294 |
saddr.sin_addr = slirp->vhost_addr; |
|
289 | 295 |
} else if (addr->sin_addr.s_addr == loopback_addr.s_addr || |
290 |
so->so_faddr.s_addr != vhost_addr.s_addr) { |
|
296 |
so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
|
|
291 | 297 |
saddr.sin_addr = so->so_faddr; |
292 | 298 |
} |
293 | 299 |
} |
... | ... | |
323 | 329 |
} else { |
324 | 330 |
/* success, insert in queue */ |
325 | 331 |
so->so_expire = curtime + SO_EXPIRE; |
326 |
insque(so,&udb);
|
|
332 |
insque(so, &so->slirp->udb);
|
|
327 | 333 |
} |
328 | 334 |
} |
329 | 335 |
return(so->s); |
... | ... | |
595 | 601 |
} |
596 | 602 |
|
597 | 603 |
struct socket * |
598 |
udp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport,
|
|
599 |
int flags) |
|
604 |
udp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
|
|
605 |
u_int lport, int flags)
|
|
600 | 606 |
{ |
601 | 607 |
struct sockaddr_in addr; |
602 | 608 |
struct socket *so; |
603 | 609 |
socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1; |
604 | 610 |
|
605 |
if ((so = socreate()) == NULL) {
|
|
606 |
free(so);
|
|
607 |
return NULL;
|
|
611 |
so = socreate(slirp);
|
|
612 |
if (!so) {
|
|
613 |
return NULL;
|
|
608 | 614 |
} |
609 | 615 |
so->s = socket(AF_INET,SOCK_DGRAM,0); |
610 | 616 |
so->so_expire = curtime + SO_EXPIRE; |
611 |
insque(so,&udb);
|
|
617 |
insque(so, &slirp->udb);
|
|
612 | 618 |
|
613 | 619 |
addr.sin_family = AF_INET; |
614 | 620 |
addr.sin_addr.s_addr = haddr; |
... | ... | |
624 | 630 |
so->so_fport = addr.sin_port; |
625 | 631 |
if (addr.sin_addr.s_addr == 0 || |
626 | 632 |
addr.sin_addr.s_addr == loopback_addr.s_addr) { |
627 |
so->so_faddr = vhost_addr; |
|
633 |
so->so_faddr = slirp->vhost_addr;
|
|
628 | 634 |
} else { |
629 | 635 |
so->so_faddr = addr.sin_addr; |
630 | 636 |
} |
Also available in: Unified diff