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