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>
This commit is contained in:
Jan Kiszka 2009-06-24 14:42:28 +02:00 committed by Anthony Liguori
parent ad196a9d0c
commit a13a4126c8
13 changed files with 148 additions and 141 deletions

View file

@ -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;
}

View file

@ -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"

View file

@ -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);

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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;
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;
}
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;

View file

@ -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"

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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)