]> git.proxmox.com Git - mirror_qemu.git/blame - slirp/slirp.c
slirp: Bind support for host forwarding rules
[mirror_qemu.git] / slirp / slirp.c
CommitLineData
d75a0b97
FB
1/*
2 * libslirp glue
3 *
4 * Copyright (c) 2004-2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
e1c5a2b3 24#include "qemu-common.h"
0580ac91 25#include "qemu-char.h"
f0cbd3ec 26#include "slirp.h"
062e5527 27#include "hw/hw.h"
f0cbd3ec
FB
28
29/* host address */
30struct in_addr our_addr;
31/* host dns address */
32struct in_addr dns_addr;
33/* host loopback address */
34struct in_addr loopback_addr;
35
a13a4126
JK
36/* virtual network configuration */
37struct in_addr vnetwork_addr;
38struct in_addr vnetwork_mask;
39struct in_addr vhost_addr;
40struct in_addr vdhcp_startaddr;
41struct in_addr vnameserver_addr;
42
43/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
9634d903 44static const uint8_t special_ethaddr[6] = {
a13a4126 45 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
f0cbd3ec
FB
46};
47
de806f07 48/* ARP cache for the guest IP addresses (XXX: allow many entries) */
f0cbd3ec 49uint8_t client_ethaddr[6];
de806f07
FB
50static struct in_addr client_ipaddr;
51
52static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
f0cbd3ec 53
a9ba3a85 54int slirp_restrict;
511d2b14 55static int do_slowtimo;
f0cbd3ec
FB
56int link_up;
57struct timeval tt;
58FILE *lfd;
a3d4af03 59struct ex_list *exec_list;
f0cbd3ec
FB
60
61/* XXX: suppress those select globals */
62fd_set *global_readfds, *global_writefds, *global_xfds;
63
3f423c9c 64char slirp_hostname[33];
115defd1 65
f0cbd3ec
FB
66#ifdef _WIN32
67
68static int get_dns_addr(struct in_addr *pdns_addr)
69{
379ff53d
FB
70 FIXED_INFO *FixedInfo=NULL;
71 ULONG BufLen;
72 DWORD ret;
73 IP_ADDR_STRING *pIPAddr;
74 struct in_addr tmp_addr;
3b46e624 75
379ff53d
FB
76 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
77 BufLen = sizeof(FIXED_INFO);
3b46e624 78
379ff53d
FB
79 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
80 if (FixedInfo) {
81 GlobalFree(FixedInfo);
82 FixedInfo = NULL;
83 }
84 FixedInfo = GlobalAlloc(GPTR, BufLen);
85 }
5fafdf24 86
379ff53d
FB
87 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
88 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
89 if (FixedInfo) {
90 GlobalFree(FixedInfo);
91 FixedInfo = NULL;
92 }
93 return -1;
94 }
3b46e624 95
379ff53d
FB
96 pIPAddr = &(FixedInfo->DnsServerList);
97 inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
98 *pdns_addr = tmp_addr;
99#if 0
100 printf( "DNS Servers:\n" );
101 printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String );
3b46e624 102
379ff53d
FB
103 pIPAddr = FixedInfo -> DnsServerList.Next;
104 while ( pIPAddr ) {
105 printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String );
106 pIPAddr = pIPAddr ->Next;
107 }
108#endif
109 if (FixedInfo) {
110 GlobalFree(FixedInfo);
111 FixedInfo = NULL;
112 }
113 return 0;
f0cbd3ec
FB
114}
115
116#else
117
118static int get_dns_addr(struct in_addr *pdns_addr)
119{
120 char buff[512];
363a37d5 121 char buff2[257];
f0cbd3ec
FB
122 FILE *f;
123 int found = 0;
124 struct in_addr tmp_addr;
3b46e624 125
f0cbd3ec
FB
126 f = fopen("/etc/resolv.conf", "r");
127 if (!f)
128 return -1;
129
31a60e22 130#ifdef DEBUG
f0cbd3ec 131 lprint("IP address of your DNS(s): ");
31a60e22 132#endif
f0cbd3ec
FB
133 while (fgets(buff, 512, f) != NULL) {
134 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
135 if (!inet_aton(buff2, &tmp_addr))
136 continue;
137 if (tmp_addr.s_addr == loopback_addr.s_addr)
138 tmp_addr = our_addr;
139 /* If it's the first one, set it to dns_addr */
140 if (!found)
141 *pdns_addr = tmp_addr;
31a60e22 142#ifdef DEBUG
f0cbd3ec
FB
143 else
144 lprint(", ");
31a60e22 145#endif
f0cbd3ec 146 if (++found > 3) {
31a60e22 147#ifdef DEBUG
f0cbd3ec 148 lprint("(more)");
31a60e22 149#endif
f0cbd3ec 150 break;
31a60e22
BS
151 }
152#ifdef DEBUG
153 else
f0cbd3ec 154 lprint("%s", inet_ntoa(tmp_addr));
31a60e22 155#endif
f0cbd3ec
FB
156 }
157 }
1d43a717 158 fclose(f);
f0cbd3ec
FB
159 if (!found)
160 return -1;
161 return 0;
162}
163
164#endif
165
379ff53d 166#ifdef _WIN32
9634d903 167static void slirp_cleanup(void)
379ff53d
FB
168{
169 WSACleanup();
170}
171#endif
172
062e5527
AL
173static void slirp_state_save(QEMUFile *f, void *opaque);
174static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
175
c92ef6a2
JK
176void slirp_init(int restricted, struct in_addr vnetwork,
177 struct in_addr vnetmask, struct in_addr vhost,
178 const char *vhostname, const char *tftp_path,
179 const char *bootfile, struct in_addr vdhcp_start,
180 struct in_addr vnameserver)
f0cbd3ec 181{
512176db 182 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
3b46e624 183
379ff53d 184#ifdef _WIN32
a13a4126
JK
185 WSADATA Data;
186
187 WSAStartup(MAKEWORD(2,0), &Data);
188 atexit(slirp_cleanup);
379ff53d
FB
189#endif
190
f0cbd3ec 191 link_up = 1;
511d2b14 192 slirp_restrict = restricted;
f0cbd3ec
FB
193
194 if_init();
195 ip_init();
196
197 /* Initialise mbufs *after* setting the MTU */
198 m_init();
199
200 /* set default addresses */
f0cbd3ec
FB
201 inet_aton("127.0.0.1", &loopback_addr);
202
203 if (get_dns_addr(&dns_addr) < 0) {
0f8134bf
PB
204 dns_addr = loopback_addr;
205 fprintf (stderr, "Warning: No DNS servers found\n");
f0cbd3ec
FB
206 }
207
c92ef6a2
JK
208 vnetwork_addr = vnetwork;
209 vnetwork_mask = vnetmask;
210 vhost_addr = vhost;
211 if (vhostname) {
212 pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);
a13a4126 213 }
ad196a9d
JK
214 qemu_free(tftp_prefix);
215 tftp_prefix = NULL;
216 if (tftp_path) {
217 tftp_prefix = qemu_strdup(tftp_path);
218 }
219 qemu_free(bootp_filename);
220 bootp_filename = NULL;
221 if (bootfile) {
222 bootp_filename = qemu_strdup(bootfile);
223 }
c92ef6a2
JK
224 vdhcp_startaddr = vdhcp_start;
225 vnameserver_addr = vnameserver;
ad196a9d 226
f4e15b4b 227 getouraddr();
062e5527 228 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
f0cbd3ec
FB
229}
230
231#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
232#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
233#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
234
235/*
236 * curtime kept to an accuracy of 1ms
237 */
379ff53d
FB
238#ifdef _WIN32
239static void updtime(void)
240{
241 struct _timeb tb;
242
243 _ftime(&tb);
244 curtime = (u_int)tb.time * (u_int)1000;
245 curtime += (u_int)tb.millitm;
246}
247#else
f0cbd3ec
FB
248static void updtime(void)
249{
511d2b14 250 gettimeofday(&tt, NULL);
5fafdf24 251
f0cbd3ec
FB
252 curtime = (u_int)tt.tv_sec * (u_int)1000;
253 curtime += (u_int)tt.tv_usec / (u_int)1000;
5fafdf24 254
f0cbd3ec
FB
255 if ((tt.tv_usec % 1000) >= 500)
256 curtime++;
257}
379ff53d 258#endif
f0cbd3ec 259
5fafdf24 260void slirp_select_fill(int *pnfds,
f0cbd3ec
FB
261 fd_set *readfds, fd_set *writefds, fd_set *xfds)
262{
263 struct socket *so, *so_next;
264 struct timeval timeout;
265 int nfds;
266 int tmp_time;
267
268 /* fail safe */
269 global_readfds = NULL;
270 global_writefds = NULL;
271 global_xfds = NULL;
3b46e624 272
f0cbd3ec
FB
273 nfds = *pnfds;
274 /*
275 * First, TCP sockets
276 */
277 do_slowtimo = 0;
278 if (link_up) {
5fafdf24 279 /*
f0cbd3ec
FB
280 * *_slowtimo needs calling if there are IP fragments
281 * in the fragment queue, or there are TCP connections active
282 */
283 do_slowtimo = ((tcb.so_next != &tcb) ||
429d0a3d 284 (&ipq.ip_link != ipq.ip_link.next));
3b46e624 285
f0cbd3ec
FB
286 for (so = tcb.so_next; so != &tcb; so = so_next) {
287 so_next = so->so_next;
3b46e624 288
f0cbd3ec
FB
289 /*
290 * See if we need a tcp_fasttimo
291 */
292 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
293 time_fasttimo = curtime; /* Flag when we want a fasttimo */
3b46e624 294
f0cbd3ec
FB
295 /*
296 * NOFDREF can include still connecting to local-host,
297 * newly socreated() sockets etc. Don't want to select these.
298 */
299 if (so->so_state & SS_NOFDREF || so->s == -1)
300 continue;
3b46e624 301
f0cbd3ec
FB
302 /*
303 * Set for reading sockets which are accepting
304 */
305 if (so->so_state & SS_FACCEPTCONN) {
306 FD_SET(so->s, readfds);
307 UPD_NFDS(so->s);
308 continue;
309 }
3b46e624 310
f0cbd3ec
FB
311 /*
312 * Set for writing sockets which are connecting
313 */
314 if (so->so_state & SS_ISFCONNECTING) {
315 FD_SET(so->s, writefds);
316 UPD_NFDS(so->s);
317 continue;
318 }
3b46e624 319
f0cbd3ec
FB
320 /*
321 * Set for writing if we are connected, can send more, and
322 * we have something to send
323 */
324 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
325 FD_SET(so->s, writefds);
326 UPD_NFDS(so->s);
327 }
3b46e624 328
f0cbd3ec
FB
329 /*
330 * Set for reading (and urgent data) if we are connected, can
331 * receive more, and we have room for it XXX /2 ?
332 */
333 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
334 FD_SET(so->s, readfds);
335 FD_SET(so->s, xfds);
336 UPD_NFDS(so->s);
337 }
338 }
3b46e624 339
f0cbd3ec
FB
340 /*
341 * UDP sockets
342 */
343 for (so = udb.so_next; so != &udb; so = so_next) {
344 so_next = so->so_next;
3b46e624 345
f0cbd3ec
FB
346 /*
347 * See if it's timed out
348 */
349 if (so->so_expire) {
350 if (so->so_expire <= curtime) {
351 udp_detach(so);
352 continue;
353 } else
354 do_slowtimo = 1; /* Let socket expire */
355 }
3b46e624 356
f0cbd3ec
FB
357 /*
358 * When UDP packets are received from over the
359 * link, they're sendto()'d straight away, so
360 * no need for setting for writing
361 * Limit the number of packets queued by this session
362 * to 4. Note that even though we try and limit this
363 * to 4 packets, the session could have more queued
364 * if the packets needed to be fragmented
365 * (XXX <= 4 ?)
366 */
367 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
368 FD_SET(so->s, readfds);
369 UPD_NFDS(so->s);
370 }
371 }
372 }
5fafdf24 373
f0cbd3ec
FB
374 /*
375 * Setup timeout to use minimum CPU usage, especially when idle
376 */
5fafdf24
TS
377
378 /*
f0cbd3ec
FB
379 * First, see the timeout needed by *timo
380 */
381 timeout.tv_sec = 0;
382 timeout.tv_usec = -1;
383 /*
384 * If a slowtimo is needed, set timeout to 500ms from the last
385 * slow timeout. If a fast timeout is needed, set timeout within
386 * 200ms of when it was requested.
387 */
388 if (do_slowtimo) {
389 /* XXX + 10000 because some select()'s aren't that accurate */
390 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
391 if (timeout.tv_usec < 0)
392 timeout.tv_usec = 0;
393 else if (timeout.tv_usec > 510000)
394 timeout.tv_usec = 510000;
3b46e624 395
f0cbd3ec
FB
396 /* Can only fasttimo if we also slowtimo */
397 if (time_fasttimo) {
398 tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
399 if (tmp_time < 0)
400 tmp_time = 0;
3b46e624 401
f0cbd3ec
FB
402 /* Choose the smallest of the 2 */
403 if (tmp_time < timeout.tv_usec)
404 timeout.tv_usec = (u_int)tmp_time;
405 }
406 }
407 *pnfds = nfds;
5fafdf24 408}
f0cbd3ec
FB
409
410void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
411{
412 struct socket *so, *so_next;
413 int ret;
414
415 global_readfds = readfds;
416 global_writefds = writefds;
417 global_xfds = xfds;
418
419 /* Update time */
420 updtime();
5fafdf24 421
f0cbd3ec 422 /*
5fafdf24 423 * See if anything has timed out
f0cbd3ec
FB
424 */
425 if (link_up) {
df5f8956 426 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
f0cbd3ec
FB
427 tcp_fasttimo();
428 time_fasttimo = 0;
429 }
430 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
431 ip_slowtimo();
432 tcp_slowtimo();
433 last_slowtimo = curtime;
434 }
435 }
5fafdf24 436
f0cbd3ec
FB
437 /*
438 * Check sockets
439 */
440 if (link_up) {
441 /*
442 * Check TCP sockets
443 */
444 for (so = tcb.so_next; so != &tcb; so = so_next) {
445 so_next = so->so_next;
3b46e624 446
f0cbd3ec
FB
447 /*
448 * FD_ISSET is meaningless on these sockets
449 * (and they can crash the program)
450 */
451 if (so->so_state & SS_NOFDREF || so->s == -1)
452 continue;
3b46e624 453
f0cbd3ec
FB
454 /*
455 * Check for URG data
456 * This will soread as well, so no need to
457 * test for readfds below if this succeeds
458 */
459 if (FD_ISSET(so->s, xfds))
460 sorecvoob(so);
461 /*
462 * Check sockets for reading
463 */
464 else if (FD_ISSET(so->s, readfds)) {
465 /*
466 * Check for incoming connections
467 */
468 if (so->so_state & SS_FACCEPTCONN) {
469 tcp_connect(so);
470 continue;
471 } /* else */
472 ret = soread(so);
3b46e624 473
f0cbd3ec
FB
474 /* Output it if we read something */
475 if (ret > 0)
476 tcp_output(sototcpcb(so));
477 }
3b46e624 478
f0cbd3ec
FB
479 /*
480 * Check sockets for writing
481 */
482 if (FD_ISSET(so->s, writefds)) {
483 /*
484 * Check for non-blocking, still-connecting sockets
485 */
486 if (so->so_state & SS_ISFCONNECTING) {
487 /* Connected */
488 so->so_state &= ~SS_ISFCONNECTING;
3b46e624 489
0a656f5f 490 ret = send(so->s, (const void *) &ret, 0, 0);
f0cbd3ec
FB
491 if (ret < 0) {
492 /* XXXXX Must fix, zero bytes is a NOP */
493 if (errno == EAGAIN || errno == EWOULDBLOCK ||
494 errno == EINPROGRESS || errno == ENOTCONN)
495 continue;
3b46e624 496
f0cbd3ec
FB
497 /* else failed */
498 so->so_state = SS_NOFDREF;
499 }
500 /* else so->so_state &= ~SS_ISFCONNECTING; */
3b46e624 501
f0cbd3ec
FB
502 /*
503 * Continue tcp_input
504 */
505 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
506 /* continue; */
507 } else
508 ret = sowrite(so);
509 /*
5fafdf24 510 * XXXXX If we wrote something (a lot), there
f0cbd3ec
FB
511 * could be a need for a window update.
512 * In the worst case, the remote will send
513 * a window probe to get things going again
514 */
515 }
3b46e624 516
f0cbd3ec
FB
517 /*
518 * Probe a still-connecting, non-blocking socket
519 * to check if it's still alive
520 */
521#ifdef PROBE_CONN
522 if (so->so_state & SS_ISFCONNECTING) {
02d2c54c 523 ret = recv(so->s, (char *)&ret, 0,0);
3b46e624 524
f0cbd3ec
FB
525 if (ret < 0) {
526 /* XXX */
527 if (errno == EAGAIN || errno == EWOULDBLOCK ||
528 errno == EINPROGRESS || errno == ENOTCONN)
529 continue; /* Still connecting, continue */
3b46e624 530
f0cbd3ec
FB
531 /* else failed */
532 so->so_state = SS_NOFDREF;
3b46e624 533
f0cbd3ec
FB
534 /* tcp_input will take care of it */
535 } else {
02d2c54c 536 ret = send(so->s, &ret, 0,0);
f0cbd3ec
FB
537 if (ret < 0) {
538 /* XXX */
539 if (errno == EAGAIN || errno == EWOULDBLOCK ||
540 errno == EINPROGRESS || errno == ENOTCONN)
541 continue;
542 /* else failed */
543 so->so_state = SS_NOFDREF;
544 } else
545 so->so_state &= ~SS_ISFCONNECTING;
3b46e624 546
f0cbd3ec
FB
547 }
548 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
549 } /* SS_ISFCONNECTING */
550#endif
551 }
3b46e624 552
f0cbd3ec
FB
553 /*
554 * Now UDP sockets.
555 * Incoming packets are sent straight away, they're not buffered.
556 * Incoming UDP data isn't buffered either.
557 */
558 for (so = udb.so_next; so != &udb; so = so_next) {
559 so_next = so->so_next;
3b46e624 560
f0cbd3ec
FB
561 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
562 sorecvfrom(so);
563 }
564 }
565 }
5fafdf24 566
f0cbd3ec
FB
567 /*
568 * See if we can start outputting
569 */
570 if (if_queued && link_up)
571 if_start();
02d2c54c
FB
572
573 /* clear global file descriptor sets.
574 * these reside on the stack in vl.c
575 * so they're unusable if we're not in
576 * slirp_select_fill or slirp_select_poll.
577 */
578 global_readfds = NULL;
579 global_writefds = NULL;
580 global_xfds = NULL;
f0cbd3ec
FB
581}
582
583#define ETH_ALEN 6
584#define ETH_HLEN 14
585
586#define ETH_P_IP 0x0800 /* Internet Protocol packet */
587#define ETH_P_ARP 0x0806 /* Address Resolution packet */
588
589#define ARPOP_REQUEST 1 /* ARP request */
590#define ARPOP_REPLY 2 /* ARP reply */
591
5fafdf24 592struct ethhdr
f0cbd3ec
FB
593{
594 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
595 unsigned char h_source[ETH_ALEN]; /* source ether addr */
596 unsigned short h_proto; /* packet type ID field */
597};
598
599struct arphdr
600{
601 unsigned short ar_hrd; /* format of hardware address */
602 unsigned short ar_pro; /* format of protocol address */
603 unsigned char ar_hln; /* length of hardware address */
604 unsigned char ar_pln; /* length of protocol address */
605 unsigned short ar_op; /* ARP opcode (command) */
606
607 /*
608 * Ethernet looks like this : This bit is variable sized however...
609 */
610 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
a13a4126 611 uint32_t ar_sip; /* sender IP address */
f0cbd3ec 612 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
a13a4126
JK
613 uint32_t ar_tip ; /* target IP address */
614} __attribute__((packed));
f0cbd3ec 615
8fcd3692 616static void arp_input(const uint8_t *pkt, int pkt_len)
f0cbd3ec
FB
617{
618 struct ethhdr *eh = (struct ethhdr *)pkt;
619 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
620 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
621 struct ethhdr *reh = (struct ethhdr *)arp_reply;
622 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
623 int ar_op;
a3d4af03 624 struct ex_list *ex_ptr;
f0cbd3ec
FB
625
626 ar_op = ntohs(ah->ar_op);
627 switch(ar_op) {
628 case ARPOP_REQUEST:
a13a4126
JK
629 if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
630 if (ah->ar_tip == vnameserver_addr.s_addr ||
631 ah->ar_tip == vhost_addr.s_addr)
a3d4af03
FB
632 goto arp_ok;
633 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
a13a4126 634 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
a3d4af03
FB
635 goto arp_ok;
636 }
637 return;
638 arp_ok:
f0cbd3ec
FB
639 /* XXX: make an ARP request to have the client address */
640 memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
641
642 /* ARP request for alias/dns mac address */
643 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
a13a4126
JK
644 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
645 memcpy(&reh->h_source[2], &ah->ar_tip, 4);
f0cbd3ec
FB
646 reh->h_proto = htons(ETH_P_ARP);
647
648 rah->ar_hrd = htons(1);
649 rah->ar_pro = htons(ETH_P_IP);
650 rah->ar_hln = ETH_ALEN;
651 rah->ar_pln = 4;
652 rah->ar_op = htons(ARPOP_REPLY);
653 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
a13a4126 654 rah->ar_sip = ah->ar_tip;
f0cbd3ec 655 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
a13a4126 656 rah->ar_tip = ah->ar_sip;
f0cbd3ec
FB
657 slirp_output(arp_reply, sizeof(arp_reply));
658 }
659 break;
de806f07
FB
660 case ARPOP_REPLY:
661 /* reply to request of client mac address ? */
662 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
a13a4126 663 ah->ar_sip == client_ipaddr.s_addr) {
de806f07
FB
664 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
665 }
666 break;
f0cbd3ec
FB
667 default:
668 break;
669 }
670}
671
672void slirp_input(const uint8_t *pkt, int pkt_len)
673{
674 struct mbuf *m;
675 int proto;
676
677 if (pkt_len < ETH_HLEN)
678 return;
3b46e624 679
f0cbd3ec
FB
680 proto = ntohs(*(uint16_t *)(pkt + 12));
681 switch(proto) {
682 case ETH_P_ARP:
683 arp_input(pkt, pkt_len);
684 break;
685 case ETH_P_IP:
686 m = m_get();
687 if (!m)
688 return;
38f3e7c2 689 /* Note: we add to align the IP header */
e8e880a7
AJ
690 if (M_FREEROOM(m) < pkt_len + 2) {
691 m_inc(m, pkt_len + 2);
692 }
38f3e7c2
FB
693 m->m_len = pkt_len + 2;
694 memcpy(m->m_data + 2, pkt, pkt_len);
f0cbd3ec 695
38f3e7c2
FB
696 m->m_data += 2 + ETH_HLEN;
697 m->m_len -= 2 + ETH_HLEN;
f0cbd3ec
FB
698
699 ip_input(m);
700 break;
701 default:
702 break;
703 }
704}
705
706/* output the IP packet to the ethernet device */
707void if_encap(const uint8_t *ip_data, int ip_data_len)
708{
709 uint8_t buf[1600];
710 struct ethhdr *eh = (struct ethhdr *)buf;
711
712 if (ip_data_len + ETH_HLEN > sizeof(buf))
713 return;
de806f07
FB
714
715 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
716 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
717 struct ethhdr *reh = (struct ethhdr *)arp_req;
718 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
719 const struct ip *iph = (const struct ip *)ip_data;
720
721 /* If the client addr is not known, there is no point in
722 sending the packet to it. Normally the sender should have
723 done an ARP request to get its MAC address. Here we do it
724 in place of sending the packet and we hope that the sender
725 will retry sending its packet. */
726 memset(reh->h_dest, 0xff, ETH_ALEN);
a13a4126
JK
727 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
728 memcpy(&reh->h_source[2], &vhost_addr, 4);
de806f07
FB
729 reh->h_proto = htons(ETH_P_ARP);
730 rah->ar_hrd = htons(1);
731 rah->ar_pro = htons(ETH_P_IP);
732 rah->ar_hln = ETH_ALEN;
733 rah->ar_pln = 4;
734 rah->ar_op = htons(ARPOP_REQUEST);
735 /* source hw addr */
a13a4126
JK
736 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
737 memcpy(&rah->ar_sha[2], &vhost_addr, 4);
de806f07 738 /* source IP */
a13a4126 739 rah->ar_sip = vhost_addr.s_addr;
de806f07
FB
740 /* target hw addr (none) */
741 memset(rah->ar_tha, 0, ETH_ALEN);
742 /* target IP */
a13a4126 743 rah->ar_tip = iph->ip_dst.s_addr;
de806f07
FB
744 client_ipaddr = iph->ip_dst;
745 slirp_output(arp_req, sizeof(arp_req));
746 } else {
747 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
a13a4126 748 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
de806f07 749 /* XXX: not correct */
a13a4126 750 memcpy(&eh->h_source[2], &vhost_addr, 4);
de806f07
FB
751 eh->h_proto = htons(ETH_P_IP);
752 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
753 slirp_output(buf, ip_data_len + ETH_HLEN);
754 }
f0cbd3ec 755}
9bf05444 756
c1261d8d
AG
757/* Unlistens a redirection
758 *
759 * Return value: number of redirs removed */
3c6a0580 760int slirp_remove_hostfwd(int is_udp, struct in_addr host_addr, int host_port)
c1261d8d
AG
761{
762 struct socket *so;
763 struct socket *head = (is_udp ? &udb : &tcb);
2ad82cf9
JK
764 struct sockaddr_in addr;
765 int port = htons(host_port);
766 socklen_t addr_len;
c1261d8d
AG
767 int n = 0;
768
769 loop_again:
770 for (so = head->so_next; so != head; so = so->so_next) {
2ad82cf9
JK
771 addr_len = sizeof(addr);
772 if (getsockname(so->s, (struct sockaddr *)&addr, &addr_len) == 0 &&
3c6a0580 773 addr.sin_addr.s_addr == host_addr.s_addr &&
2ad82cf9 774 addr.sin_port == port) {
c1261d8d
AG
775 close(so->s);
776 sofree(so);
777 n++;
778 goto loop_again;
779 }
780 }
781
782 return n;
783}
784
3c6a0580 785int slirp_add_hostfwd(int is_udp, struct in_addr host_addr, int host_port,
c92ef6a2 786 struct in_addr guest_addr, int guest_port)
9bf05444 787{
a13a4126
JK
788 if (!guest_addr.s_addr) {
789 guest_addr = vdhcp_startaddr;
790 }
9bf05444 791 if (is_udp) {
3c6a0580 792 if (!udp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
9bf05444
FB
793 htons(guest_port), 0))
794 return -1;
795 } else {
3c6a0580
JK
796 if (!tcp_listen(host_addr.s_addr, htons(host_port), guest_addr.s_addr,
797 htons(guest_port), 0))
9bf05444
FB
798 return -1;
799 }
800 return 0;
801}
a3d4af03 802
c92ef6a2
JK
803int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
804 int guest_port)
a3d4af03 805{
c92ef6a2
JK
806 if (!guest_addr.s_addr) {
807 guest_addr.s_addr =
808 vnetwork_addr.s_addr | (htonl(0x0204) & ~vnetwork_mask.s_addr);
809 }
a13a4126
JK
810 if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
811 guest_addr.s_addr == vhost_addr.s_addr ||
812 guest_addr.s_addr == vnameserver_addr.s_addr) {
813 return -1;
814 }
815 return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
816 htons(guest_port));
a3d4af03 817}
e1c5a2b3
AL
818
819ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
820{
821 if (so->s == -1 && so->extra) {
822 qemu_chr_write(so->extra, buf, len);
823 return len;
824 }
825
826 return send(so->s, buf, len, flags);
827}
828
a13a4126
JK
829static struct socket *
830slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
e1c5a2b3 831{
a13a4126 832 struct socket *so;
e1c5a2b3 833
a13a4126
JK
834 for (so = tcb.so_next; so != &tcb; so = so->so_next) {
835 if (so->so_faddr.s_addr == guest_addr.s_addr &&
836 htons(so->so_fport) == guest_port) {
837 return so;
838 }
839 }
840 return NULL;
e1c5a2b3
AL
841}
842
c92ef6a2 843size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
e1c5a2b3
AL
844{
845 struct iovec iov[2];
846 struct socket *so;
847
848 if (!link_up)
849 return 0;
850
a13a4126 851 so = slirp_find_ctl_socket(guest_addr, guest_port);
e1c5a2b3
AL
852
853 if (!so || so->so_state & SS_NOFDREF)
854 return 0;
855
856 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
857 return 0;
858
859 return sopreprbuf(so, iov, NULL);
860}
861
c92ef6a2
JK
862void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
863 const uint8_t *buf, int size)
e1c5a2b3
AL
864{
865 int ret;
a13a4126
JK
866 struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
867
e1c5a2b3
AL
868 if (!so)
869 return;
870
0580ac91 871 ret = soreadbuf(so, (const char *)buf, size);
e1c5a2b3
AL
872
873 if (ret > 0)
874 tcp_output(sototcpcb(so));
875}
062e5527
AL
876
877static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
878{
879 int i;
880
881 qemu_put_sbe16(f, tp->t_state);
882 for (i = 0; i < TCPT_NTIMERS; i++)
883 qemu_put_sbe16(f, tp->t_timer[i]);
884 qemu_put_sbe16(f, tp->t_rxtshift);
885 qemu_put_sbe16(f, tp->t_rxtcur);
886 qemu_put_sbe16(f, tp->t_dupacks);
887 qemu_put_be16(f, tp->t_maxseg);
888 qemu_put_sbyte(f, tp->t_force);
889 qemu_put_be16(f, tp->t_flags);
890 qemu_put_be32(f, tp->snd_una);
891 qemu_put_be32(f, tp->snd_nxt);
892 qemu_put_be32(f, tp->snd_up);
893 qemu_put_be32(f, tp->snd_wl1);
894 qemu_put_be32(f, tp->snd_wl2);
895 qemu_put_be32(f, tp->iss);
896 qemu_put_be32(f, tp->snd_wnd);
897 qemu_put_be32(f, tp->rcv_wnd);
898 qemu_put_be32(f, tp->rcv_nxt);
899 qemu_put_be32(f, tp->rcv_up);
900 qemu_put_be32(f, tp->irs);
901 qemu_put_be32(f, tp->rcv_adv);
902 qemu_put_be32(f, tp->snd_max);
903 qemu_put_be32(f, tp->snd_cwnd);
904 qemu_put_be32(f, tp->snd_ssthresh);
905 qemu_put_sbe16(f, tp->t_idle);
906 qemu_put_sbe16(f, tp->t_rtt);
907 qemu_put_be32(f, tp->t_rtseq);
908 qemu_put_sbe16(f, tp->t_srtt);
909 qemu_put_sbe16(f, tp->t_rttvar);
910 qemu_put_be16(f, tp->t_rttmin);
911 qemu_put_be32(f, tp->max_sndwnd);
912 qemu_put_byte(f, tp->t_oobflags);
913 qemu_put_byte(f, tp->t_iobc);
914 qemu_put_sbe16(f, tp->t_softerror);
915 qemu_put_byte(f, tp->snd_scale);
916 qemu_put_byte(f, tp->rcv_scale);
917 qemu_put_byte(f, tp->request_r_scale);
918 qemu_put_byte(f, tp->requested_s_scale);
919 qemu_put_be32(f, tp->ts_recent);
920 qemu_put_be32(f, tp->ts_recent_age);
921 qemu_put_be32(f, tp->last_ack_sent);
922}
923
924static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
925{
926 uint32_t off;
927
928 qemu_put_be32(f, sbuf->sb_cc);
929 qemu_put_be32(f, sbuf->sb_datalen);
930 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
931 qemu_put_sbe32(f, off);
932 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
933 qemu_put_sbe32(f, off);
934 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
935}
936
937static void slirp_socket_save(QEMUFile *f, struct socket *so)
938{
939 qemu_put_be32(f, so->so_urgc);
940 qemu_put_be32(f, so->so_faddr.s_addr);
941 qemu_put_be32(f, so->so_laddr.s_addr);
942 qemu_put_be16(f, so->so_fport);
943 qemu_put_be16(f, so->so_lport);
944 qemu_put_byte(f, so->so_iptos);
945 qemu_put_byte(f, so->so_emu);
946 qemu_put_byte(f, so->so_type);
947 qemu_put_be32(f, so->so_state);
948 slirp_sbuf_save(f, &so->so_rcv);
949 slirp_sbuf_save(f, &so->so_snd);
950 slirp_tcp_save(f, so->so_tcpcb);
951}
952
953static void slirp_state_save(QEMUFile *f, void *opaque)
954{
955 struct ex_list *ex_ptr;
956
957 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
958 if (ex_ptr->ex_pty == 3) {
959 struct socket *so;
960 so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
961 if (!so)
962 continue;
963
964 qemu_put_byte(f, 42);
965 slirp_socket_save(f, so);
966 }
967 qemu_put_byte(f, 0);
968}
969
970static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
971{
972 int i;
973
974 tp->t_state = qemu_get_sbe16(f);
975 for (i = 0; i < TCPT_NTIMERS; i++)
976 tp->t_timer[i] = qemu_get_sbe16(f);
977 tp->t_rxtshift = qemu_get_sbe16(f);
978 tp->t_rxtcur = qemu_get_sbe16(f);
979 tp->t_dupacks = qemu_get_sbe16(f);
980 tp->t_maxseg = qemu_get_be16(f);
981 tp->t_force = qemu_get_sbyte(f);
982 tp->t_flags = qemu_get_be16(f);
983 tp->snd_una = qemu_get_be32(f);
984 tp->snd_nxt = qemu_get_be32(f);
985 tp->snd_up = qemu_get_be32(f);
986 tp->snd_wl1 = qemu_get_be32(f);
987 tp->snd_wl2 = qemu_get_be32(f);
988 tp->iss = qemu_get_be32(f);
989 tp->snd_wnd = qemu_get_be32(f);
990 tp->rcv_wnd = qemu_get_be32(f);
991 tp->rcv_nxt = qemu_get_be32(f);
992 tp->rcv_up = qemu_get_be32(f);
993 tp->irs = qemu_get_be32(f);
994 tp->rcv_adv = qemu_get_be32(f);
995 tp->snd_max = qemu_get_be32(f);
996 tp->snd_cwnd = qemu_get_be32(f);
997 tp->snd_ssthresh = qemu_get_be32(f);
998 tp->t_idle = qemu_get_sbe16(f);
999 tp->t_rtt = qemu_get_sbe16(f);
1000 tp->t_rtseq = qemu_get_be32(f);
1001 tp->t_srtt = qemu_get_sbe16(f);
1002 tp->t_rttvar = qemu_get_sbe16(f);
1003 tp->t_rttmin = qemu_get_be16(f);
1004 tp->max_sndwnd = qemu_get_be32(f);
1005 tp->t_oobflags = qemu_get_byte(f);
1006 tp->t_iobc = qemu_get_byte(f);
1007 tp->t_softerror = qemu_get_sbe16(f);
1008 tp->snd_scale = qemu_get_byte(f);
1009 tp->rcv_scale = qemu_get_byte(f);
1010 tp->request_r_scale = qemu_get_byte(f);
1011 tp->requested_s_scale = qemu_get_byte(f);
1012 tp->ts_recent = qemu_get_be32(f);
1013 tp->ts_recent_age = qemu_get_be32(f);
1014 tp->last_ack_sent = qemu_get_be32(f);
1015 tcp_template(tp);
1016}
1017
1018static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1019{
1020 uint32_t off, sb_cc, sb_datalen;
1021
1022 sb_cc = qemu_get_be32(f);
1023 sb_datalen = qemu_get_be32(f);
1024
1025 sbreserve(sbuf, sb_datalen);
1026
1027 if (sbuf->sb_datalen != sb_datalen)
1028 return -ENOMEM;
1029
1030 sbuf->sb_cc = sb_cc;
1031
1032 off = qemu_get_sbe32(f);
1033 sbuf->sb_wptr = sbuf->sb_data + off;
1034 off = qemu_get_sbe32(f);
1035 sbuf->sb_rptr = sbuf->sb_data + off;
1036 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1037
1038 return 0;
1039}
1040
1041static int slirp_socket_load(QEMUFile *f, struct socket *so)
1042{
1043 if (tcp_attach(so) < 0)
1044 return -ENOMEM;
1045
1046 so->so_urgc = qemu_get_be32(f);
1047 so->so_faddr.s_addr = qemu_get_be32(f);
1048 so->so_laddr.s_addr = qemu_get_be32(f);
1049 so->so_fport = qemu_get_be16(f);
1050 so->so_lport = qemu_get_be16(f);
1051 so->so_iptos = qemu_get_byte(f);
1052 so->so_emu = qemu_get_byte(f);
1053 so->so_type = qemu_get_byte(f);
1054 so->so_state = qemu_get_be32(f);
1055 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1056 return -ENOMEM;
1057 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1058 return -ENOMEM;
1059 slirp_tcp_load(f, so->so_tcpcb);
1060
1061 return 0;
1062}
1063
1064static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1065{
1066 struct ex_list *ex_ptr;
1067 int r;
1068
1069 while ((r = qemu_get_byte(f))) {
1070 int ret;
1071 struct socket *so = socreate();
1072
1073 if (!so)
1074 return -ENOMEM;
1075
1076 ret = slirp_socket_load(f, so);
1077
1078 if (ret < 0)
1079 return ret;
1080
a13a4126
JK
1081 if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
1082 vnetwork_addr.s_addr) {
062e5527 1083 return -EINVAL;
a13a4126
JK
1084 }
1085 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
062e5527 1086 if (ex_ptr->ex_pty == 3 &&
a13a4126
JK
1087 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
1088 so->so_fport == ex_ptr->ex_fport) {
062e5527 1089 break;
a13a4126
JK
1090 }
1091 }
062e5527
AL
1092 if (!ex_ptr)
1093 return -EINVAL;
1094
0580ac91 1095 so->extra = (void *)ex_ptr->ex_exec;
062e5527
AL
1096 }
1097
1098 return 0;
1099}