diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2009-06-24 14:42:28 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-06-29 08:52:45 -0500 |
commit | a13a4126c8b94355bbe43e47275b97ce5bef003c (patch) | |
tree | be9f257c4e3956047481cbb2756813be3d023a94 | |
parent | ad196a9d0c14f681f010bb4b979030ec125ba976 (diff) |
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>
-rw-r--r-- | slirp/bootp.c | 26 | ||||
-rw-r--r-- | slirp/ctl.h | 7 | ||||
-rw-r--r-- | slirp/ip_icmp.c | 15 | ||||
-rw-r--r-- | slirp/ip_input.c | 9 | ||||
-rw-r--r-- | slirp/main.h | 9 | ||||
-rw-r--r-- | slirp/misc.c | 9 | ||||
-rw-r--r-- | slirp/misc.h | 4 | ||||
-rw-r--r-- | slirp/slirp.c | 142 | ||||
-rw-r--r-- | slirp/slirp.h | 1 | ||||
-rw-r--r-- | slirp/socket.c | 13 | ||||
-rw-r--r-- | slirp/tcp_input.c | 16 | ||||
-rw-r--r-- | slirp/tcp_subr.c | 17 | ||||
-rw-r--r-- | slirp/udp.c | 23 |
13 files changed, 149 insertions, 142 deletions
diff --git a/slirp/bootp.c b/slirp/bootp.c index a2fd734cd..97c2811fb 100644 --- a/slirp/bootp.c +++ b/slirp/bootp.c @@ -27,8 +27,6 @@ #define NB_ADDR 16 -#define START_ADDR 15 - #define LEASE_TIME (24 * 3600) typedef struct { @@ -64,7 +62,7 @@ static BOOTPClient *get_new_addr(struct in_addr *paddr, found: bc = &bootp_clients[i]; bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i); return bc; } @@ -72,12 +70,12 @@ static BOOTPClient *request_addr(const struct in_addr *paddr, const uint8_t *macaddr) { uint32_t req_addr = ntohl(paddr->s_addr); - uint32_t spec_addr = ntohl(special_addr.s_addr); + uint32_t dhcp_addr = ntohl(vdhcp_startaddr.s_addr); BOOTPClient *bc; - if (req_addr >= (spec_addr | START_ADDR) && - req_addr < (spec_addr | (NB_ADDR + START_ADDR))) { - bc = &bootp_clients[(req_addr & 0xff) - START_ADDR]; + if (req_addr >= dhcp_addr && + req_addr < (dhcp_addr + NB_ADDR)) { + bc = &bootp_clients[req_addr - dhcp_addr]; if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) { bc->allocated = 1; return bc; @@ -99,7 +97,7 @@ static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr) found: bc = &bootp_clients[i]; bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i); return bc; } @@ -156,7 +154,6 @@ static void bootp_reply(const struct bootp_t *bp) struct mbuf *m; struct bootp_t *rbp; struct sockaddr_in saddr, daddr; - struct in_addr dns_addr; const struct in_addr *preq_addr; int dhcp_msg_type, val; uint8_t *q; @@ -218,7 +215,7 @@ static void bootp_reply(const struct bootp_t *bp) } } - saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); + saddr.sin_addr = vhost_addr; saddr.sin_port = htons(BOOTP_SERVER); daddr.sin_port = htons(BOOTP_CLIENT); @@ -262,10 +259,8 @@ static void bootp_reply(const struct bootp_t *bp) *q++ = RFC1533_NETMASK; *q++ = 4; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0xff; - *q++ = 0x00; + memcpy(q, &vnetwork_mask, 4); + q += 4; if (!slirp_restrict) { *q++ = RFC1533_GATEWAY; @@ -275,8 +270,7 @@ static void bootp_reply(const struct bootp_t *bp) *q++ = RFC1533_DNS; *q++ = 4; - dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); - memcpy(q, &dns_addr, 4); + memcpy(q, &vnameserver_addr, 4); q += 4; } diff --git a/slirp/ctl.h b/slirp/ctl.h deleted file mode 100644 index 4a8576dc1..000000000 --- a/slirp/ctl.h +++ /dev/null @@ -1,7 +0,0 @@ -#define CTL_CMD 0 -#define CTL_EXEC 1 -#define CTL_ALIAS 2 -#define CTL_DNS 3 - -#define CTL_SPECIAL "10.0.2.0" -#define CTL_LOCAL "10.0.2.15" diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c index 61dcaf821..6e93ee3eb 100644 --- a/slirp/ip_icmp.c +++ b/slirp/ip_icmp.c @@ -110,7 +110,7 @@ icmp_input(struct mbuf *m, int hlen) case ICMP_ECHO: icp->icmp_type = ICMP_ECHOREPLY; ip->ip_len += hlen; /* since ip_input subtracts this */ - if (ip->ip_dst.s_addr == alias_addr.s_addr) { + if (ip->ip_dst.s_addr == vhost_addr.s_addr) { icmp_reflect(m); } else { struct socket *so; @@ -134,16 +134,13 @@ icmp_input(struct mbuf *m, int hlen) /* Send the packet */ addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == + vnetwork_addr.s_addr) { /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) { addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: + } else { addr.sin_addr = loopback_addr; - break; } } else { addr.sin_addr = so->so_faddr; @@ -302,7 +299,7 @@ icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, ip->ip_ttl = MAXTTL; ip->ip_p = IPPROTO_ICMP; ip->ip_dst = ip->ip_src; /* ip adresses */ - ip->ip_src = alias_addr; + ip->ip_src = vhost_addr; (void ) ip_output((struct socket *)NULL, m); diff --git a/slirp/ip_input.c b/slirp/ip_input.c index c37412e8c..7a3c88b54 100644 --- a/slirp/ip_input.c +++ b/slirp/ip_input.c @@ -134,18 +134,19 @@ ip_input(struct mbuf *m) } if (slirp_restrict) { - if (memcmp(&ip->ip_dst.s_addr, &special_addr, 3)) { + if ((ip->ip_dst.s_addr & vnetwork_mask.s_addr) == + vnetwork_addr.s_addr) { if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP) goto bad; } else { - int host = ntohl(ip->ip_dst.s_addr) & 0xff; struct ex_list *ex_ptr; - if (host == 0xff) + if ((ip->ip_dst.s_addr & ~vnetwork_mask.s_addr) == + ~vnetwork_mask.s_addr) goto bad; for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) - if (ex_ptr->ex_addr == host) + if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr) break; if (!ex_ptr) diff --git a/slirp/main.h b/slirp/main.h index 89e722f35..edbb9cb39 100644 --- a/slirp/main.h +++ b/slirp/main.h @@ -32,9 +32,11 @@ extern char *slirp_tty; extern char *exec_shell; extern u_int curtime; extern fd_set *global_readfds, *global_writefds, *global_xfds; -extern struct in_addr ctl_addr; -extern struct in_addr special_addr; -extern struct in_addr alias_addr; +extern struct in_addr vnetwork_addr; +extern struct in_addr vnetwork_mask; +extern struct in_addr vhost_addr; +extern struct in_addr vdhcp_startaddr; +extern struct in_addr vnameserver_addr; extern struct in_addr our_addr; extern struct in_addr loopback_addr; extern struct in_addr dns_addr; @@ -44,7 +46,6 @@ extern int towrite_max; extern int ppp_exit; extern int tcp_keepintvl; extern uint8_t client_ethaddr[6]; -extern const char *slirp_special_ip; extern int slirp_restrict; extern char *tftp_prefix; extern char *bootp_filename; diff --git a/slirp/misc.c b/slirp/misc.c index 1391d491d..069d8b102 100644 --- a/slirp/misc.c +++ b/slirp/misc.c @@ -112,15 +112,16 @@ remque(void *a) /* #endif */ -int -add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port) +int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec, + struct in_addr addr, int port) { struct ex_list *tmp_ptr; /* First, check if the port is "bound" */ for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { - if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) - return -1; + if (port == tmp_ptr->ex_fport && + addr.s_addr == tmp_ptr->ex_addr.s_addr) + return -1; } tmp_ptr = *ex_ptr; diff --git a/slirp/misc.h b/slirp/misc.h index ab8e3a726..29d574965 100644 --- a/slirp/misc.h +++ b/slirp/misc.h @@ -10,7 +10,7 @@ struct ex_list { int ex_pty; /* Do we want a pty? */ - int ex_addr; /* The last byte of the address */ + struct in_addr ex_addr; /* Server address */ int ex_fport; /* Port to telnet to */ const char *ex_exec; /* Command line of what to exec */ struct ex_list *ex_next; @@ -74,7 +74,7 @@ void redir_x _P((u_int32_t, int, int, int)); void getouraddr _P((void)); void slirp_insque _P((void *, void *)); void slirp_remque _P((void *)); -int add_exec _P((struct ex_list **, int, char *, int, int)); +int add_exec _P((struct ex_list **, int, char *, struct in_addr, int)); int slirp_openpty _P((int *, int *)); int fork_exec(struct socket *so, const char *ex, int do_pty); void snooze_hup _P((int)); diff --git a/slirp/slirp.c b/slirp/slirp.c index b0a092c14..8affd46c7 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -33,13 +33,16 @@ struct in_addr dns_addr; /* host loopback address */ struct in_addr loopback_addr; -/* address for slirp virtual addresses */ -struct in_addr special_addr; -/* virtual address alias for host */ -struct in_addr alias_addr; - +/* virtual network configuration */ +struct in_addr vnetwork_addr; +struct in_addr vnetwork_mask; +struct in_addr vhost_addr; +struct in_addr vdhcp_startaddr; +struct in_addr vnameserver_addr; + +/* emulated hosts use the MAC addr 52:55:IP:IP:IP:IP */ static const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 + 0x52, 0x55, 0x00, 0x00, 0x00, 0x00 }; /* ARP cache for the guest IP addresses (XXX: allow many entries) */ @@ -48,7 +51,6 @@ static struct in_addr client_ipaddr; static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; -const char *slirp_special_ip = CTL_SPECIAL; int slirp_restrict; static int do_slowtimo; int link_up; @@ -176,12 +178,12 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, { // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); + struct in_addr special_addr = { .s_addr = htonl(0x0a000200) }; #ifdef _WIN32 - { - WSADATA Data; - WSAStartup(MAKEWORD(2,0), &Data); - atexit(slirp_cleanup); - } + WSADATA Data; + + WSAStartup(MAKEWORD(2,0), &Data); + atexit(slirp_cleanup); #endif link_up = 1; @@ -201,9 +203,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, fprintf (stderr, "Warning: No DNS servers found\n"); } - if (special_ip) - slirp_special_ip = special_ip; - + if (special_ip) { + inet_aton(special_ip, &special_addr); + } qemu_free(tftp_prefix); tftp_prefix = NULL; if (tftp_path) { @@ -215,8 +217,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, bootp_filename = qemu_strdup(bootfile); } - inet_aton(slirp_special_ip, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + vnetwork_addr = special_addr; + vnetwork_mask.s_addr = htonl(0xffffff00); + vhost_addr.s_addr = special_addr.s_addr | htonl(2); + vdhcp_startaddr.s_addr = special_addr.s_addr | htonl(15); + vnameserver_addr.s_addr = special_addr.s_addr | htonl(3); getouraddr(); register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL); } @@ -601,10 +606,10 @@ struct arphdr * Ethernet looks like this : This bit is variable sized however... */ unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ + uint32_t ar_sip; /* sender IP address */ unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -}; + uint32_t ar_tip ; /* target IP address */ +} __attribute__((packed)); 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) ar_op = ntohs(ah->ar_op); switch(ar_op) { case ARPOP_REQUEST: - if (!memcmp(ah->ar_tip, &special_addr, 3)) { - if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) + if ((ah->ar_tip & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) { + if (ah->ar_tip == vnameserver_addr.s_addr || + ah->ar_tip == vhost_addr.s_addr) goto arp_ok; for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { - if (ex_ptr->ex_addr == ah->ar_tip[3]) + if (ex_ptr->ex_addr.s_addr == ah->ar_tip) goto arp_ok; } return; @@ -633,8 +639,8 @@ static void arp_input(const uint8_t *pkt, int pkt_len) /* ARP request for alias/dns mac address */ memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); - reh->h_source[5] = ah->ar_tip[3]; + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); + memcpy(&reh->h_source[2], &ah->ar_tip, 4); reh->h_proto = htons(ETH_P_ARP); rah->ar_hrd = htons(1); @@ -643,16 +649,16 @@ static void arp_input(const uint8_t *pkt, int pkt_len) rah->ar_pln = 4; rah->ar_op = htons(ARPOP_REPLY); memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); - memcpy(rah->ar_sip, ah->ar_tip, 4); + rah->ar_sip = ah->ar_tip; memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); - memcpy(rah->ar_tip, ah->ar_sip, 4); + rah->ar_tip = ah->ar_sip; slirp_output(arp_reply, sizeof(arp_reply)); } break; case ARPOP_REPLY: /* reply to request of client mac address ? */ if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) && - !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) { + ah->ar_sip == client_ipaddr.s_addr) { memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN); } break; @@ -716,8 +722,8 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) in place of sending the packet and we hope that the sender will retry sending its packet. */ memset(reh->h_dest, 0xff, ETH_ALEN); - memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); - reh->h_source[5] = CTL_ALIAS; + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4); + memcpy(&reh->h_source[2], &vhost_addr, 4); reh->h_proto = htons(ETH_P_ARP); rah->ar_hrd = htons(1); rah->ar_pro = htons(ETH_P_IP); @@ -725,21 +731,21 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) rah->ar_pln = 4; rah->ar_op = htons(ARPOP_REQUEST); /* source hw addr */ - memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1); - rah->ar_sha[5] = CTL_ALIAS; + memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 4); + memcpy(&rah->ar_sha[2], &vhost_addr, 4); /* source IP */ - memcpy(rah->ar_sip, &alias_addr, 4); + rah->ar_sip = vhost_addr.s_addr; /* target hw addr (none) */ memset(rah->ar_tha, 0, ETH_ALEN); /* target IP */ - memcpy(rah->ar_tip, &iph->ip_dst, 4); + rah->ar_tip = iph->ip_dst.s_addr; client_ipaddr = iph->ip_dst; slirp_output(arp_req, sizeof(arp_req)); } else { memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); - memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1); + memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4); /* XXX: not correct */ - eh->h_source[5] = CTL_ALIAS; + memcpy(&eh->h_source[2], &vhost_addr, 4); eh->h_proto = htons(ETH_P_IP); memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); slirp_output(buf, ip_data_len + ETH_HLEN); @@ -772,6 +778,9 @@ int slirp_redir_rm(int is_udp, int host_port) int slirp_redir(int is_udp, int host_port, struct in_addr guest_addr, int guest_port) { + if (!guest_addr.s_addr) { + guest_addr = vdhcp_startaddr; + } if (is_udp) { if (!udp_listen(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) @@ -787,8 +796,17 @@ int slirp_redir(int is_udp, int host_port, int slirp_add_exec(int do_pty, const void *args, int addr_low_byte, int guest_port) { - return add_exec(&exec_list, do_pty, (char *)args, - addr_low_byte, htons(guest_port)); + struct in_addr guest_addr = { + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte) + }; + + if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr || + guest_addr.s_addr == vhost_addr.s_addr || + guest_addr.s_addr == vnameserver_addr.s_addr) { + return -1; + } + return add_exec(&exec_list, do_pty, (char *)args, guest_addr, + htons(guest_port)); } 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) return send(so->s, buf, len, flags); } -static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port) +static struct socket * +slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port) { - struct socket *so; - - for (so = tcb.so_next; so != &tcb; so = so->so_next) { - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == - special_addr.s_addr - && (ntohl(so->so_faddr.s_addr) & 0xff) == - addr_low_byte - && htons(so->so_fport) == guest_port) - return so; - } + struct socket *so; - return NULL; + for (so = tcb.so_next; so != &tcb; so = so->so_next) { + if (so->so_faddr.s_addr == guest_addr.s_addr && + htons(so->so_fport) == guest_port) { + return so; + } + } + return NULL; } size_t slirp_socket_can_recv(int addr_low_byte, int guest_port) { + struct in_addr guest_addr = { + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte) + }; struct iovec iov[2]; struct socket *so; if (!link_up) return 0; - so = slirp_find_ctl_socket(addr_low_byte, guest_port); + so = slirp_find_ctl_socket(guest_addr, guest_port); if (!so || so->so_state & SS_NOFDREF) return 0; @@ -840,8 +859,11 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf, int size) { int ret; - struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port); - + struct in_addr guest_addr = { + .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte) + }; + struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port); + if (!so) return; @@ -1055,15 +1077,17 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) if (ret < 0) return ret; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr) + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) != + vnetwork_addr.s_addr) { return -EINVAL; - - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) + } + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if (ex_ptr->ex_pty == 3 && - (ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr && - so->so_fport == ex_ptr->ex_fport) + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr && + so->so_fport == ex_ptr->ex_fport) { break; - + } + } if (!ex_ptr) return -EINVAL; diff --git a/slirp/slirp.h b/slirp/slirp.h index 8309fe051..101d0943b 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -214,7 +214,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "if.h" #include "main.h" #include "misc.h" -#include "ctl.h" #ifdef USE_PPP #include "ppp/pppd.h" #include "ppp/ppp.h" diff --git a/slirp/socket.c b/slirp/socket.c index 82d026c70..9f13f03cc 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -555,16 +555,13 @@ sosendto(struct socket *so, struct mbuf *m) DEBUG_ARG("m = %lx", (long)m); addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == + vnetwork_addr.s_addr) { /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) { addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: + } else { addr.sin_addr = loopback_addr; - break; } } else addr.sin_addr = so->so_faddr; @@ -652,7 +649,7 @@ solisten(u_int port, u_int32_t laddr, u_int lport, int flags) getsockname(s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; + so->so_faddr = vhost_addr; else so->so_faddr = addr.sin_addr; diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index effedfc96..ab0840d8d 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -359,11 +359,12 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso) m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); if (slirp_restrict) { - for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if (ex_ptr->ex_fport == ti->ti_dport && - (ntohl(ti->ti_dst.s_addr) & 0xff) == ex_ptr->ex_addr) + ti->ti_dst.s_addr == ex_ptr->ex_addr.s_addr) { break; - + } + } if (!ex_ptr) goto drop; } @@ -639,9 +640,10 @@ findso: * If this is destined for the control address, then flag to * tcp_ctl once connected, otherwise connect */ - if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { - int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff; - if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == + vnetwork_addr.s_addr) { + if (so->so_faddr.s_addr != vhost_addr.s_addr && + so->so_faddr.s_addr != vnameserver_addr.s_addr) { #if 0 if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { /* Command or exec adress */ @@ -652,7 +654,7 @@ findso: /* May be an add exec */ for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if(ex_ptr->ex_fport == so->so_fport && - lastbyte == ex_ptr->ex_addr) { + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) { so->so_state |= SS_CTL; break; } diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 447a27c3b..858d1ae59 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -384,16 +384,12 @@ int tcp_fconnect(struct socket *so) setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); addr.sin_family = AF_INET; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) { /* It's an alias */ - switch(ntohl(so->so_faddr.s_addr) & 0xff) { - case CTL_DNS: + if (so->so_faddr.s_addr == vnameserver_addr.s_addr) { addr.sin_addr = dns_addr; - break; - case CTL_ALIAS: - default: + } else { addr.sin_addr = loopback_addr; - break; } } else addr.sin_addr = so->so_faddr; @@ -478,7 +474,7 @@ tcp_connect(struct socket *inso) so->so_faddr = addr.sin_addr; /* Translate connections from localhost to the real hostname */ if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; + so->so_faddr = vhost_addr; /* Close the accept() socket, set right state */ if (inso->so_state & SS_FACCEPTONCE) { @@ -1230,7 +1226,6 @@ do_prompt: */ int tcp_ctl(struct socket *so) { - int command = (ntohl(so->so_faddr.s_addr) & 0xff); struct sbuf *sb = &so->so_snd; struct ex_list *ex_ptr; int do_pty; @@ -1238,11 +1233,11 @@ int tcp_ctl(struct socket *so) DEBUG_CALL("tcp_ctl"); DEBUG_ARG("so = %lx", (long )so); - if (command != CTL_ALIAS) { + if (so->so_faddr.s_addr != vhost_addr.s_addr) { /* Check if it's pty_exec */ for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { if (ex_ptr->ex_fport == so->so_fport && - command == ex_ptr->ex_addr) { + so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) { if (ex_ptr->ex_pty == 3) { so->s = -1; so->extra = (void *)ex_ptr->ex_exec; diff --git a/slirp/udp.c b/slirp/udp.c index ba9d5c92b..ff3a39fb2 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -312,12 +312,14 @@ int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in saddr, daddr; saddr = *addr; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { - if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff)) - saddr.sin_addr.s_addr = alias_addr.s_addr; - else if (addr->sin_addr.s_addr == loopback_addr.s_addr || - (ntohl(so->so_faddr.s_addr) & 0xff) != CTL_ALIAS) - saddr.sin_addr.s_addr = so->so_faddr.s_addr; + if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) == vnetwork_addr.s_addr) { + if ((so->so_faddr.s_addr & ~vnetwork_mask.s_addr) == + ~vnetwork_mask.s_addr) { + saddr.sin_addr = vhost_addr; + } else if (addr->sin_addr.s_addr == loopback_addr.s_addr || + so->so_faddr.s_addr != vhost_addr.s_addr) { + saddr.sin_addr = so->so_faddr; + } } daddr.sin_addr = so->so_laddr; daddr.sin_port = so->so_lport; @@ -652,11 +654,12 @@ udp_listen(u_int port, u_int32_t laddr, u_int lport, int flags) getsockname(so->s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; - if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = alias_addr; - else + if (addr.sin_addr.s_addr == 0 || + addr.sin_addr.s_addr == loopback_addr.s_addr) { + so->so_faddr = vhost_addr; + } else { so->so_faddr = addr.sin_addr; - + } so->so_lport = lport; so->so_laddr.s_addr = laddr; if (flags != SS_FACCEPTONCE) |