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,8 +27,6 @@
27 27
28 #define NB_ADDR 16 28 #define NB_ADDR 16
29 29
30 -#define START_ADDR 15  
31 -  
32 #define LEASE_TIME (24 * 3600) 30 #define LEASE_TIME (24 * 3600)
33 31
34 typedef struct { 32 typedef struct {
@@ -64,7 +62,7 @@ static BOOTPClient *get_new_addr(struct in_addr *paddr, @@ -64,7 +62,7 @@ static BOOTPClient *get_new_addr(struct in_addr *paddr,
64 found: 62 found:
65 bc = &bootp_clients[i]; 63 bc = &bootp_clients[i];
66 bc->allocated = 1; 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 return bc; 66 return bc;
69 } 67 }
70 68
@@ -72,12 +70,12 @@ static BOOTPClient *request_addr(const struct in_addr *paddr, @@ -72,12 +70,12 @@ static BOOTPClient *request_addr(const struct in_addr *paddr,
72 const uint8_t *macaddr) 70 const uint8_t *macaddr)
73 { 71 {
74 uint32_t req_addr = ntohl(paddr->s_addr); 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 BOOTPClient *bc; 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 if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) { 79 if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) {
82 bc->allocated = 1; 80 bc->allocated = 1;
83 return bc; 81 return bc;
@@ -99,7 +97,7 @@ static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr) @@ -99,7 +97,7 @@ static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
99 found: 97 found:
100 bc = &bootp_clients[i]; 98 bc = &bootp_clients[i];
101 bc->allocated = 1; 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 return bc; 101 return bc;
104 } 102 }
105 103
@@ -156,7 +154,6 @@ static void bootp_reply(const struct bootp_t *bp) @@ -156,7 +154,6 @@ static void bootp_reply(const struct bootp_t *bp)
156 struct mbuf *m; 154 struct mbuf *m;
157 struct bootp_t *rbp; 155 struct bootp_t *rbp;
158 struct sockaddr_in saddr, daddr; 156 struct sockaddr_in saddr, daddr;
159 - struct in_addr dns_addr;  
160 const struct in_addr *preq_addr; 157 const struct in_addr *preq_addr;
161 int dhcp_msg_type, val; 158 int dhcp_msg_type, val;
162 uint8_t *q; 159 uint8_t *q;
@@ -218,7 +215,7 @@ static void bootp_reply(const struct bootp_t *bp) @@ -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 saddr.sin_port = htons(BOOTP_SERVER); 219 saddr.sin_port = htons(BOOTP_SERVER);
223 220
224 daddr.sin_port = htons(BOOTP_CLIENT); 221 daddr.sin_port = htons(BOOTP_CLIENT);
@@ -262,10 +259,8 @@ static void bootp_reply(const struct bootp_t *bp) @@ -262,10 +259,8 @@ static void bootp_reply(const struct bootp_t *bp)
262 259
263 *q++ = RFC1533_NETMASK; 260 *q++ = RFC1533_NETMASK;
264 *q++ = 4; 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 if (!slirp_restrict) { 265 if (!slirp_restrict) {
271 *q++ = RFC1533_GATEWAY; 266 *q++ = RFC1533_GATEWAY;
@@ -275,8 +270,7 @@ static void bootp_reply(const struct bootp_t *bp) @@ -275,8 +270,7 @@ static void bootp_reply(const struct bootp_t *bp)
275 270
276 *q++ = RFC1533_DNS; 271 *q++ = RFC1533_DNS;
277 *q++ = 4; 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 q += 4; 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,7 +110,7 @@ icmp_input(struct mbuf *m, int hlen)
110 case ICMP_ECHO: 110 case ICMP_ECHO:
111 icp->icmp_type = ICMP_ECHOREPLY; 111 icp->icmp_type = ICMP_ECHOREPLY;
112 ip->ip_len += hlen; /* since ip_input subtracts this */ 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 icmp_reflect(m); 114 icmp_reflect(m);
115 } else { 115 } else {
116 struct socket *so; 116 struct socket *so;
@@ -134,16 +134,13 @@ icmp_input(struct mbuf *m, int hlen) @@ -134,16 +134,13 @@ icmp_input(struct mbuf *m, int hlen)
134 134
135 /* Send the packet */ 135 /* Send the packet */
136 addr.sin_family = AF_INET; 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 /* It's an alias */ 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 addr.sin_addr = dns_addr; 141 addr.sin_addr = dns_addr;
142 - break;  
143 - case CTL_ALIAS:  
144 - default: 142 + } else {
145 addr.sin_addr = loopback_addr; 143 addr.sin_addr = loopback_addr;
146 - break;  
147 } 144 }
148 } else { 145 } else {
149 addr.sin_addr = so->so_faddr; 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,7 +299,7 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
302 ip->ip_ttl = MAXTTL; 299 ip->ip_ttl = MAXTTL;
303 ip->ip_p = IPPROTO_ICMP; 300 ip->ip_p = IPPROTO_ICMP;
304 ip->ip_dst = ip->ip_src; /* ip adresses */ 301 ip->ip_dst = ip->ip_src; /* ip adresses */
305 - ip->ip_src = alias_addr; 302 + ip->ip_src = vhost_addr;
306 303
307 (void ) ip_output((struct socket *)NULL, m); 304 (void ) ip_output((struct socket *)NULL, m);
308 305
slirp/ip_input.c
@@ -134,18 +134,19 @@ ip_input(struct mbuf *m) @@ -134,18 +134,19 @@ ip_input(struct mbuf *m)
134 } 134 }
135 135
136 if (slirp_restrict) { 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 if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP) 139 if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
139 goto bad; 140 goto bad;
140 } else { 141 } else {
141 - int host = ntohl(ip->ip_dst.s_addr) & 0xff;  
142 struct ex_list *ex_ptr; 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 goto bad; 146 goto bad;
146 147
147 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) 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 break; 150 break;
150 151
151 if (!ex_ptr) 152 if (!ex_ptr)
slirp/main.h
@@ -32,9 +32,11 @@ extern char *slirp_tty; @@ -32,9 +32,11 @@ extern char *slirp_tty;
32 extern char *exec_shell; 32 extern char *exec_shell;
33 extern u_int curtime; 33 extern u_int curtime;
34 extern fd_set *global_readfds, *global_writefds, *global_xfds; 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 extern struct in_addr our_addr; 40 extern struct in_addr our_addr;
39 extern struct in_addr loopback_addr; 41 extern struct in_addr loopback_addr;
40 extern struct in_addr dns_addr; 42 extern struct in_addr dns_addr;
@@ -44,7 +46,6 @@ extern int towrite_max; @@ -44,7 +46,6 @@ extern int towrite_max;
44 extern int ppp_exit; 46 extern int ppp_exit;
45 extern int tcp_keepintvl; 47 extern int tcp_keepintvl;
46 extern uint8_t client_ethaddr[6]; 48 extern uint8_t client_ethaddr[6];
47 -extern const char *slirp_special_ip;  
48 extern int slirp_restrict; 49 extern int slirp_restrict;
49 extern char *tftp_prefix; 50 extern char *tftp_prefix;
50 extern char *bootp_filename; 51 extern char *bootp_filename;
slirp/misc.c
@@ -112,15 +112,16 @@ remque(void *a) @@ -112,15 +112,16 @@ remque(void *a)
112 /* #endif */ 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 struct ex_list *tmp_ptr; 118 struct ex_list *tmp_ptr;
119 119
120 /* First, check if the port is "bound" */ 120 /* First, check if the port is "bound" */
121 for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { 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 tmp_ptr = *ex_ptr; 127 tmp_ptr = *ex_ptr;
slirp/misc.h
@@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
10 10
11 struct ex_list { 11 struct ex_list {
12 int ex_pty; /* Do we want a pty? */ 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 int ex_fport; /* Port to telnet to */ 14 int ex_fport; /* Port to telnet to */
15 const char *ex_exec; /* Command line of what to exec */ 15 const char *ex_exec; /* Command line of what to exec */
16 struct ex_list *ex_next; 16 struct ex_list *ex_next;
@@ -74,7 +74,7 @@ void redir_x _P((u_int32_t, int, int, int)); @@ -74,7 +74,7 @@ void redir_x _P((u_int32_t, int, int, int));
74 void getouraddr _P((void)); 74 void getouraddr _P((void));
75 void slirp_insque _P((void *, void *)); 75 void slirp_insque _P((void *, void *));
76 void slirp_remque _P((void *)); 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 int slirp_openpty _P((int *, int *)); 78 int slirp_openpty _P((int *, int *));
79 int fork_exec(struct socket *so, const char *ex, int do_pty); 79 int fork_exec(struct socket *so, const char *ex, int do_pty);
80 void snooze_hup _P((int)); 80 void snooze_hup _P((int));
slirp/slirp.c
@@ -33,13 +33,16 @@ struct in_addr dns_addr; @@ -33,13 +33,16 @@ struct in_addr dns_addr;
33 /* host loopback address */ 33 /* host loopback address */
34 struct in_addr loopback_addr; 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 static const uint8_t special_ethaddr[6] = { 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 /* ARP cache for the guest IP addresses (XXX: allow many entries) */ 48 /* ARP cache for the guest IP addresses (XXX: allow many entries) */
@@ -48,7 +51,6 @@ static struct in_addr client_ipaddr; @@ -48,7 +51,6 @@ static struct in_addr client_ipaddr;
48 51
49 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; 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 int slirp_restrict; 54 int slirp_restrict;
53 static int do_slowtimo; 55 static int do_slowtimo;
54 int link_up; 56 int link_up;
@@ -176,12 +178,12 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, @@ -176,12 +178,12 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
176 { 178 {
177 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); 179 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
178 180
  181 + struct in_addr special_addr = { .s_addr = htonl(0x0a000200) };
179 #ifdef _WIN32 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 #endif 187 #endif
186 188
187 link_up = 1; 189 link_up = 1;
@@ -201,9 +203,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, @@ -201,9 +203,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
201 fprintf (stderr, "Warning: No DNS servers found\n"); 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 qemu_free(tftp_prefix); 209 qemu_free(tftp_prefix);
208 tftp_prefix = NULL; 210 tftp_prefix = NULL;
209 if (tftp_path) { 211 if (tftp_path) {
@@ -215,8 +217,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, @@ -215,8 +217,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
215 bootp_filename = qemu_strdup(bootfile); 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 getouraddr(); 225 getouraddr();
221 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL); 226 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
222 } 227 }
@@ -601,10 +606,10 @@ struct arphdr @@ -601,10 +606,10 @@ struct arphdr
601 * Ethernet looks like this : This bit is variable sized however... 606 * Ethernet looks like this : This bit is variable sized however...
602 */ 607 */
603 unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ 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 unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ 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 static void arp_input(const uint8_t *pkt, int pkt_len) 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,11 +624,12 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
619 ar_op = ntohs(ah->ar_op); 624 ar_op = ntohs(ah->ar_op);
620 switch(ar_op) { 625 switch(ar_op) {
621 case ARPOP_REQUEST: 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 goto arp_ok; 630 goto arp_ok;
625 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 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 goto arp_ok; 633 goto arp_ok;
628 } 634 }
629 return; 635 return;
@@ -633,8 +639,8 @@ static void arp_input(const uint8_t *pkt, int pkt_len) @@ -633,8 +639,8 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
633 639
634 /* ARP request for alias/dns mac address */ 640 /* ARP request for alias/dns mac address */
635 memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); 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 reh->h_proto = htons(ETH_P_ARP); 644 reh->h_proto = htons(ETH_P_ARP);
639 645
640 rah->ar_hrd = htons(1); 646 rah->ar_hrd = htons(1);
@@ -643,16 +649,16 @@ static void arp_input(const uint8_t *pkt, int pkt_len) @@ -643,16 +649,16 @@ static void arp_input(const uint8_t *pkt, int pkt_len)
643 rah->ar_pln = 4; 649 rah->ar_pln = 4;
644 rah->ar_op = htons(ARPOP_REPLY); 650 rah->ar_op = htons(ARPOP_REPLY);
645 memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); 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 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); 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 slirp_output(arp_reply, sizeof(arp_reply)); 655 slirp_output(arp_reply, sizeof(arp_reply));
650 } 656 }
651 break; 657 break;
652 case ARPOP_REPLY: 658 case ARPOP_REPLY:
653 /* reply to request of client mac address ? */ 659 /* reply to request of client mac address ? */
654 if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) && 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 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN); 662 memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
657 } 663 }
658 break; 664 break;
@@ -716,8 +722,8 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) @@ -716,8 +722,8 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
716 in place of sending the packet and we hope that the sender 722 in place of sending the packet and we hope that the sender
717 will retry sending its packet. */ 723 will retry sending its packet. */
718 memset(reh->h_dest, 0xff, ETH_ALEN); 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 reh->h_proto = htons(ETH_P_ARP); 727 reh->h_proto = htons(ETH_P_ARP);
722 rah->ar_hrd = htons(1); 728 rah->ar_hrd = htons(1);
723 rah->ar_pro = htons(ETH_P_IP); 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,21 +731,21 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
725 rah->ar_pln = 4; 731 rah->ar_pln = 4;
726 rah->ar_op = htons(ARPOP_REQUEST); 732 rah->ar_op = htons(ARPOP_REQUEST);
727 /* source hw addr */ 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 /* source IP */ 736 /* source IP */
731 - memcpy(rah->ar_sip, &alias_addr, 4); 737 + rah->ar_sip = vhost_addr.s_addr;
732 /* target hw addr (none) */ 738 /* target hw addr (none) */
733 memset(rah->ar_tha, 0, ETH_ALEN); 739 memset(rah->ar_tha, 0, ETH_ALEN);
734 /* target IP */ 740 /* target IP */
735 - memcpy(rah->ar_tip, &iph->ip_dst, 4); 741 + rah->ar_tip = iph->ip_dst.s_addr;
736 client_ipaddr = iph->ip_dst; 742 client_ipaddr = iph->ip_dst;
737 slirp_output(arp_req, sizeof(arp_req)); 743 slirp_output(arp_req, sizeof(arp_req));
738 } else { 744 } else {
739 memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); 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 /* XXX: not correct */ 747 /* XXX: not correct */
742 - eh->h_source[5] = CTL_ALIAS; 748 + memcpy(&eh->h_source[2], &vhost_addr, 4);
743 eh->h_proto = htons(ETH_P_IP); 749 eh->h_proto = htons(ETH_P_IP);
744 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); 750 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
745 slirp_output(buf, ip_data_len + ETH_HLEN); 751 slirp_output(buf, ip_data_len + ETH_HLEN);
@@ -772,6 +778,9 @@ int slirp_redir_rm(int is_udp, int host_port) @@ -772,6 +778,9 @@ int slirp_redir_rm(int is_udp, int host_port)
772 int slirp_redir(int is_udp, int host_port, 778 int slirp_redir(int is_udp, int host_port,
773 struct in_addr guest_addr, int guest_port) 779 struct in_addr guest_addr, int guest_port)
774 { 780 {
  781 + if (!guest_addr.s_addr) {
  782 + guest_addr = vdhcp_startaddr;
  783 + }
775 if (is_udp) { 784 if (is_udp) {
776 if (!udp_listen(htons(host_port), guest_addr.s_addr, 785 if (!udp_listen(htons(host_port), guest_addr.s_addr,
777 htons(guest_port), 0)) 786 htons(guest_port), 0))
@@ -787,8 +796,17 @@ int slirp_redir(int is_udp, int host_port, @@ -787,8 +796,17 @@ int slirp_redir(int is_udp, int host_port,
787 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte, 796 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
788 int guest_port) 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 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags) 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,31 +819,32 @@ ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
801 return send(so->s, buf, len, flags); 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 size_t slirp_socket_can_recv(int addr_low_byte, int guest_port) 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 struct iovec iov[2]; 841 struct iovec iov[2];
823 struct socket *so; 842 struct socket *so;
824 843
825 if (!link_up) 844 if (!link_up)
826 return 0; 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 if (!so || so->so_state & SS_NOFDREF) 849 if (!so || so->so_state & SS_NOFDREF)
831 return 0; 850 return 0;
@@ -840,8 +859,11 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf, @@ -840,8 +859,11 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
840 int size) 859 int size)
841 { 860 {
842 int ret; 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 if (!so) 867 if (!so)
846 return; 868 return;
847 869
@@ -1055,15 +1077,17 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) @@ -1055,15 +1077,17 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
1055 if (ret < 0) 1077 if (ret < 0)
1056 return ret; 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 return -EINVAL; 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 if (ex_ptr->ex_pty == 3 && 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 break; 1088 break;
1066 - 1089 + }
  1090 + }
1067 if (!ex_ptr) 1091 if (!ex_ptr)
1068 return -EINVAL; 1092 return -EINVAL;
1069 1093
slirp/slirp.h
@@ -214,7 +214,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); @@ -214,7 +214,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia));
214 #include "if.h" 214 #include "if.h"
215 #include "main.h" 215 #include "main.h"
216 #include "misc.h" 216 #include "misc.h"
217 -#include "ctl.h"  
218 #ifdef USE_PPP 217 #ifdef USE_PPP
219 #include "ppp/pppd.h" 218 #include "ppp/pppd.h"
220 #include "ppp/ppp.h" 219 #include "ppp/ppp.h"
slirp/socket.c
@@ -555,16 +555,13 @@ sosendto(struct socket *so, struct mbuf *m) @@ -555,16 +555,13 @@ sosendto(struct socket *so, struct mbuf *m)
555 DEBUG_ARG("m = %lx", (long)m); 555 DEBUG_ARG("m = %lx", (long)m);
556 556
557 addr.sin_family = AF_INET; 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 /* It's an alias */ 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 addr.sin_addr = dns_addr; 562 addr.sin_addr = dns_addr;
563 - break;  
564 - case CTL_ALIAS:  
565 - default: 563 + } else {
566 addr.sin_addr = loopback_addr; 564 addr.sin_addr = loopback_addr;
567 - break;  
568 } 565 }
569 } else 566 } else
570 addr.sin_addr = so->so_faddr; 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,7 +649,7 @@ solisten(u_int port, u_int32_t laddr, u_int lport, int flags)
652 getsockname(s,(struct sockaddr *)&addr,&addrlen); 649 getsockname(s,(struct sockaddr *)&addr,&addrlen);
653 so->so_fport = addr.sin_port; 650 so->so_fport = addr.sin_port;
654 if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) 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 else 653 else
657 so->so_faddr = addr.sin_addr; 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,11 +359,12 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
359 m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 359 m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
360 360
361 if (slirp_restrict) { 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 if (ex_ptr->ex_fport == ti->ti_dport && 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 break; 365 break;
366 - 366 + }
  367 + }
367 if (!ex_ptr) 368 if (!ex_ptr)
368 goto drop; 369 goto drop;
369 } 370 }
@@ -639,9 +640,10 @@ findso: @@ -639,9 +640,10 @@ findso:
639 * If this is destined for the control address, then flag to 640 * If this is destined for the control address, then flag to
640 * tcp_ctl once connected, otherwise connect 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 #if 0 647 #if 0
646 if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { 648 if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) {
647 /* Command or exec adress */ 649 /* Command or exec adress */
@@ -652,7 +654,7 @@ findso: @@ -652,7 +654,7 @@ findso:
652 /* May be an add exec */ 654 /* May be an add exec */
653 for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 655 for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
654 if(ex_ptr->ex_fport == so->so_fport && 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 so->so_state |= SS_CTL; 658 so->so_state |= SS_CTL;
657 break; 659 break;
658 } 660 }
slirp/tcp_subr.c
@@ -384,16 +384,12 @@ int tcp_fconnect(struct socket *so) @@ -384,16 +384,12 @@ int tcp_fconnect(struct socket *so)
384 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); 384 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
385 385
386 addr.sin_family = AF_INET; 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 /* It's an alias */ 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 addr.sin_addr = dns_addr; 390 addr.sin_addr = dns_addr;
392 - break;  
393 - case CTL_ALIAS:  
394 - default: 391 + } else {
395 addr.sin_addr = loopback_addr; 392 addr.sin_addr = loopback_addr;
396 - break;  
397 } 393 }
398 } else 394 } else
399 addr.sin_addr = so->so_faddr; 395 addr.sin_addr = so->so_faddr;
@@ -478,7 +474,7 @@ tcp_connect(struct socket *inso) @@ -478,7 +474,7 @@ tcp_connect(struct socket *inso)
478 so->so_faddr = addr.sin_addr; 474 so->so_faddr = addr.sin_addr;
479 /* Translate connections from localhost to the real hostname */ 475 /* Translate connections from localhost to the real hostname */
480 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) 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 /* Close the accept() socket, set right state */ 479 /* Close the accept() socket, set right state */
484 if (inso->so_state & SS_FACCEPTONCE) { 480 if (inso->so_state & SS_FACCEPTONCE) {
@@ -1230,7 +1226,6 @@ do_prompt: @@ -1230,7 +1226,6 @@ do_prompt:
1230 */ 1226 */
1231 int tcp_ctl(struct socket *so) 1227 int tcp_ctl(struct socket *so)
1232 { 1228 {
1233 - int command = (ntohl(so->so_faddr.s_addr) & 0xff);  
1234 struct sbuf *sb = &so->so_snd; 1229 struct sbuf *sb = &so->so_snd;
1235 struct ex_list *ex_ptr; 1230 struct ex_list *ex_ptr;
1236 int do_pty; 1231 int do_pty;
@@ -1238,11 +1233,11 @@ int tcp_ctl(struct socket *so) @@ -1238,11 +1233,11 @@ int tcp_ctl(struct socket *so)
1238 DEBUG_CALL("tcp_ctl"); 1233 DEBUG_CALL("tcp_ctl");
1239 DEBUG_ARG("so = %lx", (long )so); 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 /* Check if it's pty_exec */ 1237 /* Check if it's pty_exec */
1243 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 1238 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
1244 if (ex_ptr->ex_fport == so->so_fport && 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 if (ex_ptr->ex_pty == 3) { 1241 if (ex_ptr->ex_pty == 3) {
1247 so->s = -1; 1242 so->s = -1;
1248 so->extra = (void *)ex_ptr->ex_exec; 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,12 +312,14 @@ int udp_output(struct socket *so, struct mbuf *m,
312 struct sockaddr_in saddr, daddr; 312 struct sockaddr_in saddr, daddr;
313 313
314 saddr = *addr; 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 daddr.sin_addr = so->so_laddr; 324 daddr.sin_addr = so->so_laddr;
323 daddr.sin_port = so->so_lport; 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,11 +654,12 @@ udp_listen(u_int port, u_int32_t laddr, u_int lport, int flags)
652 654
653 getsockname(so->s,(struct sockaddr *)&addr,&addrlen); 655 getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
654 so->so_fport = addr.sin_port; 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 so->so_faddr = addr.sin_addr; 661 so->so_faddr = addr.sin_addr;
659 - 662 + }
660 so->so_lport = lport; 663 so->so_lport = lport;
661 so->so_laddr.s_addr = laddr; 664 so->so_laddr.s_addr = laddr;
662 if (flags != SS_FACCEPTONCE) 665 if (flags != SS_FACCEPTONCE)