qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 09/11] slirp: Rework internal configuration


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 09/11] slirp: Rework internal configuration
Date: Fri, 08 May 2009 12:34:18 +0200
User-agent: StGIT/0.14.2

The user mode IP stack is currently only minially 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 are kept
yet, they will be enhanced in the following patch.

Signed-off-by: Jan Kiszka <address@hidden>
---

 slirp/bootp.c     |   26 ++++------
 slirp/ctl.h       |    7 ---
 slirp/ip_icmp.c   |   15 ++----
 slirp/ip_input.c  |    9 ++-
 slirp/main.h      |    9 ++-
 slirp/misc.c      |    9 ++-
 slirp/misc.h      |    4 +
 slirp/slirp.c     |  143 +++++++++++++++++++++++++++++++----------------------
 slirp/slirp.h     |    1 
 slirp/socket.c    |   13 ++---
 slirp/tcp_input.c |   16 +++---
 slirp/tcp_subr.c  |  120 ++++++++++++--------------------------------
 slirp/udp.c       |   23 +++++----
 13 files changed, 176 insertions(+), 219 deletions(-)
 delete mode 100644 slirp/ctl.h

diff --git a/slirp/bootp.c b/slirp/bootp.c
index 3f4d079..8717343 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 {
@@ -62,7 +60,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;
 }
 
@@ -70,12 +68,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;
@@ -97,7 +95,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;
 }
 
@@ -154,7 +152,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;
@@ -216,7 +213,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);
@@ -260,10 +257,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;
@@ -273,8 +268,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 4a8576d..0000000
--- 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 61dcaf8..6e93ee3 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 c37412e..7a3c88b 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 537c145..8682d55 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[PATH_MAX];
 extern char bootp_filename[PATH_MAX];
diff --git a/slirp/misc.c b/slirp/misc.c
index 0137e75..ff7fbf4 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 ab8e3a7..29d5749 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 0fe0286..53f866d 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;
@@ -174,14 +176,12 @@ static int slirp_state_load(QEMUFile *f, void *opaque, 
int version_id);
 void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
                 const char *bootfile)
 {
-    //    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,16 +201,20 @@ 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);
+    }
     if (tftp_path) {
         pstrcpy(tftp_prefix, sizeof(tftp_prefix), tftp_path);
     }
     if (bootfile) {
         pstrcpy(bootp_filename, sizeof(bootp_filename), 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);
 }
@@ -595,10 +599,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)
 {
@@ -613,11 +617,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;
@@ -627,8 +632,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);
@@ -637,16 +642,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;
@@ -710,8 +715,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);
@@ -719,21 +724,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);
@@ -743,6 +748,9 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
 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))
@@ -758,8 +766,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)
@@ -772,31 +789,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;
@@ -811,8 +829,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;
 
@@ -1026,15 +1047,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 8309fe0..101d094 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 098132a..56f794d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -550,16 +550,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;
@@ -647,7 +644,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 effedfc..ab0840d 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 9d020a6..858d1ae 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) {
@@ -1228,84 +1224,34 @@ do_prompt:
  * Return 0 if this connections is to be closed, 1 otherwise,
  * return 2 if this is a command-line connection
  */
-int
-tcp_ctl(struct socket *so)
+int tcp_ctl(struct socket *so)
 {
-       struct sbuf *sb = &so->so_snd;
-       int command;
-       struct ex_list *ex_ptr;
-       int do_pty;
-        //     struct socket *tmpso;
-
-       DEBUG_CALL("tcp_ctl");
-       DEBUG_ARG("so = %lx", (long )so);
-
-#if 0
-       /*
-        * Check if they're authorised
-        */
-       if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr 
!= ctl_addr.s_addr))) {
-               sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission 
denied.\r\n");
-               sb->sb_wptr += sb->sb_cc;
-               return 0;
-       }
-#endif
-       command = (ntohl(so->so_faddr.s_addr) & 0xff);
-
-       switch(command) {
-       default: /* Check for exec's */
-
-               /*
-                * 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) {
-                               if (ex_ptr->ex_pty == 3) {
-                                       so->s = -1;
-                                       so->extra = (void *)ex_ptr->ex_exec;
-                                       return 1;
-                               }
-                               do_pty = ex_ptr->ex_pty;
-                               goto do_exec;
-                       }
-               }
-
-               /*
-                * Nothing bound..
-                */
-               /* tcp_fconnect(so); */
-
-               /* FALLTHROUGH */
-       case CTL_ALIAS:
-          sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - 
sb->sb_data),
-                               "Error: No application configured.\r\n");
-         sb->sb_wptr += sb->sb_cc;
-         return(0);
-
-       do_exec:
-               DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec));
-               return(fork_exec(so, ex_ptr->ex_exec, do_pty));
-
-#if 0
-       case CTL_CMD:
-          for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
-            if (tmpso->so_emu == EMU_CTL &&
-                !(tmpso->so_tcpcb?
-                  (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK))
-                  :0)) {
-              /* Ooops, control connection already active */
-              sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n");
-              sb->sb_wptr += sb->sb_cc;
-              return 0;
-            }
-          }
-          so->so_emu = EMU_CTL;
-          ctl_password_ok = 0;
-          sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type 
\"help\" for help).\r\nSlirp> ");
-          sb->sb_wptr += sb->sb_cc;
-          do_echo=-1;
-          return(2);
-#endif
-       }
+    struct sbuf *sb = &so->so_snd;
+    struct ex_list *ex_ptr;
+    int do_pty;
+
+    DEBUG_CALL("tcp_ctl");
+    DEBUG_ARG("so = %lx", (long )so);
+
+    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 &&
+                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;
+                    return 1;
+                }
+                do_pty = ex_ptr->ex_pty;
+                DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec));
+                return fork_exec(so, ex_ptr->ex_exec, do_pty);
+            }
+        }
+    }
+    sb->sb_cc =
+        snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data),
+                 "Error: No application configured.\r\n");
+    sb->sb_wptr += sb->sb_cc;
+    return 0;
 }
diff --git a/slirp/udp.c b/slirp/udp.c
index 11e78cd..dd91671 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -314,12 +314,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;
@@ -654,11 +656,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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]