diff --git a/slirp/bootp.c b/slirp/bootp.c index a2fd734cd4dae3fe6e0d69d9b6c1bed05e8f27d0..97c2811fbf38cd04d7c468e8ec6b2eb307ca21c0 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 4a8576dc1c5b734d94e5e2de48af53dcaf7dab1f..0000000000000000000000000000000000000000 --- 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 61dcaf821b48cac919eb5291b58986f0354d69bd..6e93ee3eb42a081b07869bd1e442707ace8a48d9 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 c37412e8cf2ea40a710eec34c724f9bc0aa3f79e..7a3c88b5497471f6ec7ce9ec67bb3b734df06846 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 89e722f355656f2af61afce5ff80336eb42ab424..edbb9cb39a47638364322e62d3fd28395d1b64c1 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 1391d491d7d425bf59d50175aabe5e138d04f77e..069d8b102d9ef4ec77f58ee6045f1fcf056609a2 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 ab8e3a726b52fb4b5dc07f98fe9967546d7346c4..29d574965ea400c7a48ca8497e534e8b571a433a 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 b0a092c14c8ad5d5dda9b6e969034ca080b880c0..8affd46c7c3313cb0b3d4f6200094ae45bb90948 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 8309fe051c01f9ef63209f275d8f8bfc812f556f..101d0943b75b03a0424511ac1f559b09aabd1f7e 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 82d026c7034a7883fff9f9216d1b3f91465318e3..9f13f03cc69a1a82326c5e7b1f3fa8beeaa0d1d1 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 effedfc966cd0cc32cd8f3ba6c82e52094e6faba..ab0840d8dd527084ba10f2d0cd16a878e4b5d477 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 447a27c3b040bcb7c5770ccb118d9246f870f00e..858d1ae59cfbdbf13c23b08dfbf1d8b2e6f82e27 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 ba9d5c92baa837dbfbf09a3a9c26910c0cc7aa8e..ff3a39fb21acb3085f6ba4718e535cb4e7d47a2e 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)