blob: b739320b44f1034d2f0a93a91792f31ab5932300 [file] [log] [blame]
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001/*
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 */
24#include "qemu-common.h"
David 'Digit' Turnere7216d82013-12-15 00:51:13 +010025#include "sysemu/char.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070026#include "slirp.h"
27#include "proxy_common.h"
28#include "hw/hw.h"
29
30#include "android/utils/debug.h" /* for dprint */
31#include "android/utils/bufprint.h"
32#include "android/android.h"
David 'Digit' Turnercc330d42013-12-14 23:26:42 +010033#include "android/sockets.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070034
David 'Digit' Turner031d6552013-12-15 00:52:36 +010035#include "qemu/queue.h"
rich cannings7339b552011-02-16 13:43:44 -080036
37/* proto types */
38static void slirp_net_forward_init(void);
39
40
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070041#define D(...) VERBOSE_PRINT(slirp,__VA_ARGS__)
42#define DN(...) do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)
43
44/* host address */
45uint32_t our_addr_ip;
46/* host dns address */
47uint32_t dns_addr[DNS_ADDR_MAX];
48int dns_addr_count;
49
50/* host loopback address */
51uint32_t loopback_addr_ip;
52
53/* address for slirp virtual addresses */
54uint32_t special_addr_ip;
55
56/* virtual address alias for host */
57uint32_t alias_addr_ip;
58
59static const uint8_t special_ethaddr[6] = {
60 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
61};
62
63/* ARP cache for the guest IP addresses (XXX: allow many entries) */
64uint8_t client_ethaddr[6];
65static ipaddr_t client_ip;
66
67static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
68
69const char *slirp_special_ip = CTL_SPECIAL;
70int slirp_restrict;
71static int do_slowtimo;
72int link_up;
73struct timeval tt;
74FILE *lfd;
75struct ex_list *exec_list;
76
77/* XXX: suppress those select globals */
78fd_set *global_readfds, *global_writefds, *global_xfds;
79
80char slirp_hostname[33];
81
82int slirp_add_dns_server(const SockAddress* new_dns_addr)
83{
84 int dns_ip;
85
86 if (dns_addr_count >= DNS_ADDR_MAX)
87 return -1;
88
89 dns_ip = sock_address_get_ip(new_dns_addr);
rich canningsf06d4c72011-02-09 13:24:37 -080090 if (dns_ip == -1)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070091 return -1;
92
93 dns_addr[dns_addr_count++] = dns_ip;
94 return 0;
95}
96
97
98#ifdef _WIN32
99
100int slirp_get_system_dns_servers(void)
101{
102 FIXED_INFO *FixedInfo=NULL;
103 ULONG BufLen;
104 DWORD ret;
105 IP_ADDR_STRING *pIPAddr;
106
107 if (dns_addr_count > 0)
108 return dns_addr_count;
109
110 FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
111 BufLen = sizeof(FIXED_INFO);
112
113 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) {
114 if (FixedInfo) {
115 GlobalFree(FixedInfo);
116 FixedInfo = NULL;
117 }
118 FixedInfo = GlobalAlloc(GPTR, BufLen);
119 }
120
121 if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) {
122 printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret );
123 if (FixedInfo) {
124 GlobalFree(FixedInfo);
125 FixedInfo = NULL;
126 }
127 return -1;
128 }
129
130 D( "DNS Servers:");
131 pIPAddr = &(FixedInfo->DnsServerList);
132 while (pIPAddr && dns_addr_count < DNS_ADDR_MAX) {
133 uint32_t ip;
134 D( " %s", pIPAddr->IpAddress.String );
135 if (inet_strtoip(pIPAddr->IpAddress.String, &ip) == 0) {
136 if (ip == loopback_addr_ip)
137 ip = our_addr_ip;
138 if (dns_addr_count < DNS_ADDR_MAX)
139 dns_addr[dns_addr_count++] = ip;
140 }
141 pIPAddr = pIPAddr->Next;
142 }
143
144 if (FixedInfo) {
145 GlobalFree(FixedInfo);
146 FixedInfo = NULL;
147 }
148 if (dns_addr_count <= 0)
149 return -1;
150
151 return dns_addr_count;
152}
153
154#else
155
156int slirp_get_system_dns_servers(void)
157{
158 char buff[512];
159 char buff2[257];
160 FILE *f;
161
162 if (dns_addr_count > 0)
163 return dns_addr_count;
164
165#ifdef CONFIG_DARWIN
166 /* on Darwin /etc/resolv.conf is a symlink to /private/var/run/resolv.conf
167 * in some siutations, the symlink can be destroyed and the system will not
168 * re-create it. Darwin-aware applications will continue to run, but "legacy"
169 * Unix ones will not.
170 */
171 f = fopen("/private/var/run/resolv.conf", "r");
172 if (!f)
173 f = fopen("/etc/resolv.conf", "r"); /* desperate attempt to sanity */
174#else
175 f = fopen("/etc/resolv.conf", "r");
176#endif
177 if (!f)
178 return -1;
179
180 DN("emulator: IP address of your DNS(s): ");
181 while (fgets(buff, 512, f) != NULL) {
182 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
183 uint32_t tmp_ip;
184
185 if (inet_strtoip(buff2, &tmp_ip) < 0)
186 continue;
187 if (tmp_ip == loopback_addr_ip)
188 tmp_ip = our_addr_ip;
189 if (dns_addr_count < DNS_ADDR_MAX) {
190 dns_addr[dns_addr_count++] = tmp_ip;
191 if (dns_addr_count > 1)
192 DN(", ");
193 DN("%s", inet_iptostr(tmp_ip));
194 } else {
195 DN("(more)");
196 break;
197 }
198 }
199 }
200 DN("\n");
201 fclose(f);
202
203 if (!dns_addr_count)
204 return -1;
205
206 return dns_addr_count;
207}
208
209#endif
210
211static void slirp_state_save(QEMUFile *f, void *opaque);
212static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
213
214void slirp_init(int restricted, const char *special_ip)
215{
216#if DEBUG
217 int slirp_logmask = 0;
218 char slirp_logfile[512];
219 {
220 const char* env = getenv( "ANDROID_SLIRP_LOGMASK" );
221 if (env != NULL)
222 slirp_logmask = atoi(env);
223 else if (VERBOSE_CHECK(slirp))
224 slirp_logmask = DEBUG_DEFAULT;
225 }
226
227 {
228 char* p = slirp_logfile;
229 char* end = p + sizeof(slirp_logfile);
230
231 p = bufprint_temp_file( p, end, "slirp.log" );
232 if (p >= end) {
233 dprint( "cannot create slirp log file in temporary directory" );
234 slirp_logmask = 0;
235 }
236 }
237 if (slirp_logmask) {
238 dprint( "sending slirp logs with mask %x to %s", slirp_logmask, slirp_logfile );
239 debug_init( slirp_logfile, slirp_logmask );
240 }
241#endif
242
243 link_up = 1;
244 slirp_restrict = restricted;
245
246 if_init();
247 ip_init();
248
249 /* Initialise mbufs *after* setting the MTU */
250 m_init();
251
252 /* set default addresses */
253 inet_strtoip("127.0.0.1", &loopback_addr_ip);
254
255 if (dns_addr_count == 0) {
256 if (slirp_get_system_dns_servers() < 0) {
257 dns_addr[0] = loopback_addr_ip;
258 dns_addr_count = 1;
259 fprintf (stderr, "Warning: No DNS servers found\n");
260 }
261 }
262
263 inet_strtoip(CTL_SPECIAL, &special_addr_ip);
264
265 alias_addr_ip = special_addr_ip | CTL_ALIAS;
266 getouraddr();
David 'Digit' Turner5cb5c0b2014-02-17 16:04:03 +0100267 register_savevm(NULL, "slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
rich cannings7339b552011-02-16 13:43:44 -0800268
269 slirp_net_forward_init();
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700270}
271
272#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
273#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
274#define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
275
276/*
277 * curtime kept to an accuracy of 1ms
278 */
279#ifdef _WIN32
280static void updtime(void)
281{
282 struct _timeb tb;
283
284 _ftime(&tb);
285 curtime = (u_int)tb.time * (u_int)1000;
286 curtime += (u_int)tb.millitm;
287}
288#else
289static void updtime(void)
290{
291 gettimeofday(&tt, NULL);
292
293 curtime = (u_int)tt.tv_sec * (u_int)1000;
294 curtime += (u_int)tt.tv_usec / (u_int)1000;
295
296 if ((tt.tv_usec % 1000) >= 500)
297 curtime++;
298}
299#endif
300
301void slirp_select_fill(int *pnfds,
302 fd_set *readfds, fd_set *writefds, fd_set *xfds)
303{
304 struct socket *so, *so_next;
305 struct timeval timeout;
306 int nfds;
307 int tmp_time;
308
309 /* fail safe */
310 global_readfds = NULL;
311 global_writefds = NULL;
312 global_xfds = NULL;
313
314 nfds = *pnfds;
315 /*
316 * First, TCP sockets
317 */
318 do_slowtimo = 0;
319 if (link_up) {
320 /*
321 * *_slowtimo needs calling if there are IP fragments
322 * in the fragment queue, or there are TCP connections active
323 */
324 do_slowtimo = ((tcb.so_next != &tcb) ||
325 (&ipq.ip_link != ipq.ip_link.next));
326
327 for (so = tcb.so_next; so != &tcb; so = so_next) {
328 so_next = so->so_next;
329
330 /*
331 * See if we need a tcp_fasttimo
332 */
333 if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
334 time_fasttimo = curtime; /* Flag when we want a fasttimo */
335
336 /*
337 * NOFDREF can include still connecting to local-host,
338 * newly socreated() sockets etc. Don't want to select these.
339 */
340 if (so->so_state & SS_NOFDREF || so->s == -1)
341 continue;
342
343 /*
344 * don't register proxified socked connections here
345 */
346 if ((so->so_state & SS_PROXIFIED) != 0)
347 continue;
348
349 /*
350 * Set for reading sockets which are accepting
351 */
352 if (so->so_state & SS_FACCEPTCONN) {
353 FD_SET(so->s, readfds);
354 UPD_NFDS(so->s);
355 continue;
356 }
357
358 /*
359 * Set for writing sockets which are connecting
360 */
361 if (so->so_state & SS_ISFCONNECTING) {
362 FD_SET(so->s, writefds);
363 UPD_NFDS(so->s);
364 continue;
365 }
366
367 /*
368 * Set for writing if we are connected, can send more, and
369 * we have something to send
370 */
371 if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) {
372 FD_SET(so->s, writefds);
373 UPD_NFDS(so->s);
374 }
375
376 /*
377 * Set for reading (and urgent data) if we are connected, can
378 * receive more, and we have room for it XXX /2 ?
379 */
380 if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) {
381 FD_SET(so->s, readfds);
382 FD_SET(so->s, xfds);
383 UPD_NFDS(so->s);
384 }
385 }
386
387 /*
388 * UDP sockets
389 */
390 for (so = udb.so_next; so != &udb; so = so_next) {
391 so_next = so->so_next;
392
393 if ((so->so_state & SS_PROXIFIED) != 0)
394 continue;
395
396 /*
397 * See if it's timed out
398 */
399 if (so->so_expire) {
400 if (so->so_expire <= curtime) {
401 udp_detach(so);
402 continue;
403 } else
404 do_slowtimo = 1; /* Let socket expire */
405 }
406
407 /*
408 * When UDP packets are received from over the
409 * link, they're sendto()'d straight away, so
410 * no need for setting for writing
411 * Limit the number of packets queued by this session
412 * to 4. Note that even though we try and limit this
413 * to 4 packets, the session could have more queued
414 * if the packets needed to be fragmented
415 * (XXX <= 4 ?)
416 */
417 if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) {
418 FD_SET(so->s, readfds);
419 UPD_NFDS(so->s);
420 }
421 }
422 }
423
424 /*
425 * Setup timeout to use minimum CPU usage, especially when idle
426 */
427
428 /*
429 * First, see the timeout needed by *timo
430 */
431 timeout.tv_sec = 0;
432 timeout.tv_usec = -1;
433 /*
434 * If a slowtimo is needed, set timeout to 500ms from the last
435 * slow timeout. If a fast timeout is needed, set timeout within
436 * 200ms of when it was requested.
437 */
438 if (do_slowtimo) {
439 /* XXX + 10000 because some select()'s aren't that accurate */
440 timeout.tv_usec = ((500 - (curtime - last_slowtimo)) * 1000) + 10000;
441 if (timeout.tv_usec < 0)
442 timeout.tv_usec = 0;
443 else if (timeout.tv_usec > 510000)
444 timeout.tv_usec = 510000;
445
446 /* Can only fasttimo if we also slowtimo */
447 if (time_fasttimo) {
448 tmp_time = (200 - (curtime - time_fasttimo)) * 1000;
449 if (tmp_time < 0)
450 tmp_time = 0;
451
452 /* Choose the smallest of the 2 */
453 if (tmp_time < timeout.tv_usec)
454 timeout.tv_usec = (u_int)tmp_time;
455 }
456 }
457 /*
458 * now, the proxified sockets
459 */
460 proxy_manager_select_fill(&nfds, readfds, writefds, xfds);
461
462 *pnfds = nfds;
463}
464
465void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds)
466{
467 struct socket *so, *so_next;
468 int ret;
469
470 global_readfds = readfds;
471 global_writefds = writefds;
472 global_xfds = xfds;
473
474 /* Update time */
475 updtime();
476
477 /*
478 * See if anything has timed out
479 */
480 if (link_up) {
481 if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {
482 tcp_fasttimo();
483 time_fasttimo = 0;
484 }
485 if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {
486 ip_slowtimo();
487 tcp_slowtimo();
488 last_slowtimo = curtime;
489 }
490 }
491
492 /*
493 * Check sockets
494 */
495 if (link_up) {
496 /*
497 * Check TCP sockets
498 */
499 for (so = tcb.so_next; so != &tcb; so = so_next) {
500 so_next = so->so_next;
501
502 /*
503 * FD_ISSET is meaningless on these sockets
504 * (and they can crash the program)
505 */
506 if (so->so_state & SS_NOFDREF || so->s == -1)
507 continue;
508
509 /*
510 * proxified sockets are polled later in this
511 * function.
512 */
513 if ((so->so_state & SS_PROXIFIED) != 0)
514 continue;
515
516 /*
517 * Check for URG data
518 * This will soread as well, so no need to
519 * test for readfds below if this succeeds
520 */
521 if (FD_ISSET(so->s, xfds))
522 sorecvoob(so);
523 /*
524 * Check sockets for reading
525 */
526 else if (FD_ISSET(so->s, readfds)) {
527 /*
528 * Check for incoming connections
529 */
530 if (so->so_state & SS_FACCEPTCONN) {
531 tcp_connect(so);
532 continue;
533 } /* else */
534 ret = soread(so);
535
536 /* Output it if we read something */
537 if (ret > 0)
538 tcp_output(sototcpcb(so));
539 }
540
541 /*
542 * Check sockets for writing
543 */
544 if (FD_ISSET(so->s, writefds)) {
545 /*
546 * Check for non-blocking, still-connecting sockets
547 */
548 if (so->so_state & SS_ISFCONNECTING) {
549 /* Connected */
550 so->so_state &= ~SS_ISFCONNECTING;
551
552 ret = socket_send(so->s, (const void *)&ret, 0);
553 if (ret < 0) {
554 /* XXXXX Must fix, zero bytes is a NOP */
555 if (errno == EAGAIN || errno == EWOULDBLOCK ||
556 errno == EINPROGRESS || errno == ENOTCONN)
557 continue;
558
559 /* else failed */
560 so->so_state = SS_NOFDREF;
561 }
562 /* else so->so_state &= ~SS_ISFCONNECTING; */
563
564 /*
565 * Continue tcp_input
566 */
567 tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
568 /* continue; */
569 } else
570 ret = sowrite(so);
571 /*
572 * XXXXX If we wrote something (a lot), there
573 * could be a need for a window update.
574 * In the worst case, the remote will send
575 * a window probe to get things going again
576 */
577 }
578
579 /*
580 * Probe a still-connecting, non-blocking socket
581 * to check if it's still alive
582 */
583#ifdef PROBE_CONN
584 if (so->so_state & SS_ISFCONNECTING) {
585 ret = socket_recv(so->s, (char *)&ret, 0);
586
587 if (ret < 0) {
588 /* XXX */
589 if (errno == EAGAIN || errno == EWOULDBLOCK ||
590 errno == EINPROGRESS || errno == ENOTCONN)
591 continue; /* Still connecting, continue */
592
593 /* else failed */
594 so->so_state = SS_NOFDREF;
595
596 /* tcp_input will take care of it */
597 } else {
598 ret = socket_send(so->s, &ret, 0);
599 if (ret < 0) {
600 /* XXX */
601 if (errno == EAGAIN || errno == EWOULDBLOCK ||
602 errno == EINPROGRESS || errno == ENOTCONN)
603 continue;
604 /* else failed */
605 so->so_state = SS_NOFDREF;
606 } else
607 so->so_state &= ~SS_ISFCONNECTING;
608
609 }
610 tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
611 } /* SS_ISFCONNECTING */
612#endif
613 }
614
615 /*
616 * Now UDP sockets.
617 * Incoming packets are sent straight away, they're not buffered.
618 * Incoming UDP data isn't buffered either.
619 */
620 for (so = udb.so_next; so != &udb; so = so_next) {
621 so_next = so->so_next;
622
623 if ((so->so_state & SS_PROXIFIED) != 0)
624 continue;
625
626 if (so->s != -1 && FD_ISSET(so->s, readfds)) {
627 sorecvfrom(so);
628 }
629 }
630 }
631
632 /*
633 * Now the proxified sockets
634 */
635 proxy_manager_poll(readfds, writefds, xfds);
636
637 /*
638 * See if we can start outputting
639 */
640 if (if_queued && link_up)
641 if_start();
642
643 /* clear global file descriptor sets.
644 * these reside on the stack in vl.c
645 * so they're unusable if we're not in
646 * slirp_select_fill or slirp_select_poll.
647 */
648 global_readfds = NULL;
649 global_writefds = NULL;
650 global_xfds = NULL;
651}
652
653#define ETH_ALEN 6
654#define ETH_HLEN 14
655
656#define ETH_P_IP 0x0800 /* Internet Protocol packet */
657#define ETH_P_ARP 0x0806 /* Address Resolution packet */
658
659#define ARPOP_REQUEST 1 /* ARP request */
660#define ARPOP_REPLY 2 /* ARP reply */
661
662struct ethhdr
663{
664 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
665 unsigned char h_source[ETH_ALEN]; /* source ether addr */
666 unsigned short h_proto; /* packet type ID field */
667};
668
669struct arphdr
670{
671 unsigned short ar_hrd; /* format of hardware address */
672 unsigned short ar_pro; /* format of protocol address */
673 unsigned char ar_hln; /* length of hardware address */
674 unsigned char ar_pln; /* length of protocol address */
675 unsigned short ar_op; /* ARP opcode (command) */
676
677 /*
678 * Ethernet looks like this : This bit is variable sized however...
679 */
680 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
681 unsigned char ar_sip[4]; /* sender IP address */
682 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
683 unsigned char ar_tip[4]; /* target IP address */
684};
685
686static void arp_input(const uint8_t *pkt, int pkt_len)
687{
688 struct ethhdr *eh = (struct ethhdr *)pkt;
689 struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
690 uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
691 struct ethhdr *reh = (struct ethhdr *)arp_reply;
692 struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
693 int ar_op;
694 struct ex_list *ex_ptr;
695
696 ar_op = ntohs(ah->ar_op);
697 switch(ar_op) {
698 uint32_t ar_tip_ip;
699
700 case ARPOP_REQUEST:
701 ar_tip_ip = ip_read32h(ah->ar_tip);
702 if ((ar_tip_ip & 0xffffff00) == special_addr_ip) {
703 uint32_t ar_tip_low = ar_tip_ip & 0xff;
704 if ( CTL_IS_DNS(ar_tip_low) || ar_tip_low == CTL_ALIAS)
705 goto arp_ok;
706 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
707 if (ex_ptr->ex_addr == ar_tip_low)
708 goto arp_ok;
709 }
710 return;
711 arp_ok:
712 /* XXX: make an ARP request to have the client address */
713 memcpy(client_ethaddr, eh->h_source, ETH_ALEN);
714
715 /* ARP request for alias/dns mac address */
716 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
717 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
718 reh->h_source[5] = ar_tip_low;
719 reh->h_proto = htons(ETH_P_ARP);
720
721 rah->ar_hrd = htons(1);
722 rah->ar_pro = htons(ETH_P_IP);
723 rah->ar_hln = ETH_ALEN;
724 rah->ar_pln = 4;
725 rah->ar_op = htons(ARPOP_REPLY);
726 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
727 memcpy(rah->ar_sip, ah->ar_tip, 4);
728 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
729 memcpy(rah->ar_tip, ah->ar_sip, 4);
730 slirp_output(arp_reply, sizeof(arp_reply));
731 }
732 break;
733 case ARPOP_REPLY:
734 /* reply to request of client mac address ? */
735 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
736 ip_equal( ip_read(ah->ar_sip), client_ip )) {
737 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
738 }
739 break;
740 default:
741 break;
742 }
743}
744
745void slirp_input(const uint8_t *pkt, int pkt_len)
746{
747 struct mbuf *m;
748 int proto;
749
750 if (pkt_len < ETH_HLEN)
751 return;
752
753 proto = ntohs(*(uint16_t *)(pkt + 12));
754 switch(proto) {
755 case ETH_P_ARP:
756 arp_input(pkt, pkt_len);
757 break;
758 case ETH_P_IP:
759 m = m_get();
760 if (!m)
761 return;
762 /* Note: we add to align the IP header */
763 if (M_FREEROOM(m) < pkt_len + 2) {
764 m_inc(m, pkt_len + 2);
765 }
766 m->m_len = pkt_len + 2;
767 memcpy(m->m_data + 2, pkt, pkt_len);
768
769 m->m_data += 2 + ETH_HLEN;
770 m->m_len -= 2 + ETH_HLEN;
771
772 ip_input(m);
773 break;
774 default:
775 break;
776 }
777}
778
779/* output the IP packet to the ethernet device */
780void if_encap(const uint8_t *ip_data, int ip_data_len)
781{
782 uint8_t buf[1600];
783 struct ethhdr *eh = (struct ethhdr *)buf;
784
785 if (ip_data_len + ETH_HLEN > sizeof(buf))
786 return;
787
788 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
789 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
790 struct ethhdr *reh = (struct ethhdr *)arp_req;
791 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
792 const struct ip *iph = (const struct ip *)ip_data;
793
794 /* If the client addr is not known, there is no point in
795 sending the packet to it. Normally the sender should have
796 done an ARP request to get its MAC address. Here we do it
797 in place of sending the packet and we hope that the sender
798 will retry sending its packet. */
799 memset(reh->h_dest, 0xff, ETH_ALEN);
800 memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
801 reh->h_source[5] = CTL_ALIAS;
802 reh->h_proto = htons(ETH_P_ARP);
803 rah->ar_hrd = htons(1);
804 rah->ar_pro = htons(ETH_P_IP);
805 rah->ar_hln = ETH_ALEN;
806 rah->ar_pln = 4;
807 rah->ar_op = htons(ARPOP_REQUEST);
808 /* source hw addr */
809 memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
810 rah->ar_sha[5] = CTL_ALIAS;
811 /* source IP */
812 ip_write32h(alias_addr_ip, rah->ar_sip);
813 /* target hw addr (none) */
814 memset(rah->ar_tha, 0, ETH_ALEN);
815 /* target IP */
816 ip_write( iph->ip_dst, rah->ar_tip );
817 client_ip = iph->ip_dst;
818 slirp_output(arp_req, sizeof(arp_req));
819 } else {
820 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
821 memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
822 /* XXX: not correct */
823 eh->h_source[5] = CTL_ALIAS;
824 eh->h_proto = htons(ETH_P_IP);
825 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
826 slirp_output(buf, ip_data_len + ETH_HLEN);
827 }
828}
829
rich cannings7339b552011-02-16 13:43:44 -0800830
831/*---------------------------------------------------*/
832/* User mode network stack restrictions */
833struct fw_allow_entry {
834 struct fw_allow_entry* next;
835 unsigned long dst_addr; /* host byte order */
836 /* Allowed port range. dst_lport should be the same as dst_hport for a
837 * single port. */
838 unsigned short dst_lport; /* host byte order */
839 unsigned short dst_hport; /* host byte order */
840};
841
842static int drop_udp = 0;
843static int drop_tcp = 0;
844static struct fw_allow_entry* allow_tcp_entries = NULL;
845static struct fw_allow_entry* allow_udp_entries = NULL;
846static FILE* drop_log_fd = NULL;
847static FILE* dns_log_fd = NULL;
848static int max_dns_conns = -1; /* unlimited max DNS connections by default */
849static int slirp_net_forward_inited = 0;
850
851void slirp_drop_udp() {
852 drop_udp = 1;
853}
854
855void slirp_drop_tcp() {
856 drop_tcp = 1;
857}
858
859/* TCP traffic forwarding to a sink - If enabled, all TCP traffic to any
860 * ip/port that is not explicitly forwared using '-net-forward', and which would
861 * otherwise be dropped if '-drop-tcp' has been specified, is redirected to the
862 * specified ip:port
863 */
864int forward_dropped_tcp2sink = 0;
865static unsigned long tcp_sink_ip;
866int tcp_sink_port;
867
868void slirp_forward_dropped_tcp2sink(unsigned long sink_ip, int sink_port) {
869 tcp_sink_ip = sink_ip;
870 tcp_sink_port = sink_port;
871 forward_dropped_tcp2sink = 1;
872}
873
874int slirp_should_forward_dropped_tcp2sink() {
875 return forward_dropped_tcp2sink;
876}
877
878unsigned long slirp_get_tcp_sink_ip() {
879 return tcp_sink_ip;
880}
881int slirp_get_tcp_sink_port() {
882 return tcp_sink_port;
883}
884
885/* Fill in the firewall rules. dst_lport and dst_hport are in host byte order */
886void slirp_add_allow(unsigned long dst_addr,
887 int dst_lport, int dst_hport,
888 u_int8_t proto) {
889
890 struct fw_allow_entry** ate;
891 switch (proto) {
892 case IPPROTO_TCP:
893 ate = &allow_tcp_entries;
894 break;
895 case IPPROTO_UDP:
896 ate = &allow_udp_entries;
897 break;
898 default:
899 return; // unknown protocol for the FW
900 }
901
902 while(*ate != NULL)
903 ate = &(*ate)->next;
904
905 *ate = malloc(sizeof(**ate));
906 if (*ate == NULL) {
907 DEBUG_MISC((dfd,
908 "Unable to create new firewall record, malloc failed\n"));
909 exit(-1);
910 }
911
912 (*ate)->next = NULL;
913 (*ate)->dst_addr = dst_addr;
914 (*ate)->dst_lport = dst_lport;
915 (*ate)->dst_hport = dst_hport;
916}
917
918void slirp_drop_log_fd(FILE* fd) {
919 drop_log_fd = fd;
920}
921
922void slirp_dns_log_fd(FILE* fd) {
923 dns_log_fd = fd;
924}
925
rich canningsd952f282011-03-01 15:40:09 -0800926FILE* get_slirp_drop_log_fd(void) {
927 return drop_log_fd;
928}
929
930FILE* get_slirp_dns_log_fd(void) {
931 return dns_log_fd;
932}
933
rich cannings7339b552011-02-16 13:43:44 -0800934/* Address and ports are in host byte order */
935int slirp_should_drop(unsigned long dst_addr,
936 int dst_port,
937 u_int8_t proto) {
938
939 struct fw_allow_entry* ate;
940
941 switch (proto) {
942 case IPPROTO_TCP:
943 if (drop_tcp != 0)
944 ate = allow_tcp_entries;
945 else
946 return 0;
947 break;
948 case IPPROTO_UDP:
949 if (drop_udp != 0)
950 ate = allow_udp_entries;
951 else
952 return 0;
953 break;
954 default:
955 return 1; // unknown protocol for the FW
956 }
957
958 while(ate) {
959 if ((ate->dst_lport <= dst_port) && (dst_port <= ate->dst_hport)) {
960 // allow any destination if 0
961 if (ate->dst_addr == 0 || ate->dst_addr == dst_addr)
962 return 0;
963 }
964 ate = ate->next;
965 }
966
967 return 1;
968}
969
970/*
971 * log DNS requests in a separate log
972 */
973int
974slirp_log_dns(struct mbuf* m, int dropped) {
975 char dns_query[256]; // max allowable dns name size
976 int c = 0;
977 int i= 0;
978 int index = 0;
979 int offset = 40 + 1; // udp/ip headers length + 1;
980 int trim_bytes = 4;
981
982 if (!dns_log_fd)
983 return -1;
984
985 /* We assume one DNS name per query: 300 = 255 (max dns name length)
986 * + 40 (udp/ip hdr) + 1 byte DNS peamble + 4 bytes DNS suffix
987 */
988 if (m->m_len < offset || m->m_len > 300) {
989 DEBUG_MISC((dfd,"Malformed DNS qeury, length %d \n", (int)m->m_len));
990 return -1;
991 }
992 for (i = offset; i < m->m_len - trim_bytes && index < sizeof(dns_query); i++, index++) {
993 c = m->m_data[i];
994 if (c < ' ' || c > '~')
995 c = '.';
996
997 dns_query[index] = (char)c;
998 }
999 dns_query[index] = '\0';
1000 if (!dropped) {
1001 fprintf(dns_log_fd, "Sent DNS query for, %s\n" , dns_query);
1002 } else {
1003 fprintf(dns_log_fd, "Dropped DNS query for, %s\n" , dns_query);
1004 }
1005 fflush(dns_log_fd);
1006 return 1;
1007}
1008
1009/*
1010 * log DNS requests in a separate log
1011 */
1012int
1013slirp_dump_dns(struct mbuf* m) {
1014
1015 if (!dns_log_fd)
1016 return 0;
1017 // first we write the length of the record then the record (IP packet)
1018 if (!fwrite(&(m->m_len), sizeof(int), 1, dns_log_fd) ||
1019 !fwrite(m->m_data, m->m_len, 1, dns_log_fd)) {
1020 return 0;
1021 }
1022
1023 fflush(dns_log_fd);
1024 return 1;
1025}
1026
1027/* Log dropped/accepted packet info */
1028int slirp_drop_log(const char* format, ...) {
1029 va_list args;
1030
1031 if (!drop_log_fd)
1032 return 0;
1033
1034 va_start(args, format);
1035 vfprintf(drop_log_fd, format, args);
1036 va_end(args);
1037
1038 fflush(drop_log_fd);
1039
1040 return 1;
1041}
1042
1043
1044/* Set max DNS requests allowed to be issued from the VM */
1045void slirp_set_max_dns_conns(int num_conns) {
1046 max_dns_conns = num_conns;
1047}
1048
1049int slirp_get_max_dns_conns() {
1050 return max_dns_conns;
1051}
1052
1053/* generic guest network redirection functionality for ipv4 */
1054struct net_forward_entry {
1055 QTAILQ_ENTRY(net_forward_entry) next;
1056 /* ip addresses are also in host byte order */
1057 unsigned long dest_ip; /* the destination address they try to contact */
1058 unsigned long dest_mask; /* the mask to apply to the address for matching */
1059 /* Range of ports they were trying to contact. In case of a single port,
1060 * dest_lport should be the same as dest_hport */
1061 int dest_lport; /* Host byte order */
1062 int dest_hport; /* Host byte order */
1063
1064 unsigned long redirect_ip;
1065 int redirect_port; /* Host byte order */
1066};
1067
1068static QTAILQ_HEAD(net_forwardq, net_forward_entry) net_forwards;
1069
1070static void slirp_net_forward_init(void)
1071{
1072 if (!slirp_net_forward_inited) {
1073 QTAILQ_INIT(&net_forwards);
1074 slirp_net_forward_inited = 1;
1075 }
1076}
1077
1078/* all addresses and ports ae in host byte order */
1079void slirp_add_net_forward(unsigned long dest_ip, unsigned long dest_mask,
1080 int dest_lport, int dest_hport,
1081 unsigned long redirect_ip, int redirect_port)
1082{
1083 slirp_net_forward_init();
1084
1085 struct net_forward_entry *entry = malloc(sizeof(*entry));
1086 if (entry == NULL) {
1087 DEBUG_MISC((dfd, "Unable to create new forwarding entry, malloc failed\n"));
1088 exit(-1);
1089 }
1090
1091 entry->dest_ip = dest_ip;
1092 entry->dest_mask = dest_mask;
1093 entry->dest_lport = dest_lport;
1094 entry->dest_hport = dest_hport;
1095 entry->redirect_ip = redirect_ip;
1096 entry->redirect_port = redirect_port;
1097
1098 QTAILQ_INSERT_TAIL(&net_forwards, entry, next);
1099}
1100
1101/* remote_port and redir_port arguments
1102 * are in network byte order (tcp_subr.c) */
1103int slirp_should_net_forward(unsigned long remote_ip, int remote_port,
1104 unsigned long *redirect_ip, int *redirect_port)
1105{
1106 struct net_forward_entry *entry;
1107
1108 for (entry = net_forwards.tqh_first;
1109 entry != NULL; entry = entry->next.tqe_next) {
1110
1111 if ((entry->dest_lport <= remote_port)
1112 && (remote_port <= entry->dest_hport)) {
1113 if ((entry->dest_ip & entry->dest_mask)
1114 == (remote_ip & entry->dest_mask)) {
1115 *redirect_ip = entry->redirect_ip;
1116 *redirect_port = entry->redirect_port;
1117 return 1;
1118 }
1119 }
1120 }
1121
1122 return 0;
1123}
1124
1125/*---------------------------------------------------*/
1126
1127
1128
1129
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001130static void _slirp_redir_loop(void (*func)(void *opaque, int is_udp,
1131 const SockAddress *laddr,
1132 const SockAddress *faddr),
1133 void *opaque, int is_udp)
1134{
1135 struct socket *head = (is_udp ? &udb : &tcb);
1136 struct socket *so;
1137
1138 for (so = head->so_next; so != head; so = so->so_next) {
1139 SockAddress local, foreign;
David 'Digit' Turnerc0052462014-02-25 18:39:29 +01001140
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001141 sock_address_init_inet(&local, so->so_laddr_ip, so->so_laddr_port);
1142 sock_address_init_inet(&foreign, so->so_faddr_ip, so->so_faddr_port);
1143 func(opaque, is_udp,
1144 &local, &foreign);
1145 }
1146}
1147
1148void slirp_redir_loop(void (*func)(void *opaque, int is_udp,
1149 const SockAddress *laddr,
1150 const SockAddress *faddr),
1151 void *opaque)
1152{
1153 _slirp_redir_loop(func, opaque, 0);
1154 _slirp_redir_loop(func, opaque, 1);
1155}
1156
1157/* Unlistens a redirection
1158 *
1159 * Return value: number of redirs removed */
1160int slirp_redir_rm(int is_udp, int host_port)
1161{
1162 struct socket *so;
1163 struct socket *head = (is_udp ? &udb : &tcb);
1164 int n = 0;
1165
1166 loop_again:
1167 for (so = head->so_next; so != head; so = so->so_next) {
1168 if (so->so_faddr_port == host_port) {
1169 close(so->s);
1170 sofree(so);
1171 n++;
1172 goto loop_again;
1173 }
1174 }
1175
1176 return n;
1177}
1178
1179int slirp_redir(int is_udp, int host_port,
1180 uint32_t guest_ip, int guest_port)
1181{
1182 if (is_udp) {
1183 if (!udp_listen(host_port,
1184 guest_ip,
1185 guest_port, 0))
1186 return -1;
1187 } else {
1188 if (!solisten(host_port, guest_ip, guest_port, 0))
1189 return -1;
1190 }
1191 return 0;
1192}
1193
1194int slirp_unredir(int is_udp, int host_port)
1195{
1196 if (is_udp)
1197 return udp_unlisten( host_port );
1198 else
1199 return sounlisten( host_port );
1200}
1201
1202int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
1203 int guest_port)
1204{
1205 return add_exec(&exec_list, do_pty, (char *)args,
1206 addr_low_byte, htons(guest_port));
1207}
1208
1209ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
1210{
1211 if (so->s == -1 && so->extra) {
1212 qemu_chr_write(so->extra, buf, len);
1213 return len;
1214 }
1215
1216 return send(so->s, buf, len, flags);
1217}
1218
1219static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
1220{
1221 struct socket *so;
1222
1223 for (so = tcb.so_next; so != &tcb; so = so->so_next) {
1224 if ((so->so_faddr_ip & 0xffffff00) ==
1225 special_addr_ip
1226 && ((so->so_faddr_port & 0xff) ==
1227 addr_low_byte)
1228 && so->so_faddr_port == guest_port)
1229 return so;
1230 }
1231
1232 return NULL;
1233}
1234
1235size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
1236{
1237 struct iovec iov[2];
1238 struct socket *so;
1239
1240 if (!link_up)
1241 return 0;
1242
1243 so = slirp_find_ctl_socket(addr_low_byte, guest_port);
1244
1245 if (!so || so->so_state & SS_NOFDREF)
1246 return 0;
1247
1248 if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
1249 return 0;
1250
1251 return sopreprbuf(so, iov, NULL);
1252}
1253
1254void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
1255 int size)
1256{
1257 int ret;
1258 struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
David 'Digit' Turnerc0052462014-02-25 18:39:29 +01001259
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001260 if (!so)
1261 return;
1262
1263 ret = soreadbuf(so, (const char *)buf, size);
1264
1265 if (ret > 0)
1266 tcp_output(sototcpcb(so));
1267}
1268
1269static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
1270{
1271 int i;
1272
1273 qemu_put_sbe16(f, tp->t_state);
1274 for (i = 0; i < TCPT_NTIMERS; i++)
1275 qemu_put_sbe16(f, tp->t_timer[i]);
1276 qemu_put_sbe16(f, tp->t_rxtshift);
1277 qemu_put_sbe16(f, tp->t_rxtcur);
1278 qemu_put_sbe16(f, tp->t_dupacks);
1279 qemu_put_be16(f, tp->t_maxseg);
1280 qemu_put_sbyte(f, tp->t_force);
1281 qemu_put_be16(f, tp->t_flags);
1282 qemu_put_be32(f, tp->snd_una);
1283 qemu_put_be32(f, tp->snd_nxt);
1284 qemu_put_be32(f, tp->snd_up);
1285 qemu_put_be32(f, tp->snd_wl1);
1286 qemu_put_be32(f, tp->snd_wl2);
1287 qemu_put_be32(f, tp->iss);
1288 qemu_put_be32(f, tp->snd_wnd);
1289 qemu_put_be32(f, tp->rcv_wnd);
1290 qemu_put_be32(f, tp->rcv_nxt);
1291 qemu_put_be32(f, tp->rcv_up);
1292 qemu_put_be32(f, tp->irs);
1293 qemu_put_be32(f, tp->rcv_adv);
1294 qemu_put_be32(f, tp->snd_max);
1295 qemu_put_be32(f, tp->snd_cwnd);
1296 qemu_put_be32(f, tp->snd_ssthresh);
1297 qemu_put_sbe16(f, tp->t_idle);
1298 qemu_put_sbe16(f, tp->t_rtt);
1299 qemu_put_be32(f, tp->t_rtseq);
1300 qemu_put_sbe16(f, tp->t_srtt);
1301 qemu_put_sbe16(f, tp->t_rttvar);
1302 qemu_put_be16(f, tp->t_rttmin);
1303 qemu_put_be32(f, tp->max_sndwnd);
1304 qemu_put_byte(f, tp->t_oobflags);
1305 qemu_put_byte(f, tp->t_iobc);
1306 qemu_put_sbe16(f, tp->t_softerror);
1307 qemu_put_byte(f, tp->snd_scale);
1308 qemu_put_byte(f, tp->rcv_scale);
1309 qemu_put_byte(f, tp->request_r_scale);
1310 qemu_put_byte(f, tp->requested_s_scale);
1311 qemu_put_be32(f, tp->ts_recent);
1312 qemu_put_be32(f, tp->ts_recent_age);
1313 qemu_put_be32(f, tp->last_ack_sent);
1314}
1315
1316static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
1317{
1318 uint32_t off;
1319
1320 qemu_put_be32(f, sbuf->sb_cc);
1321 qemu_put_be32(f, sbuf->sb_datalen);
1322 off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
1323 qemu_put_sbe32(f, off);
1324 off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
1325 qemu_put_sbe32(f, off);
1326 qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1327}
1328
1329static void slirp_socket_save(QEMUFile *f, struct socket *so)
1330{
1331 qemu_put_be32(f, so->so_urgc);
1332 qemu_put_be32(f, so->so_faddr_ip);
1333 qemu_put_be32(f, so->so_laddr_ip);
1334 qemu_put_be16(f, so->so_faddr_port);
1335 qemu_put_be16(f, so->so_laddr_port);
1336 qemu_put_byte(f, so->so_iptos);
1337 qemu_put_byte(f, so->so_emu);
1338 qemu_put_byte(f, so->so_type);
1339 qemu_put_be32(f, so->so_state);
1340 slirp_sbuf_save(f, &so->so_rcv);
1341 slirp_sbuf_save(f, &so->so_snd);
1342 slirp_tcp_save(f, so->so_tcpcb);
1343}
1344
1345static void slirp_state_save(QEMUFile *f, void *opaque)
1346{
1347 struct ex_list *ex_ptr;
1348
1349 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1350 if (ex_ptr->ex_pty == 3) {
1351 struct socket *so;
1352 so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
1353 if (!so)
1354 continue;
1355
1356 qemu_put_byte(f, 42);
1357 slirp_socket_save(f, so);
1358 }
1359 qemu_put_byte(f, 0);
1360}
1361
1362static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
1363{
1364 int i;
1365
1366 tp->t_state = qemu_get_sbe16(f);
1367 for (i = 0; i < TCPT_NTIMERS; i++)
1368 tp->t_timer[i] = qemu_get_sbe16(f);
1369 tp->t_rxtshift = qemu_get_sbe16(f);
1370 tp->t_rxtcur = qemu_get_sbe16(f);
1371 tp->t_dupacks = qemu_get_sbe16(f);
1372 tp->t_maxseg = qemu_get_be16(f);
1373 tp->t_force = qemu_get_sbyte(f);
1374 tp->t_flags = qemu_get_be16(f);
1375 tp->snd_una = qemu_get_be32(f);
1376 tp->snd_nxt = qemu_get_be32(f);
1377 tp->snd_up = qemu_get_be32(f);
1378 tp->snd_wl1 = qemu_get_be32(f);
1379 tp->snd_wl2 = qemu_get_be32(f);
1380 tp->iss = qemu_get_be32(f);
1381 tp->snd_wnd = qemu_get_be32(f);
1382 tp->rcv_wnd = qemu_get_be32(f);
1383 tp->rcv_nxt = qemu_get_be32(f);
1384 tp->rcv_up = qemu_get_be32(f);
1385 tp->irs = qemu_get_be32(f);
1386 tp->rcv_adv = qemu_get_be32(f);
1387 tp->snd_max = qemu_get_be32(f);
1388 tp->snd_cwnd = qemu_get_be32(f);
1389 tp->snd_ssthresh = qemu_get_be32(f);
1390 tp->t_idle = qemu_get_sbe16(f);
1391 tp->t_rtt = qemu_get_sbe16(f);
1392 tp->t_rtseq = qemu_get_be32(f);
1393 tp->t_srtt = qemu_get_sbe16(f);
1394 tp->t_rttvar = qemu_get_sbe16(f);
1395 tp->t_rttmin = qemu_get_be16(f);
1396 tp->max_sndwnd = qemu_get_be32(f);
1397 tp->t_oobflags = qemu_get_byte(f);
1398 tp->t_iobc = qemu_get_byte(f);
1399 tp->t_softerror = qemu_get_sbe16(f);
1400 tp->snd_scale = qemu_get_byte(f);
1401 tp->rcv_scale = qemu_get_byte(f);
1402 tp->request_r_scale = qemu_get_byte(f);
1403 tp->requested_s_scale = qemu_get_byte(f);
1404 tp->ts_recent = qemu_get_be32(f);
1405 tp->ts_recent_age = qemu_get_be32(f);
1406 tp->last_ack_sent = qemu_get_be32(f);
1407 tcp_template(tp);
1408}
1409
1410static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
1411{
1412 uint32_t off, sb_cc, sb_datalen;
1413
1414 sb_cc = qemu_get_be32(f);
1415 sb_datalen = qemu_get_be32(f);
1416
1417 sbreserve(sbuf, sb_datalen);
1418
1419 if (sbuf->sb_datalen != sb_datalen)
1420 return -ENOMEM;
1421
1422 sbuf->sb_cc = sb_cc;
1423
1424 off = qemu_get_sbe32(f);
1425 sbuf->sb_wptr = sbuf->sb_data + off;
1426 off = qemu_get_sbe32(f);
1427 sbuf->sb_rptr = sbuf->sb_data + off;
1428 qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
1429
1430 return 0;
1431}
1432
1433static int slirp_socket_load(QEMUFile *f, struct socket *so)
1434{
1435 if (tcp_attach(so) < 0)
1436 return -ENOMEM;
1437
1438 so->so_urgc = qemu_get_be32(f);
1439 so->so_faddr_ip = qemu_get_be32(f);
1440 so->so_laddr_ip = qemu_get_be32(f);
1441 so->so_faddr_port = qemu_get_be16(f);
1442 so->so_laddr_port = qemu_get_be16(f);
1443 so->so_iptos = qemu_get_byte(f);
1444 so->so_emu = qemu_get_byte(f);
1445 so->so_type = qemu_get_byte(f);
1446 so->so_state = qemu_get_be32(f);
1447 if (slirp_sbuf_load(f, &so->so_rcv) < 0)
1448 return -ENOMEM;
1449 if (slirp_sbuf_load(f, &so->so_snd) < 0)
1450 return -ENOMEM;
1451 slirp_tcp_load(f, so->so_tcpcb);
1452
1453 return 0;
1454}
1455
1456static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1457{
1458 struct ex_list *ex_ptr;
1459 int r;
1460
1461 while ((r = qemu_get_byte(f))) {
1462 int ret;
1463 struct socket *so = socreate();
1464
1465 if (!so)
1466 return -ENOMEM;
1467
1468 ret = slirp_socket_load(f, so);
1469
1470 if (ret < 0)
1471 return ret;
1472
1473 if ((so->so_faddr_ip & 0xffffff00) != special_addr_ip)
1474 return -EINVAL;
1475
1476 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
1477 if (ex_ptr->ex_pty == 3 &&
1478 (so->so_faddr_ip & 0xff) == ex_ptr->ex_addr &&
1479 so->so_faddr_port == ex_ptr->ex_fport)
1480 break;
1481
1482 if (!ex_ptr)
1483 return -EINVAL;
1484
1485 so->extra = (void *)ex_ptr->ex_exec;
1486 }
1487
1488 return 0;
1489}