Commit a13a4126c8b94355bbe43e47275b97ce5bef003c

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent ad196a9d

slirp: Rework internal configuration

The user mode IP stack is currently only minimally configurable /wrt to
its virtual IP addresses. This is unfortunate if some guest has a fixed
idea of which IP addresses to use.

Therefore this patch prepares the stack for fully configurable IP
addresses and masks. The user interface and default addresses remain
untouched in this step, they will be enhanced in the following patch.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
slirp/bootp.c
... ... @@ -27,8 +27,6 @@
27 27  
28 28 #define NB_ADDR 16
29 29  
30   -#define START_ADDR 15
31   -
32 30 #define LEASE_TIME (24 * 3600)
33 31  
34 32 typedef struct {
... ... @@ -64,7 +62,7 @@ static BOOTPClient *get_new_addr(struct in_addr *paddr,
64 62 found:
65 63 bc = &bootp_clients[i];
66 64 bc->allocated = 1;
67   - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
  65 + paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
68 66 return bc;
69 67 }
70 68  
... ... @@ -72,12 +70,12 @@ static BOOTPClient *request_addr(const struct in_addr *paddr,
72 70 const uint8_t *macaddr)
73 71 {
74 72 uint32_t req_addr = ntohl(paddr->s_addr);
75   - uint32_t spec_addr = ntohl(special_addr.s_addr);
  73 + uint32_t dhcp_addr = ntohl(vdhcp_startaddr.s_addr);
76 74 BOOTPClient *bc;
77 75  
78   - if (req_addr >= (spec_addr | START_ADDR) &&
79   - req_addr < (spec_addr | (NB_ADDR + START_ADDR))) {
80   - bc = &bootp_clients[(req_addr & 0xff) - START_ADDR];
  76 + if (req_addr >= dhcp_addr &&
  77 + req_addr < (dhcp_addr + NB_ADDR)) {
  78 + bc = &bootp_clients[req_addr - dhcp_addr];
81 79 if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) {
82 80 bc->allocated = 1;
83 81 return bc;
... ... @@ -99,7 +97,7 @@ static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
99 97 found:
100 98 bc = &bootp_clients[i];
101 99 bc->allocated = 1;
102   - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
  100 + paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
103 101 return bc;
104 102 }
105 103  
... ... @@ -156,7 +154,6 @@ static void bootp_reply(const struct bootp_t *bp)
156 154 struct mbuf *m;
157 155 struct bootp_t *rbp;
158 156 struct sockaddr_in saddr, daddr;
159   - struct in_addr dns_addr;
160 157 const struct in_addr *preq_addr;
161 158 int dhcp_msg_type, val;
162 159 uint8_t *q;
... ... @@ -218,7 +215,7 @@ static void bootp_reply(const struct bootp_t *bp)
218 215 }
219 216 }
220 217  
221   - saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
  218 + saddr.sin_addr = vhost_addr;
222 219 saddr.sin_port = htons(BOOTP_SERVER);
223 220  
224 221 daddr.sin_port = htons(BOOTP_CLIENT);
... ... @@ -262,10 +259,8 @@ static void bootp_reply(const struct bootp_t *bp)
262 259  
263 260 *q++ = RFC1533_NETMASK;
264 261 *q++ = 4;
265   - *q++ = 0xff;
266   - *q++ = 0xff;
267   - *q++ = 0xff;
268   - *q++ = 0x00;
  262 + memcpy(q, &vnetwork_mask, 4);
  263 + q += 4;
269 264  
270 265 if (!slirp_restrict) {
271 266 *q++ = RFC1533_GATEWAY;
... ... @@ -275,8 +270,7 @@ static void bootp_reply(const struct bootp_t *bp)
275 270  
276 271 *q++ = RFC1533_DNS;
277 272 *q++ = 4;
278   - dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS);
279   - memcpy(q, &dns_addr, 4);
  273 + memcpy(q, &vnameserver_addr, 4);
280 274 q += 4;
281 275 }
282 276  
... ...
slirp/ctl.h deleted 100644 → 0
1   -#define CTL_CMD 0
2   -#define CTL_EXEC 1
3   -#define CTL_ALIAS 2
4   -#define CTL_DNS 3
5   -
6   -#define CTL_SPECIAL "10.0.2.0"
7   -#define CTL_LOCAL "10.0.2.15"
slirp/ip_icmp.c
... ... @@ -110,7 +110,7 @@ icmp_input(struct mbuf *m, int hlen)
110 110 case ICMP_ECHO:
111 111 icp->icmp_type = ICMP_ECHOREPLY;
112 112 ip->ip_len += hlen; /* since ip_input subtracts this */
113   - if (ip->ip_dst.s_addr == alias_addr.s_addr) {
  113 + if (ip->ip_dst.s_addr == vhost_addr.s_addr) {
114 114 icmp_reflect(m);
115 115 } else {
116 116 struct socket *so;
... ... @@ -134,16 +134,13 @@ icmp_input(struct mbuf *m, int hlen)
134 134  
135 135 /* Send the packet */
136 136 addr.sin_family = AF_INET;
137   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
  137 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
  138 + vnetwork_addr.s_addr) {
138 139 /* It's an alias */
139   - switch(ntohl(so->so_faddr.s_addr) & 0xff) {
140   - case CTL_DNS:
  140 + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
141 141 addr.sin_addr = dns_addr;
142   - break;
143   - case CTL_ALIAS:
144   - default:
  142 + } else {
145 143 addr.sin_addr = loopback_addr;
146   - break;
147 144 }
148 145 } else {
149 146 addr.sin_addr = so->so_faddr;
... ... @@ -302,7 +299,7 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
302 299 ip->ip_ttl = MAXTTL;
303 300 ip->ip_p = IPPROTO_ICMP;
304 301 ip->ip_dst = ip->ip_src; /* ip adresses */
305   - ip->ip_src = alias_addr;
  302 + ip->ip_src = vhost_addr;
306 303  
307 304 (void ) ip_output((struct socket *)NULL, m);
308 305  
... ...
slirp/ip_input.c
... ... @@ -134,18 +134,19 @@ ip_input(struct mbuf *m)
134 134 }
135 135  
136 136 if (slirp_restrict) {
137   - if (memcmp(&ip->ip_dst.s_addr, &special_addr, 3)) {
  137 + if ((ip->ip_dst.s_addr & vnetwork_mask.s_addr) ==
  138 + vnetwork_addr.s_addr) {
138 139 if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
139 140 goto bad;
140 141 } else {
141   - int host = ntohl(ip->ip_dst.s_addr) & 0xff;
142 142 struct ex_list *ex_ptr;
143 143  
144   - if (host == 0xff)
  144 + if ((ip->ip_dst.s_addr & ~vnetwork_mask.s_addr) ==
  145 + ~vnetwork_mask.s_addr)
145 146 goto bad;
146 147  
147 148 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
148   - if (ex_ptr->ex_addr == host)
  149 + if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr)
149 150 break;
150 151  
151 152 if (!ex_ptr)
... ...
slirp/main.h
... ... @@ -32,9 +32,11 @@ extern char *slirp_tty;
32 32 extern char *exec_shell;
33 33 extern u_int curtime;
34 34 extern fd_set *global_readfds, *global_writefds, *global_xfds;
35   -extern struct in_addr ctl_addr;
36   -extern struct in_addr special_addr;
37   -extern struct in_addr alias_addr;
  35 +extern struct in_addr vnetwork_addr;
  36 +extern struct in_addr vnetwork_mask;
  37 +extern struct in_addr vhost_addr;
  38 +extern struct in_addr vdhcp_startaddr;
  39 +extern struct in_addr vnameserver_addr;
38 40 extern struct in_addr our_addr;
39 41 extern struct in_addr loopback_addr;
40 42 extern struct in_addr dns_addr;
... ... @@ -44,7 +46,6 @@ extern int towrite_max;
44 46 extern int ppp_exit;
45 47 extern int tcp_keepintvl;
46 48 extern uint8_t client_ethaddr[6];
47   -extern const char *slirp_special_ip;
48 49 extern int slirp_restrict;
49 50 extern char *tftp_prefix;
50 51 extern char *bootp_filename;
... ...
slirp/misc.c
... ... @@ -112,15 +112,16 @@ remque(void *a)
112 112 /* #endif */
113 113  
114 114  
115   -int
116   -add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port)
  115 +int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
  116 + struct in_addr addr, int port)
117 117 {
118 118 struct ex_list *tmp_ptr;
119 119  
120 120 /* First, check if the port is "bound" */
121 121 for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
122   - if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
123   - return -1;
  122 + if (port == tmp_ptr->ex_fport &&
  123 + addr.s_addr == tmp_ptr->ex_addr.s_addr)
  124 + return -1;
124 125 }
125 126  
126 127 tmp_ptr = *ex_ptr;
... ...
slirp/misc.h
... ... @@ -10,7 +10,7 @@
10 10  
11 11 struct ex_list {
12 12 int ex_pty; /* Do we want a pty? */
13   - int ex_addr; /* The last byte of the address */
  13 + struct in_addr ex_addr; /* Server address */
14 14 int ex_fport; /* Port to telnet to */
15 15 const char *ex_exec; /* Command line of what to exec */
16 16 struct ex_list *ex_next;
... ... @@ -74,7 +74,7 @@ void redir_x _P((u_int32_t, int, int, int));
74 74 void getouraddr _P((void));
75 75 void slirp_insque _P((void *, void *));
76 76 void slirp_remque _P((void *));
77   -int add_exec _P((struct ex_list **, int, char *, int, int));
  77 +int add_exec _P((struct ex_list **, int, char *, struct in_addr, int));
78 78 int slirp_openpty _P((int *, int *));
79 79 int fork_exec(struct socket *so, const char *ex, int do_pty);
80 80 void snooze_hup _P((int));
... ...
slirp/slirp.c
... ... @@ -33,13 +33,16 @@ struct in_addr dns_addr;
33 33 /* host loopback address */
34 34 struct in_addr loopback_addr;
35 35  
36   -/* address for slirp virtual addresses */
37   -struct in_addr special_addr;
38   -/* virtual address alias for host */
39   -struct in_addr alias_addr;
40   -
  36 +/* virtual network configuration */
  37 +struct in_addr vnetwork_addr;
  38 +struct in_addr vnetwork_mask;
  39 +struct in_addr vhost_addr;
  40 +struct in_addr vdhcp_startaddr;
  41 +struct in_addr vnameserver_addr;
  42 +
  43 +/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */
41 44 static const uint8_t special_ethaddr[6] = {
42   - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00
  45 + 0x52, 0x55, 0x00, 0x00, 0x00, 0x00
43 46 };
44 47  
45 48 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
... ... @@ -48,7 +51,6 @@ static struct in_addr client_ipaddr;
48 51  
49 52 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
50 53  
51   -const char *slirp_special_ip = CTL_SPECIAL;
52 54 int slirp_restrict;
53 55 static int do_slowtimo;
54 56 int link_up;
... ... @@ -176,12 +178,12 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
176 178 {
177 179 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
178 180  
  181 + struct in_addr special_addr = { .s_addr = htonl(0x0a000200) };
179 182 #ifdef _WIN32
180   - {
181   - WSADATA Data;
182   - WSAStartup(MAKEWORD(2,0), &Data);
183   - atexit(slirp_cleanup);
184   - }
  183 + WSADATA Data;
  184 +
  185 + WSAStartup(MAKEWORD(2,0), &Data);
  186 + atexit(slirp_cleanup);
185 187 #endif
186 188  
187 189 link_up = 1;
... ... @@ -201,9 +203,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
201 203 fprintf (stderr, "Warning: No DNS servers found\n");
202 204 }
203 205  
204   - if (special_ip)
205   - slirp_special_ip = special_ip;
206   -
  206 + if (special_ip) {
  207 + inet_aton(special_ip, &special_addr);
  208 + }
207 209 qemu_free(tftp_prefix);
208 210 tftp_prefix = NULL;
209 211 if (tftp_path) {
... ... @@ -215,8 +217,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
215 217 bootp_filename = qemu_strdup(bootfile);
216 218 }
217 219  
218   - inet_aton(slirp_special_ip, &special_addr);
219   - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
  220 + vnetwork_addr = special_addr;
  221 + vnetwork_mask.s_addr = htonl(0xffffff00);
  222 + vhost_addr.s_addr = special_addr.s_addr | htonl(2);
  223 + vdhcp_startaddr.s_addr = special_addr.s_addr | htonl(15);
  224 + vnameserver_addr.s_addr = special_addr.s_addr | htonl(3);
220 225 getouraddr();
221 226 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
222 227 }
... ... @@ -601,10 +606,10 @@ struct arphdr
601 606 * Ethernet looks like this : This bit is variable sized however...
602 607 */
603 608 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
604   - unsigned char ar_sip[4]; /* sender IP address */
  609 + uint32_t ar_sip; /* sender IP address */
605 610 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
606   - unsigned char ar_tip[4]; /* target IP address */
607   -};
  611 + uint32_t ar_tip ; /* target IP address */
  612 +} __attribute__((packed));
608 613  
609 614 static void arp_input(const uint8_t *pkt, int pkt_len)
610 615 {
... ... @@ -619,11 +624,12 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
619 624 ar_op = ntohs(ah->ar_op);
620 625 switch(ar_op) {
621 626 case ARPOP_REQUEST:
622   - if (!memcmp(ah->ar_tip, &special_addr, 3)) {
623   - if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS)
  627 + if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
  628 + if (ah->ar_tip == vnameserver_addr.s_addr ||
  629 + ah->ar_tip == vhost_addr.s_addr)
624 630 goto arp_ok;
625 631 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
626   - if (ex_ptr->ex_addr == ah->ar_tip[3])
  632 + if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
627 633 goto arp_ok;
628 634 }
629 635 return;
... ... @@ -633,8 +639,8 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
633 639  
634 640 /* ARP request for alias/dns mac address */
635 641 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN);
636   - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
637   - reh->h_source[5] = ah->ar_tip[3];
  642 + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
  643 + memcpy(&reh->h_source[2], &ah->ar_tip, 4);
638 644 reh->h_proto = htons(ETH_P_ARP);
639 645  
640 646 rah->ar_hrd = htons(1);
... ... @@ -643,16 +649,16 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
643 649 rah->ar_pln = 4;
644 650 rah->ar_op = htons(ARPOP_REPLY);
645 651 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN);
646   - memcpy(rah->ar_sip, ah->ar_tip, 4);
  652 + rah->ar_sip = ah->ar_tip;
647 653 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
648   - memcpy(rah->ar_tip, ah->ar_sip, 4);
  654 + rah->ar_tip = ah->ar_sip;
649 655 slirp_output(arp_reply, sizeof(arp_reply));
650 656 }
651 657 break;
652 658 case ARPOP_REPLY:
653 659 /* reply to request of client mac address ? */
654 660 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
655   - !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) {
  661 + ah->ar_sip == client_ipaddr.s_addr) {
656 662 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
657 663 }
658 664 break;
... ... @@ -716,8 +722,8 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
716 722 in place of sending the packet and we hope that the sender
717 723 will retry sending its packet. */
718 724 memset(reh->h_dest, 0xff, ETH_ALEN);
719   - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
720   - reh->h_source[5] = CTL_ALIAS;
  725 + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
  726 + memcpy(&reh->h_source[2], &vhost_addr, 4);
721 727 reh->h_proto = htons(ETH_P_ARP);
722 728 rah->ar_hrd = htons(1);
723 729 rah->ar_pro = htons(ETH_P_IP);
... ... @@ -725,21 +731,21 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
725 731 rah->ar_pln = 4;
726 732 rah->ar_op = htons(ARPOP_REQUEST);
727 733 /* source hw addr */
728   - memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
729   - rah->ar_sha[5] = CTL_ALIAS;
  734 + memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4);
  735 + memcpy(&rah->ar_sha[2], &vhost_addr, 4);
730 736 /* source IP */
731   - memcpy(rah->ar_sip, &alias_addr, 4);
  737 + rah->ar_sip = vhost_addr.s_addr;
732 738 /* target hw addr (none) */
733 739 memset(rah->ar_tha, 0, ETH_ALEN);
734 740 /* target IP */
735   - memcpy(rah->ar_tip, &iph->ip_dst, 4);
  741 + rah->ar_tip = iph->ip_dst.s_addr;
736 742 client_ipaddr = iph->ip_dst;
737 743 slirp_output(arp_req, sizeof(arp_req));
738 744 } else {
739 745 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
740   - memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
  746 + memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
741 747 /* XXX: not correct */
742   - eh->h_source[5] = CTL_ALIAS;
  748 + memcpy(&eh->h_source[2], &vhost_addr, 4);
743 749 eh->h_proto = htons(ETH_P_IP);
744 750 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
745 751 slirp_output(buf, ip_data_len + ETH_HLEN);
... ... @@ -772,6 +778,9 @@ int slirp_redir_rm(int is_udp, int host_port)
772 778 int slirp_redir(int is_udp, int host_port,
773 779 struct in_addr guest_addr, int guest_port)
774 780 {
  781 + if (!guest_addr.s_addr) {
  782 + guest_addr = vdhcp_startaddr;
  783 + }
775 784 if (is_udp) {
776 785 if (!udp_listen(htons(host_port), guest_addr.s_addr,
777 786 htons(guest_port), 0))
... ... @@ -787,8 +796,17 @@ int slirp_redir(int is_udp, int host_port,
787 796 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
788 797 int guest_port)
789 798 {
790   - return add_exec(&exec_list, do_pty, (char *)args,
791   - addr_low_byte, htons(guest_port));
  799 + struct in_addr guest_addr = {
  800 + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)
  801 + };
  802 +
  803 + if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
  804 + guest_addr.s_addr == vhost_addr.s_addr ||
  805 + guest_addr.s_addr == vnameserver_addr.s_addr) {
  806 + return -1;
  807 + }
  808 + return add_exec(&exec_list, do_pty, (char *)args, guest_addr,
  809 + htons(guest_port));
792 810 }
793 811  
794 812 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
... ... @@ -801,31 +819,32 @@ ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
801 819 return send(so->s, buf, len, flags);
802 820 }
803 821  
804   -static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
  822 +static struct socket *
  823 +slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
805 824 {
806   - struct socket *so;
807   -
808   - for (so = tcb.so_next; so != &tcb; so = so->so_next) {
809   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) ==
810   - special_addr.s_addr
811   - && (ntohl(so->so_faddr.s_addr) & 0xff) ==
812   - addr_low_byte
813   - && htons(so->so_fport) == guest_port)
814   - return so;
815   - }
  825 + struct socket *so;
816 826  
817   - return NULL;
  827 + for (so = tcb.so_next; so != &tcb; so = so->so_next) {
  828 + if (so->so_faddr.s_addr == guest_addr.s_addr &&
  829 + htons(so->so_fport) == guest_port) {
  830 + return so;
  831 + }
  832 + }
  833 + return NULL;
818 834 }
819 835  
820 836 size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
821 837 {
  838 + struct in_addr guest_addr = {
  839 + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)
  840 + };
822 841 struct iovec iov[2];
823 842 struct socket *so;
824 843  
825 844 if (!link_up)
826 845 return 0;
827 846  
828   - so = slirp_find_ctl_socket(addr_low_byte, guest_port);
  847 + so = slirp_find_ctl_socket(guest_addr, guest_port);
829 848  
830 849 if (!so || so->so_state & SS_NOFDREF)
831 850 return 0;
... ... @@ -840,8 +859,11 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
840 859 int size)
841 860 {
842 861 int ret;
843   - struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
844   -
  862 + struct in_addr guest_addr = {
  863 + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)
  864 + };
  865 + struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
  866 +
845 867 if (!so)
846 868 return;
847 869  
... ... @@ -1055,15 +1077,17 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1055 1077 if (ret < 0)
1056 1078 return ret;
1057 1079  
1058   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr)
  1080 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) !=
  1081 + vnetwork_addr.s_addr) {
1059 1082 return -EINVAL;
1060   -
1061   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
  1083 + }
  1084 + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1062 1085 if (ex_ptr->ex_pty == 3 &&
1063   - (ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr &&
1064   - so->so_fport == ex_ptr->ex_fport)
  1086 + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
  1087 + so->so_fport == ex_ptr->ex_fport) {
1065 1088 break;
1066   -
  1089 + }
  1090 + }
1067 1091 if (!ex_ptr)
1068 1092 return -EINVAL;
1069 1093  
... ...
slirp/slirp.h
... ... @@ -214,7 +214,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
214 214 #include "if.h"
215 215 #include "main.h"
216 216 #include "misc.h"
217   -#include "ctl.h"
218 217 #ifdef USE_PPP
219 218 #include "ppp/pppd.h"
220 219 #include "ppp/ppp.h"
... ...
slirp/socket.c
... ... @@ -555,16 +555,13 @@ sosendto(struct socket *so, struct mbuf *m)
555 555 DEBUG_ARG("m = %lx", (long)m);
556 556  
557 557 addr.sin_family = AF_INET;
558   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
  558 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
  559 + vnetwork_addr.s_addr) {
559 560 /* It's an alias */
560   - switch(ntohl(so->so_faddr.s_addr) & 0xff) {
561   - case CTL_DNS:
  561 + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
562 562 addr.sin_addr = dns_addr;
563   - break;
564   - case CTL_ALIAS:
565   - default:
  563 + } else {
566 564 addr.sin_addr = loopback_addr;
567   - break;
568 565 }
569 566 } else
570 567 addr.sin_addr = so->so_faddr;
... ... @@ -652,7 +649,7 @@ solisten(u_int port, u_int32_t laddr, u_int lport, int flags)
652 649 getsockname(s,(struct sockaddr *)&addr,&addrlen);
653 650 so->so_fport = addr.sin_port;
654 651 if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
655   - so->so_faddr = alias_addr;
  652 + so->so_faddr = vhost_addr;
656 653 else
657 654 so->so_faddr = addr.sin_addr;
658 655  
... ...
slirp/tcp_input.c
... ... @@ -359,11 +359,12 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
359 359 m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
360 360  
361 361 if (slirp_restrict) {
362   - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
  362 + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
363 363 if (ex_ptr->ex_fport == ti->ti_dport &&
364   - (ntohl(ti->ti_dst.s_addr) & 0xff) == ex_ptr->ex_addr)
  364 + ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) {
365 365 break;
366   -
  366 + }
  367 + }
367 368 if (!ex_ptr)
368 369 goto drop;
369 370 }
... ... @@ -639,9 +640,10 @@ findso:
639 640 * If this is destined for the control address, then flag to
640 641 * tcp_ctl once connected, otherwise connect
641 642 */
642   - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) {
643   - int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff;
644   - if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) {
  643 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
  644 + vnetwork_addr.s_addr) {
  645 + if (so->so_faddr.s_addr != vhost_addr.s_addr &&
  646 + so->so_faddr.s_addr != vnameserver_addr.s_addr) {
645 647 #if 0
646 648 if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) {
647 649 /* Command or exec adress */
... ... @@ -652,7 +654,7 @@ findso:
652 654 /* May be an add exec */
653 655 for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
654 656 if(ex_ptr->ex_fport == so->so_fport &&
655   - lastbyte == ex_ptr->ex_addr) {
  657 + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
656 658 so->so_state |= SS_CTL;
657 659 break;
658 660 }
... ...
slirp/tcp_subr.c
... ... @@ -384,16 +384,12 @@ int tcp_fconnect(struct socket *so)
384 384 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
385 385  
386 386 addr.sin_family = AF_INET;
387   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
  387 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
388 388 /* It's an alias */
389   - switch(ntohl(so->so_faddr.s_addr) & 0xff) {
390   - case CTL_DNS:
  389 + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
391 390 addr.sin_addr = dns_addr;
392   - break;
393   - case CTL_ALIAS:
394   - default:
  391 + } else {
395 392 addr.sin_addr = loopback_addr;
396   - break;
397 393 }
398 394 } else
399 395 addr.sin_addr = so->so_faddr;
... ... @@ -478,7 +474,7 @@ tcp_connect(struct socket *inso)
478 474 so->so_faddr = addr.sin_addr;
479 475 /* Translate connections from localhost to the real hostname */
480 476 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
481   - so->so_faddr = alias_addr;
  477 + so->so_faddr = vhost_addr;
482 478  
483 479 /* Close the accept() socket, set right state */
484 480 if (inso->so_state & SS_FACCEPTONCE) {
... ... @@ -1230,7 +1226,6 @@ do_prompt:
1230 1226 */
1231 1227 int tcp_ctl(struct socket *so)
1232 1228 {
1233   - int command = (ntohl(so->so_faddr.s_addr) & 0xff);
1234 1229 struct sbuf *sb = &so->so_snd;
1235 1230 struct ex_list *ex_ptr;
1236 1231 int do_pty;
... ... @@ -1238,11 +1233,11 @@ int tcp_ctl(struct socket *so)
1238 1233 DEBUG_CALL("tcp_ctl");
1239 1234 DEBUG_ARG("so = %lx", (long )so);
1240 1235  
1241   - if (command != CTL_ALIAS) {
  1236 + if (so->so_faddr.s_addr != vhost_addr.s_addr) {
1242 1237 /* Check if it's pty_exec */
1243 1238 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1244 1239 if (ex_ptr->ex_fport == so->so_fport &&
1245   - command == ex_ptr->ex_addr) {
  1240 + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
1246 1241 if (ex_ptr->ex_pty == 3) {
1247 1242 so->s = -1;
1248 1243 so->extra = (void *)ex_ptr->ex_exec;
... ...
slirp/udp.c
... ... @@ -312,12 +312,14 @@ int udp_output(struct socket *so, struct mbuf *m,
312 312 struct sockaddr_in saddr, daddr;
313 313  
314 314 saddr = *addr;
315   - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
316   - if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff))
317   - saddr.sin_addr.s_addr = alias_addr.s_addr;
318   - else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
319   - (ntohl(so->so_faddr.s_addr) & 0xff) != CTL_ALIAS)
320   - saddr.sin_addr.s_addr = so->so_faddr.s_addr;
  315 + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) {
  316 + if ((so->so_faddr.s_addr & ~vnetwork_mask.s_addr) ==
  317 + ~vnetwork_mask.s_addr) {
  318 + saddr.sin_addr = vhost_addr;
  319 + } else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
  320 + so->so_faddr.s_addr != vhost_addr.s_addr) {
  321 + saddr.sin_addr = so->so_faddr;
  322 + }
321 323 }
322 324 daddr.sin_addr = so->so_laddr;
323 325 daddr.sin_port = so->so_lport;
... ... @@ -652,11 +654,12 @@ udp_listen(u_int port, u_int32_t laddr, u_int lport, int flags)
652 654  
653 655 getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
654 656 so->so_fport = addr.sin_port;
655   - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
656   - so->so_faddr = alias_addr;
657   - else
  657 + if (addr.sin_addr.s_addr == 0 ||
  658 + addr.sin_addr.s_addr == loopback_addr.s_addr) {
  659 + so->so_faddr = vhost_addr;
  660 + } else {
658 661 so->so_faddr = addr.sin_addr;
659   -
  662 + }
660 663 so->so_lport = lport;
661 664 so->so_laddr.s_addr = laddr;
662 665 if (flags != SS_FACCEPTONCE)
... ...