• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
24 #include "qemu-common.h"
25 #include "qemu-char.h"
26 #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"
33 #include "sockets.h"
34 
35 #include "qemu-queue.h"
36 
37 /* proto types */
38 static void slirp_net_forward_init(void);
39 
40 
41 #define  D(...)   VERBOSE_PRINT(slirp,__VA_ARGS__)
42 #define  DN(...)  do { if (VERBOSE_CHECK(slirp)) dprintn(__VA_ARGS__); } while (0)
43 
44 /* host address */
45 uint32_t our_addr_ip;
46 /* host dns address */
47 uint32_t dns_addr[DNS_ADDR_MAX];
48 int      dns_addr_count;
49 
50 /* host loopback address */
51 uint32_t loopback_addr_ip;
52 
53 /* address for slirp virtual addresses */
54 uint32_t  special_addr_ip;
55 
56 /* virtual address alias for host */
57 uint32_t alias_addr_ip;
58 
59 static 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) */
64 uint8_t client_ethaddr[6];
65 static ipaddr_t  client_ip;
66 
67 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
68 
69 const char *slirp_special_ip = CTL_SPECIAL;
70 int slirp_restrict;
71 static int do_slowtimo;
72 int link_up;
73 struct timeval tt;
74 FILE *lfd;
75 struct ex_list *exec_list;
76 
77 /* XXX: suppress those select globals */
78 fd_set *global_readfds, *global_writefds, *global_xfds;
79 
80 char slirp_hostname[33];
81 
slirp_add_dns_server(const SockAddress * new_dns_addr)82 int 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);
90     if (dns_ip == -1)
91         return -1;
92 
93     dns_addr[dns_addr_count++] = dns_ip;
94     return 0;
95 }
96 
97 
98 #ifdef _WIN32
99 
slirp_get_system_dns_servers(void)100 int 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 
slirp_get_system_dns_servers(void)156 int 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 
211 static void slirp_state_save(QEMUFile *f, void *opaque);
212 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
213 
slirp_init(int restricted,const char * special_ip)214 void 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();
267     register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
268 
269     slirp_net_forward_init();
270 }
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
updtime(void)280 static 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
updtime(void)289 static 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 
slirp_select_fill(int * pnfds,fd_set * readfds,fd_set * writefds,fd_set * xfds)301 void 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 
slirp_select_poll(fd_set * readfds,fd_set * writefds,fd_set * xfds)465 void 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 
662 struct 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 
669 struct 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 
arp_input(const uint8_t * pkt,int pkt_len)686 static 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 
slirp_input(const uint8_t * pkt,int pkt_len)745 void 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 */
if_encap(const uint8_t * ip_data,int ip_data_len)780 void 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 
830 
831 /*---------------------------------------------------*/
832 /* User mode network stack restrictions */
833 struct 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 
842 static int drop_udp = 0;
843 static int drop_tcp = 0;
844 static struct fw_allow_entry* allow_tcp_entries = NULL;
845 static struct fw_allow_entry* allow_udp_entries = NULL;
846 static FILE* drop_log_fd = NULL;
847 static FILE* dns_log_fd = NULL;
848 static int max_dns_conns = -1;   /* unlimited max DNS connections by default */
849 static int slirp_net_forward_inited = 0;
850 
slirp_drop_udp()851 void slirp_drop_udp() {
852     drop_udp = 1;
853 }
854 
slirp_drop_tcp()855 void 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  */
864 int forward_dropped_tcp2sink = 0;
865 static unsigned long tcp_sink_ip;
866 int tcp_sink_port;
867 
slirp_forward_dropped_tcp2sink(unsigned long sink_ip,int sink_port)868 void 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 
slirp_should_forward_dropped_tcp2sink()874 int slirp_should_forward_dropped_tcp2sink() {
875     return forward_dropped_tcp2sink;
876 }
877 
slirp_get_tcp_sink_ip()878 unsigned long slirp_get_tcp_sink_ip() {
879     return tcp_sink_ip;
880 }
slirp_get_tcp_sink_port()881 int 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 */
slirp_add_allow(unsigned long dst_addr,int dst_lport,int dst_hport,u_int8_t proto)886 void 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 
slirp_drop_log_fd(FILE * fd)918 void slirp_drop_log_fd(FILE* fd) {
919     drop_log_fd = fd;
920 }
921 
slirp_dns_log_fd(FILE * fd)922 void slirp_dns_log_fd(FILE* fd) {
923     dns_log_fd = fd;
924 }
925 
get_slirp_drop_log_fd(void)926 FILE* get_slirp_drop_log_fd(void) {
927   return drop_log_fd;
928 }
929 
get_slirp_dns_log_fd(void)930 FILE* get_slirp_dns_log_fd(void) {
931   return dns_log_fd;
932 }
933 
934 /* Address and ports are in host byte order */
slirp_should_drop(unsigned long dst_addr,int dst_port,u_int8_t proto)935 int 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  */
973 int
slirp_log_dns(struct mbuf * m,int dropped)974 slirp_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  */
1012 int
slirp_dump_dns(struct mbuf * m)1013 slirp_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 */
slirp_drop_log(const char * format,...)1028 int 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 */
slirp_set_max_dns_conns(int num_conns)1045 void slirp_set_max_dns_conns(int num_conns) {
1046     max_dns_conns = num_conns;
1047 }
1048 
slirp_get_max_dns_conns()1049 int slirp_get_max_dns_conns() {
1050     return max_dns_conns;
1051 }
1052 
1053 /* generic guest network redirection functionality for ipv4 */
1054 struct 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 
1068 static QTAILQ_HEAD(net_forwardq, net_forward_entry) net_forwards;
1069 
slirp_net_forward_init(void)1070 static 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 */
slirp_add_net_forward(unsigned long dest_ip,unsigned long dest_mask,int dest_lport,int dest_hport,unsigned long redirect_ip,int redirect_port)1079 void 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) */
slirp_should_net_forward(unsigned long remote_ip,int remote_port,unsigned long * redirect_ip,int * redirect_port)1103 int 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 
_slirp_redir_loop(void (* func)(void * opaque,int is_udp,const SockAddress * laddr,const SockAddress * faddr),void * opaque,int is_udp)1130 static 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;
1140 
1141 		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 
slirp_redir_loop(void (* func)(void * opaque,int is_udp,const SockAddress * laddr,const SockAddress * faddr),void * opaque)1148 void 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 */
slirp_redir_rm(int is_udp,int host_port)1160 int 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 
slirp_redir(int is_udp,int host_port,uint32_t guest_ip,int guest_port)1179 int 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 
slirp_unredir(int is_udp,int host_port)1194 int  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 
slirp_add_exec(int do_pty,const void * args,int addr_low_byte,int guest_port)1202 int 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 
slirp_send(struct socket * so,const void * buf,size_t len,int flags)1209 ssize_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 
slirp_find_ctl_socket(int addr_low_byte,int guest_port)1219 static 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 
slirp_socket_can_recv(int addr_low_byte,int guest_port)1235 size_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 
slirp_socket_recv(int addr_low_byte,int guest_port,const uint8_t * buf,int size)1254 void 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);
1259 
1260     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 
slirp_tcp_save(QEMUFile * f,struct tcpcb * tp)1269 static 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 
slirp_sbuf_save(QEMUFile * f,struct sbuf * sbuf)1316 static 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 
slirp_socket_save(QEMUFile * f,struct socket * so)1329 static 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 
slirp_state_save(QEMUFile * f,void * opaque)1345 static 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 
slirp_tcp_load(QEMUFile * f,struct tcpcb * tp)1362 static 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 
slirp_sbuf_load(QEMUFile * f,struct sbuf * sbuf)1410 static 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 
slirp_socket_load(QEMUFile * f,struct socket * so)1433 static 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 
slirp_state_load(QEMUFile * f,void * opaque,int version_id)1456 static 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 }
1490