Commit c92ef6a22d3c71538fcc48fb61ad353f7ba03b62

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent a13a4126

slirp: Rework external configuration interface

With the internal IP configuration made more flexible, we can now
enhance the user interface. This patch adds a number of new options to
"-net user": net (address and mask), host, dhcpstart, dns and smbserver.
It also renames "redir" to "hostfwd" and "channel" to "guestfwd" in
order to (hopefully) clarify their meanings. The format of guestfwd is
extended so that the user can define not only the port but also the
virtual server's IP address the forwarding starts from.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
@@ -669,12 +669,14 @@ static void config_error(Monitor *mon, const char *fmt, ...) @@ -669,12 +669,14 @@ static void config_error(Monitor *mon, const char *fmt, ...)
669 669
670 /* slirp network adapter */ 670 /* slirp network adapter */
671 671
672 -#define SLIRP_CFG_REDIR 1 672 +#define SLIRP_CFG_HOSTFWD 1
  673 +#define SLIRP_CFG_LEGACY 2
673 674
674 struct slirp_config_str { 675 struct slirp_config_str {
675 struct slirp_config_str *next; 676 struct slirp_config_str *next;
676 int flags; 677 int flags;
677 char str[1024]; 678 char str[1024];
  679 + int legacy_format;
678 }; 680 };
679 681
680 static int slirp_inited; 682 static int slirp_inited;
@@ -683,13 +685,14 @@ const char *legacy_tftp_prefix; @@ -683,13 +685,14 @@ const char *legacy_tftp_prefix;
683 const char *legacy_bootp_filename; 685 const char *legacy_bootp_filename;
684 static VLANClientState *slirp_vc; 686 static VLANClientState *slirp_vc;
685 687
686 -static void slirp_redirection(Monitor *mon, const char *redir_str);  
687 -static void vmchannel_init(Monitor *mon, const char *config_str); 688 +static void slirp_hostfwd(Monitor *mon, const char *redir_str);
  689 +static void slirp_guestfwd(Monitor *mon, const char *config_str,
  690 + int legacy_format);
688 691
689 #ifndef _WIN32 692 #ifndef _WIN32
690 static const char *legacy_smb_export; 693 static const char *legacy_smb_export;
691 694
692 -static void slirp_smb(const char *exported_dir); 695 +static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr);
693 #endif 696 #endif
694 697
695 int slirp_can_output(void) 698 int slirp_can_output(void)
@@ -731,31 +734,122 @@ static void net_slirp_cleanup(VLANClientState *vc) @@ -731,31 +734,122 @@ static void net_slirp_cleanup(VLANClientState *vc)
731 } 734 }
732 735
733 static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, 736 static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
734 - const char *name, int restricted, const char *ip,  
735 - const char *tftp_export, const char *bootfile,  
736 - const char *smb_export) 737 + const char *name, int restricted,
  738 + const char *vnetwork, const char *vhost,
  739 + const char *vhostname, const char *tftp_export,
  740 + const char *bootfile, const char *vdhcp_start,
  741 + const char *vnameserver, const char *smb_export,
  742 + const char *vsmbserver)
737 { 743 {
738 if (slirp_in_use) { 744 if (slirp_in_use) {
739 /* slirp only supports a single instance so far */ 745 /* slirp only supports a single instance so far */
740 return -1; 746 return -1;
741 } 747 }
742 if (!slirp_inited) { 748 if (!slirp_inited) {
  749 + /* default settings according to historic slirp */
  750 + struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
  751 + struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */
  752 + struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
  753 + struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
  754 + struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
  755 +#ifndef _WIN32
  756 + struct in_addr smbsrv = { .s_addr = 0 };
  757 +#endif
  758 + char buf[20];
  759 + uint32_t addr;
  760 + int shift;
  761 + char *end;
  762 +
743 if (!tftp_export) { 763 if (!tftp_export) {
744 tftp_export = legacy_tftp_prefix; 764 tftp_export = legacy_tftp_prefix;
745 } 765 }
746 if (!bootfile) { 766 if (!bootfile) {
747 bootfile = legacy_bootp_filename; 767 bootfile = legacy_bootp_filename;
748 } 768 }
  769 +
  770 + if (vnetwork) {
  771 + if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) {
  772 + if (!inet_aton(vnetwork, &net)) {
  773 + return -1;
  774 + }
  775 + addr = ntohl(net.s_addr);
  776 + if (!(addr & 0x80000000)) {
  777 + mask.s_addr = htonl(0xff000000); /* class A */
  778 + } else if ((addr & 0xfff00000) == 0xac100000) {
  779 + mask.s_addr = htonl(0xfff00000); /* priv. 172.16.0.0/12 */
  780 + } else if ((addr & 0xc0000000) == 0x80000000) {
  781 + mask.s_addr = htonl(0xffff0000); /* class B */
  782 + } else if ((addr & 0xffff0000) == 0xc0a80000) {
  783 + mask.s_addr = htonl(0xffff0000); /* priv. 192.168.0.0/16 */
  784 + } else if ((addr & 0xffff0000) == 0xc6120000) {
  785 + mask.s_addr = htonl(0xfffe0000); /* tests 198.18.0.0/15 */
  786 + } else if ((addr & 0xe0000000) == 0xe0000000) {
  787 + mask.s_addr = htonl(0xffffff00); /* class C */
  788 + } else {
  789 + mask.s_addr = htonl(0xfffffff0); /* multicast/reserved */
  790 + }
  791 + } else {
  792 + if (!inet_aton(buf, &net)) {
  793 + return -1;
  794 + }
  795 + shift = strtol(vnetwork, &end, 10);
  796 + if (*end != '\0') {
  797 + if (!inet_aton(vnetwork, &mask)) {
  798 + return -1;
  799 + }
  800 + } else if (shift < 4 || shift > 32) {
  801 + return -1;
  802 + } else {
  803 + mask.s_addr = htonl(0xffffffff << (32 - shift));
  804 + }
  805 + }
  806 + net.s_addr &= mask.s_addr;
  807 + host.s_addr = net.s_addr | (htonl(0x0202) & ~mask.s_addr);
  808 + dhcp.s_addr = net.s_addr | (htonl(0x020f) & ~mask.s_addr);
  809 + dns.s_addr = net.s_addr | (htonl(0x0203) & ~mask.s_addr);
  810 + }
  811 +
  812 + if (vhost && !inet_aton(vhost, &host)) {
  813 + return -1;
  814 + }
  815 + if ((host.s_addr & mask.s_addr) != net.s_addr) {
  816 + return -1;
  817 + }
  818 +
  819 + if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) {
  820 + return -1;
  821 + }
  822 + if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
  823 + dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
  824 + return -1;
  825 + }
  826 +
  827 + if (vnameserver && !inet_aton(vnameserver, &dns)) {
  828 + return -1;
  829 + }
  830 + if ((dns.s_addr & mask.s_addr) != net.s_addr ||
  831 + dns.s_addr == host.s_addr) {
  832 + return -1;
  833 + }
  834 +
  835 +#ifndef _WIN32
  836 + if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
  837 + return -1;
  838 + }
  839 +#endif
  840 +
  841 + slirp_init(restricted, net, mask, host, vhostname, tftp_export,
  842 + bootfile, dhcp, dns);
749 slirp_inited = 1; 843 slirp_inited = 1;
750 - slirp_init(restricted, ip, tftp_export, bootfile);  
751 844
752 while (slirp_configs) { 845 while (slirp_configs) {
753 struct slirp_config_str *config = slirp_configs; 846 struct slirp_config_str *config = slirp_configs;
754 847
755 - if (config->flags & SLIRP_CFG_REDIR) {  
756 - slirp_redirection(mon, config->str); 848 + if (config->flags & SLIRP_CFG_HOSTFWD) {
  849 + slirp_hostfwd(mon, config->str);
757 } else { 850 } else {
758 - vmchannel_init(mon, config->str); 851 + slirp_guestfwd(mon, config->str,
  852 + config->flags & SLIRP_CFG_LEGACY);
759 } 853 }
760 slirp_configs = config->next; 854 slirp_configs = config->next;
761 qemu_free(config); 855 qemu_free(config);
@@ -765,7 +859,7 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, @@ -765,7 +859,7 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
765 smb_export = legacy_smb_export; 859 smb_export = legacy_smb_export;
766 } 860 }
767 if (smb_export) { 861 if (smb_export) {
768 - slirp_smb(smb_export); 862 + slirp_smb(smb_export, smbsrv);
769 } 863 }
770 #endif 864 #endif
771 } 865 }
@@ -777,7 +871,7 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model, @@ -777,7 +871,7 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
777 return 0; 871 return 0;
778 } 872 }
779 873
780 -static void net_slirp_redir_rm(Monitor *mon, const char *port_str) 874 +static void net_slirp_hostfwd_remove(Monitor *mon, const char *port_str)
781 { 875 {
782 int host_port; 876 int host_port;
783 char buf[256] = ""; 877 char buf[256] = "";
@@ -803,23 +897,24 @@ static void net_slirp_redir_rm(Monitor *mon, const char *port_str) @@ -803,23 +897,24 @@ static void net_slirp_redir_rm(Monitor *mon, const char *port_str)
803 897
804 host_port = atoi(p); 898 host_port = atoi(p);
805 899
806 - n = slirp_redir_rm(is_udp, host_port); 900 + n = slirp_remove_hostfwd(is_udp, host_port);
807 901
808 - monitor_printf(mon, "removed %d redirections to %s port %d\n", n,  
809 - is_udp ? "udp" : "tcp", host_port); 902 + monitor_printf(mon, "removed %d host forwarding rules for %s port %d\n",
  903 + n, is_udp ? "udp" : "tcp", host_port);
810 return; 904 return;
811 905
812 fail_syntax: 906 fail_syntax:
813 monitor_printf(mon, "invalid format\n"); 907 monitor_printf(mon, "invalid format\n");
814 } 908 }
815 909
816 -static void slirp_redirection(Monitor *mon, const char *redir_str) 910 +static void slirp_hostfwd(Monitor *mon, const char *redir_str)
817 { 911 {
818 - struct in_addr guest_addr; 912 + struct in_addr guest_addr = { .s_addr = 0 };
819 int host_port, guest_port; 913 int host_port, guest_port;
820 const char *p; 914 const char *p;
821 - char buf[256], *r; 915 + char buf[256];
822 int is_udp; 916 int is_udp;
  917 + char *end;
823 918
824 p = redir_str; 919 p = redir_str;
825 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { 920 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
@@ -836,33 +931,31 @@ static void slirp_redirection(Monitor *mon, const char *redir_str) @@ -836,33 +931,31 @@ static void slirp_redirection(Monitor *mon, const char *redir_str)
836 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { 931 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
837 goto fail_syntax; 932 goto fail_syntax;
838 } 933 }
839 - host_port = strtol(buf, &r, 0);  
840 - if (r == buf) { 934 + host_port = strtol(buf, &end, 0);
  935 + if (*end != '\0' || host_port < 1 || host_port > 65535) {
841 goto fail_syntax; 936 goto fail_syntax;
842 } 937 }
843 938
844 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) { 939 if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
845 goto fail_syntax; 940 goto fail_syntax;
846 } 941 }
847 - if (buf[0] == '\0') {  
848 - pstrcpy(buf, sizeof(buf), "10.0.2.15");  
849 - }  
850 - if (!inet_aton(buf, &guest_addr)) { 942 + if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {
851 goto fail_syntax; 943 goto fail_syntax;
852 } 944 }
853 945
854 - guest_port = strtol(p, &r, 0);  
855 - if (r == p) { 946 + guest_port = strtol(p, &end, 0);
  947 + if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
856 goto fail_syntax; 948 goto fail_syntax;
857 } 949 }
858 950
859 - if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {  
860 - config_error(mon, "could not set up redirection '%s'\n", redir_str); 951 + if (slirp_add_hostfwd(is_udp, host_port, guest_addr, guest_port) < 0) {
  952 + config_error(mon, "could not set up host forwarding rule '%s'\n",
  953 + redir_str);
861 } 954 }
862 return; 955 return;
863 956
864 fail_syntax: 957 fail_syntax:
865 - config_error(mon, "invalid redirection format '%s'\n", redir_str); 958 + config_error(mon, "invalid host forwarding rule '%s'\n", redir_str);
866 } 959 }
867 960
868 void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2) 961 void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2)
@@ -875,7 +968,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -875,7 +968,7 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
875 } else { 968 } else {
876 config = qemu_malloc(sizeof(*config)); 969 config = qemu_malloc(sizeof(*config));
877 pstrcpy(config->str, sizeof(config->str), redir_str); 970 pstrcpy(config->str, sizeof(config->str), redir_str);
878 - config->flags = SLIRP_CFG_REDIR; 971 + config->flags = SLIRP_CFG_HOSTFWD;
879 config->next = slirp_configs; 972 config->next = slirp_configs;
880 slirp_configs = config; 973 slirp_configs = config;
881 } 974 }
@@ -883,11 +976,11 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -883,11 +976,11 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
883 } 976 }
884 977
885 if (!strcmp(redir_str, "remove")) { 978 if (!strcmp(redir_str, "remove")) {
886 - net_slirp_redir_rm(mon, redir_opt2); 979 + net_slirp_hostfwd_remove(mon, redir_opt2);
887 return; 980 return;
888 } 981 }
889 982
890 - slirp_redirection(mon, redir_str); 983 + slirp_hostfwd(mon, redir_str);
891 } 984 }
892 985
893 #ifndef _WIN32 986 #ifndef _WIN32
@@ -925,7 +1018,7 @@ static void smb_exit(void) @@ -925,7 +1018,7 @@ static void smb_exit(void)
925 erase_dir(smb_dir); 1018 erase_dir(smb_dir);
926 } 1019 }
927 1020
928 -static void slirp_smb(const char *exported_dir) 1021 +static void slirp_smb(const char *exported_dir, struct in_addr vserver_addr)
929 { 1022 {
930 char smb_conf[1024]; 1023 char smb_conf[1024];
931 char smb_cmdline[1024]; 1024 char smb_cmdline[1024];
@@ -971,19 +1064,24 @@ static void slirp_smb(const char *exported_dir) @@ -971,19 +1064,24 @@ static void slirp_smb(const char *exported_dir)
971 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s", 1064 snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
972 SMBD_COMMAND, smb_conf); 1065 SMBD_COMMAND, smb_conf);
973 1066
974 - slirp_add_exec(0, smb_cmdline, 4, 139); 1067 + if (slirp_add_exec(0, smb_cmdline, vserver_addr, 139) < 0) {
  1068 + fprintf(stderr, "conflicting/invalid smbserver address\n");
  1069 + exit(1);
  1070 + }
975 } 1071 }
976 1072
977 /* automatic user mode samba server configuration (legacy interface) */ 1073 /* automatic user mode samba server configuration (legacy interface) */
978 void net_slirp_smb(const char *exported_dir) 1074 void net_slirp_smb(const char *exported_dir)
979 { 1075 {
  1076 + struct in_addr vserver_addr = { .s_addr = 0 };
  1077 +
980 if (legacy_smb_export) { 1078 if (legacy_smb_export) {
981 fprintf(stderr, "-smb given twice\n"); 1079 fprintf(stderr, "-smb given twice\n");
982 exit(1); 1080 exit(1);
983 } 1081 }
984 legacy_smb_export = exported_dir; 1082 legacy_smb_export = exported_dir;
985 if (slirp_inited) { 1083 if (slirp_inited) {
986 - slirp_smb(exported_dir); 1084 + slirp_smb(exported_dir, vserver_addr);
987 } 1085 }
988 } 1086 }
989 1087
@@ -994,51 +1092,85 @@ void do_info_slirp(Monitor *mon) @@ -994,51 +1092,85 @@ void do_info_slirp(Monitor *mon)
994 slirp_stats(); 1092 slirp_stats();
995 } 1093 }
996 1094
997 -struct VMChannel { 1095 +struct GuestFwd {
998 CharDriverState *hd; 1096 CharDriverState *hd;
  1097 + struct in_addr server;
999 int port; 1098 int port;
1000 }; 1099 };
1001 1100
1002 -static int vmchannel_can_read(void *opaque) 1101 +static int guestfwd_can_read(void *opaque)
1003 { 1102 {
1004 - struct VMChannel *vmc = (struct VMChannel*)opaque;  
1005 - return slirp_socket_can_recv(4, vmc->port); 1103 + struct GuestFwd *fwd = opaque;
  1104 + return slirp_socket_can_recv(fwd->server, fwd->port);
1006 } 1105 }
1007 1106
1008 -static void vmchannel_read(void *opaque, const uint8_t *buf, int size) 1107 +static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
1009 { 1108 {
1010 - struct VMChannel *vmc = (struct VMChannel*)opaque;  
1011 - slirp_socket_recv(4, vmc->port, buf, size); 1109 + struct GuestFwd *fwd = opaque;
  1110 + slirp_socket_recv(fwd->server, fwd->port, buf, size);
1012 } 1111 }
1013 1112
1014 -static void vmchannel_init(Monitor *mon, const char *config_str) 1113 +static void slirp_guestfwd(Monitor *mon, const char *config_str,
  1114 + int legacy_format)
1015 { 1115 {
1016 - struct VMChannel *vmc;  
1017 - char *devname;  
1018 - char name[20]; 1116 + struct in_addr server = { .s_addr = 0 };
  1117 + struct GuestFwd *fwd;
  1118 + const char *p;
  1119 + char buf[128];
  1120 + char *end;
1019 int port; 1121 int port;
1020 1122
1021 - port = strtol(config_str, &devname, 10);  
1022 - if (port < 1 || port > 65535 || *devname != ':') {  
1023 - config_error(mon, "invalid vmchannel port number\n");  
1024 - return; 1123 + p = config_str;
  1124 + if (legacy_format) {
  1125 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
  1126 + goto fail_syntax;
  1127 + }
  1128 + } else {
  1129 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
  1130 + goto fail_syntax;
  1131 + }
  1132 + if (strcmp(buf, "tcp") && buf[0] != '\0') {
  1133 + goto fail_syntax;
  1134 + }
  1135 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
  1136 + goto fail_syntax;
  1137 + }
  1138 + if (buf[0] != '\0' && !inet_aton(buf, &server)) {
  1139 + goto fail_syntax;
  1140 + }
  1141 + if (get_str_sep(buf, sizeof(buf), &p, '-') < 0) {
  1142 + goto fail_syntax;
  1143 + }
  1144 + }
  1145 + port = strtol(buf, &end, 10);
  1146 + if (*end != '\0' || port < 1 || port > 65535) {
  1147 + goto fail_syntax;
1025 } 1148 }
1026 - devname++;  
1027 1149
1028 - vmc = qemu_malloc(sizeof(struct VMChannel));  
1029 - snprintf(name, sizeof(name), "vmchannel%d", port);  
1030 - vmc->hd = qemu_chr_open(name, devname, NULL);  
1031 - if (!vmc->hd) {  
1032 - config_error(mon, "could not open vmchannel device '%s'\n", devname);  
1033 - qemu_free(vmc); 1150 + fwd = qemu_malloc(sizeof(struct GuestFwd));
  1151 + snprintf(buf, sizeof(buf), "guestfwd.tcp:%d", port);
  1152 + fwd->hd = qemu_chr_open(buf, p, NULL);
  1153 + if (!fwd->hd) {
  1154 + config_error(mon, "could not open guest forwarding device '%s'\n",
  1155 + buf);
  1156 + qemu_free(fwd);
1034 return; 1157 return;
1035 } 1158 }
1036 - vmc->port = port; 1159 + fwd->server = server;
  1160 + fwd->port = port;
1037 1161
1038 - slirp_add_exec(3, vmc->hd, 4, port);  
1039 - qemu_chr_add_handlers(vmc->hd, vmchannel_can_read, vmchannel_read,  
1040 - NULL, vmc); 1162 + if (slirp_add_exec(3, fwd->hd, server, port) < 0) {
  1163 + config_error(mon, "conflicting/invalid host:port in guest forwarding "
  1164 + "rule '%s'\n", config_str);
  1165 + qemu_free(fwd);
  1166 + return;
  1167 + }
  1168 + qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
  1169 + NULL, fwd);
1041 return; 1170 return;
  1171 +
  1172 + fail_syntax:
  1173 + config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
1042 } 1174 }
1043 1175
1044 #endif /* CONFIG_SLIRP */ 1176 #endif /* CONFIG_SLIRP */
@@ -2252,15 +2384,21 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2252,15 +2384,21 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2252 #ifdef CONFIG_SLIRP 2384 #ifdef CONFIG_SLIRP
2253 if (!strcmp(device, "user")) { 2385 if (!strcmp(device, "user")) {
2254 static const char * const slirp_params[] = { 2386 static const char * const slirp_params[] = {
2255 - "vlan", "name", "hostname", "restrict", "ip", "tftp", "bootfile",  
2256 - "smb", "redir", "channel", NULL 2387 + "vlan", "name", "hostname", "restrict", "ip", "net", "host",
  2388 + "tftp", "bootfile", "dhcpstart", "dns", "smb", "smbserver",
  2389 + "hostfwd", "guestfwd", NULL
2257 }; 2390 };
2258 struct slirp_config_str *config; 2391 struct slirp_config_str *config;
  2392 + int restricted = 0;
  2393 + char *vnet = NULL;
  2394 + char *vhost = NULL;
  2395 + char *vhostname = NULL;
2259 char *tftp_export = NULL; 2396 char *tftp_export = NULL;
2260 char *bootfile = NULL; 2397 char *bootfile = NULL;
  2398 + char *vdhcp_start = NULL;
  2399 + char *vnamesrv = NULL;
2261 char *smb_export = NULL; 2400 char *smb_export = NULL;
2262 - int restricted = 0;  
2263 - char *ip = NULL; 2401 + char *vsmbsrv = NULL;
2264 const char *q; 2402 const char *q;
2265 2403
2266 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) { 2404 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {
@@ -2268,14 +2406,29 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2268,14 +2406,29 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2268 ret = -1; 2406 ret = -1;
2269 goto out; 2407 goto out;
2270 } 2408 }
  2409 + if (get_param_value(buf, sizeof(buf), "ip", p)) {
  2410 + /* emulate legacy parameter */
  2411 + vnet = qemu_malloc(strlen(buf) + strlen("/24") + 1);
  2412 + strcpy(vnet, buf);
  2413 + strcat(vnet, "/24");
  2414 + }
  2415 + if (get_param_value(buf, sizeof(buf), "net", p)) {
  2416 + vnet = qemu_strdup(buf);
  2417 + }
  2418 + if (get_param_value(buf, sizeof(buf), "host", p)) {
  2419 + vhost = qemu_strdup(buf);
  2420 + }
2271 if (get_param_value(buf, sizeof(buf), "hostname", p)) { 2421 if (get_param_value(buf, sizeof(buf), "hostname", p)) {
2272 - pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf); 2422 + vhostname = qemu_strdup(buf);
2273 } 2423 }
2274 if (get_param_value(buf, sizeof(buf), "restrict", p)) { 2424 if (get_param_value(buf, sizeof(buf), "restrict", p)) {
2275 restricted = (buf[0] == 'y') ? 1 : 0; 2425 restricted = (buf[0] == 'y') ? 1 : 0;
2276 } 2426 }
2277 - if (get_param_value(buf, sizeof(buf), "ip", p)) {  
2278 - ip = qemu_strdup(buf); 2427 + if (get_param_value(buf, sizeof(buf), "dhcpstart", p)) {
  2428 + vdhcp_start = qemu_strdup(buf);
  2429 + }
  2430 + if (get_param_value(buf, sizeof(buf), "dns", p)) {
  2431 + vnamesrv = qemu_strdup(buf);
2279 } 2432 }
2280 if (get_param_value(buf, sizeof(buf), "tftp", p)) { 2433 if (get_param_value(buf, sizeof(buf), "tftp", p)) {
2281 tftp_export = qemu_strdup(buf); 2434 tftp_export = qemu_strdup(buf);
@@ -2285,15 +2438,18 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2285,15 +2438,18 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2285 } 2438 }
2286 if (get_param_value(buf, sizeof(buf), "smb", p)) { 2439 if (get_param_value(buf, sizeof(buf), "smb", p)) {
2287 smb_export = qemu_strdup(buf); 2440 smb_export = qemu_strdup(buf);
  2441 + if (get_param_value(buf, sizeof(buf), "smbserver", p)) {
  2442 + vsmbsrv = qemu_strdup(buf);
  2443 + }
2288 } 2444 }
2289 q = p; 2445 q = p;
2290 while (1) { 2446 while (1) {
2291 config = qemu_malloc(sizeof(*config)); 2447 config = qemu_malloc(sizeof(*config));
2292 if (!get_next_param_value(config->str, sizeof(config->str), 2448 if (!get_next_param_value(config->str, sizeof(config->str),
2293 - "redir", &q)) { 2449 + "hostfwd", &q)) {
2294 break; 2450 break;
2295 } 2451 }
2296 - config->flags = SLIRP_CFG_REDIR; 2452 + config->flags = SLIRP_CFG_HOSTFWD;
2297 config->next = slirp_configs; 2453 config->next = slirp_configs;
2298 slirp_configs = config; 2454 slirp_configs = config;
2299 config = NULL; 2455 config = NULL;
@@ -2302,7 +2458,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2302,7 +2458,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2302 while (1) { 2458 while (1) {
2303 config = qemu_malloc(sizeof(*config)); 2459 config = qemu_malloc(sizeof(*config));
2304 if (!get_next_param_value(config->str, sizeof(config->str), 2460 if (!get_next_param_value(config->str, sizeof(config->str),
2305 - "channel", &q)) { 2461 + "guestfwd", &q)) {
2306 break; 2462 break;
2307 } 2463 }
2308 config->flags = 0; 2464 config->flags = 0;
@@ -2312,23 +2468,29 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2312,23 +2468,29 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2312 } 2468 }
2313 qemu_free(config); 2469 qemu_free(config);
2314 vlan->nb_host_devs++; 2470 vlan->nb_host_devs++;
2315 - ret = net_slirp_init(mon, vlan, device, name, restricted, ip,  
2316 - tftp_export, bootfile, smb_export);  
2317 - qemu_free(ip); 2471 + ret = net_slirp_init(mon, vlan, device, name, restricted, vnet, vhost,
  2472 + vhostname, tftp_export, bootfile, vdhcp_start,
  2473 + vnamesrv, smb_export, vsmbsrv);
  2474 + qemu_free(vnet);
  2475 + qemu_free(vhost);
  2476 + qemu_free(vhostname);
2318 qemu_free(tftp_export); 2477 qemu_free(tftp_export);
2319 qemu_free(bootfile); 2478 qemu_free(bootfile);
  2479 + qemu_free(vdhcp_start);
  2480 + qemu_free(vnamesrv);
2320 qemu_free(smb_export); 2481 qemu_free(smb_export);
  2482 + qemu_free(vsmbsrv);
2321 } else if (!strcmp(device, "channel")) { 2483 } else if (!strcmp(device, "channel")) {
2322 if (!slirp_inited) { 2484 if (!slirp_inited) {
2323 struct slirp_config_str *config; 2485 struct slirp_config_str *config;
2324 2486
2325 config = qemu_malloc(sizeof(*config)); 2487 config = qemu_malloc(sizeof(*config));
2326 pstrcpy(config->str, sizeof(config->str), p); 2488 pstrcpy(config->str, sizeof(config->str), p);
2327 - config->flags = 0; 2489 + config->flags = SLIRP_CFG_LEGACY;
2328 config->next = slirp_configs; 2490 config->next = slirp_configs;
2329 slirp_configs = config; 2491 slirp_configs = config;
2330 } else { 2492 } else {
2331 - vmchannel_init(mon, p); 2493 + slirp_guestfwd(mon, p, 1);
2332 } 2494 }
2333 ret = 0; 2495 ret = 0;
2334 } else 2496 } else
qemu-options.hx
@@ -749,10 +749,11 @@ DEF(&quot;net&quot;, HAS_ARG, QEMU_OPTION_net, @@ -749,10 +749,11 @@ DEF(&quot;net&quot;, HAS_ARG, QEMU_OPTION_net,
749 "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" 749 "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
750 " create a new Network Interface Card and connect it to VLAN 'n'\n" 750 " create a new Network Interface Card and connect it to VLAN 'n'\n"
751 #ifdef CONFIG_SLIRP 751 #ifdef CONFIG_SLIRP
752 - "-net user[,vlan=n][,name=str][ip=netaddr][,restrict=y|n][,hostname=host]\n"  
753 - " [,tftp=dir][,bootfile=f][,redir=rule][,channel=rule]" 752 + "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n"
  753 + " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n"
  754 + " [,hostfwd=rule][,guestfwd=rule]"
754 #ifndef _WIN32 755 #ifndef _WIN32
755 - "[,smb=dir]\n" 756 + "[,smb=dir[,smbserver=addr]]\n"
756 #endif 757 #endif
757 " connect the user mode network stack to VLAN 'n', configure its\n" 758 " connect the user mode network stack to VLAN 'n', configure its\n"
758 " DHCP server and enabled optional services\n" 759 " DHCP server and enabled optional services\n"
@@ -819,8 +820,14 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default). @@ -819,8 +820,14 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
819 @item name=@var{name} 820 @item name=@var{name}
820 Assign symbolic name for use in monitor commands. 821 Assign symbolic name for use in monitor commands.
821 822
822 -@item ip=@var{netaddr}  
823 -Set IP network address the guest will see (default: 10.0.2.x). 823 +@item net=@var{addr}[/@var{mask}]
  824 +Set IP network address the guest will see. Optionally specify the netmask,
  825 +either in the form a.b.c.d or as number of valid top-most bits. Default is
  826 +10.0.2.0/8.
  827 +
  828 +@item host=@var{addr}
  829 +Specify the guest-visible address of the host. Default is the 2nd IP in the
  830 +guest network, i.e. x.x.x.2.
824 831
825 @item restrict=y|yes|n|no 832 @item restrict=y|yes|n|no
826 If this options is enabled, the guest will be isolated, i.e. it will not be 833 If this options is enabled, the guest will be isolated, i.e. it will not be
@@ -830,12 +837,20 @@ to the outside. This option does not affect explicitly set forwarding rule. @@ -830,12 +837,20 @@ to the outside. This option does not affect explicitly set forwarding rule.
830 @item hostname=@var{name} 837 @item hostname=@var{name}
831 Specifies the client hostname reported by the builtin DHCP server. 838 Specifies the client hostname reported by the builtin DHCP server.
832 839
  840 +@item dhcpstart=@var{addr}
  841 +Specify the first of the 16 IPs the built-in DHCP server can assign. Default
  842 +is the 16th to 31st IP in the guest network, i.e. x.x.x.16 to x.x.x.31.
  843 +
  844 +@item dns=@var{addr}
  845 +Specify the guest-visible address of the virtual nameserver. The address must
  846 +be different from the host address. Default is the 3rd IP in the guest network,
  847 +i.e. x.x.x.3.
  848 +
833 @item tftp=@var{dir} 849 @item tftp=@var{dir}
834 When using the user mode network stack, activate a built-in TFTP 850 When using the user mode network stack, activate a built-in TFTP
835 server. The files in @var{dir} will be exposed as the root of a TFTP server. 851 server. The files in @var{dir} will be exposed as the root of a TFTP server.
836 The TFTP client on the guest must be configured in binary mode (use the command 852 The TFTP client on the guest must be configured in binary mode (use the command
837 -@code{bin} of the Unix TFTP client). The host IP address on the guest is  
838 -10.0.2.2 by default. 853 +@code{bin} of the Unix TFTP client).
839 854
840 @item bootfile=@var{file} 855 @item bootfile=@var{file}
841 When using the user mode network stack, broadcast @var{file} as the BOOTP 856 When using the user mode network stack, broadcast @var{file} as the BOOTP
@@ -847,10 +862,11 @@ Example (using pxelinux): @@ -847,10 +862,11 @@ Example (using pxelinux):
847 qemu -hda linux.img -boot n -net user,tftp=/path/to/tftp/files,bootfile=/pxelinux.0 862 qemu -hda linux.img -boot n -net user,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
848 @end example 863 @end example
849 864
850 -@item smb=@var{dir} 865 +@item smb=@var{dir}[,smbserver=@var{addr}]
851 When using the user mode network stack, activate a built-in SMB 866 When using the user mode network stack, activate a built-in SMB
852 server so that Windows OSes can access to the host files in @file{@var{dir}} 867 server so that Windows OSes can access to the host files in @file{@var{dir}}
853 -transparently. 868 +transparently. The IP address of the SMB server can be set to @var{addr}. By
  869 +default the 4th IP in the guest network is used, i.e. x.x.x.4.
854 870
855 In the guest Windows OS, the line: 871 In the guest Windows OS, the line:
856 @example 872 @example
@@ -865,19 +881,19 @@ Note that a SAMBA server must be installed on the host OS in @@ -865,19 +881,19 @@ Note that a SAMBA server must be installed on the host OS in
865 @file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from 881 @file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from
866 Red Hat 9, Fedora Core 3 and OpenSUSE 11.x. 882 Red Hat 9, Fedora Core 3 and OpenSUSE 11.x.
867 883
868 -@item redir=[tcp|udp]:@var{host-port}:[@var{guest-host}]:@var{guest-port}  
869 -Redirect incoming TCP or UDP connections to the host port @var{host-port} to  
870 -the guest @var{guest-host} on guest port @var{guest-port}. If @var{guest-host}  
871 -is not specified, its value is 10.0.2.15 (default address given by the built-in  
872 -DHCP server). If no connection type is specified, TCP is used. This option can  
873 -be given multiple times. 884 +@item hostfwd=[tcp|udp]:@var{hostport}:[@var{guestaddr}]:@var{guestport}
  885 +Redirect incoming TCP or UDP connections to the host port @var{hostport} to
  886 +the guest IP address @var{guestaddr} on guest port @var{guestport}. If
  887 +@var{guestaddr} is not specified, its value is x.x.x.15 (default first address
  888 +given by the built-in DHCP server). If no connection type is specified, TCP is
  889 +used. This option can be given multiple times.
874 890
875 For example, to redirect host X11 connection from screen 1 to guest 891 For example, to redirect host X11 connection from screen 1 to guest
876 screen 0, use the following: 892 screen 0, use the following:
877 893
878 @example 894 @example
879 # on the host 895 # on the host
880 -qemu -net user,redir=tcp:6001::6000 [...] 896 +qemu -net user,hostfwd=tcp:6001::6000 [...]
881 # this host xterm should open in the guest X11 server 897 # this host xterm should open in the guest X11 server
882 xterm -display :1 898 xterm -display :1
883 @end example 899 @end example
@@ -887,14 +903,14 @@ the guest, use the following: @@ -887,14 +903,14 @@ the guest, use the following:
887 903
888 @example 904 @example
889 # on the host 905 # on the host
890 -qemu -net user,redir=tcp:5555::23 [...] 906 +qemu -net user,hostfwd=tcp:5555::23 [...]
891 telnet localhost 5555 907 telnet localhost 5555
892 @end example 908 @end example
893 909
894 Then when you use on the host @code{telnet localhost 5555}, you 910 Then when you use on the host @code{telnet localhost 5555}, you
895 connect to the guest telnet server. 911 connect to the guest telnet server.
896 912
897 -@item channel=@var{port}:@var{dev} 913 +@item guestfwd=[tcp]:@var{server}:@var{port}-@var{dev}
898 Forward guest TCP connections to port @var{port} on the host to character 914 Forward guest TCP connections to port @var{port} on the host to character
899 device @var{dev}. This option can be given multiple times. 915 device @var{dev}. This option can be given multiple times.
900 916
slirp/libslirp.h
@@ -5,8 +5,11 @@ @@ -5,8 +5,11 @@
5 extern "C" { 5 extern "C" {
6 #endif 6 #endif
7 7
8 -void slirp_init(int restricted, const char *special_ip, const char *tftp_path,  
9 - const char *bootfile); 8 +void slirp_init(int restricted, struct in_addr vnetwork,
  9 + struct in_addr vnetmask, struct in_addr vhost,
  10 + const char *vhostname, const char *tftp_path,
  11 + const char *bootfile, struct in_addr vdhcp_start,
  12 + struct in_addr vnameserver);
10 13
11 void slirp_select_fill(int *pnfds, 14 void slirp_select_fill(int *pnfds,
12 fd_set *readfds, fd_set *writefds, fd_set *xfds); 15 fd_set *readfds, fd_set *writefds, fd_set *xfds);
@@ -19,18 +22,17 @@ void slirp_input(const uint8_t *pkt, int pkt_len); @@ -19,18 +22,17 @@ void slirp_input(const uint8_t *pkt, int pkt_len);
19 int slirp_can_output(void); 22 int slirp_can_output(void);
20 void slirp_output(const uint8_t *pkt, int pkt_len); 23 void slirp_output(const uint8_t *pkt, int pkt_len);
21 24
22 -int slirp_redir_rm(int is_udp, int host_port);  
23 -int slirp_redir(int is_udp, int host_port,  
24 - struct in_addr guest_addr, int guest_port);  
25 -int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,  
26 - int guest_port); 25 +int slirp_add_hostfwd(int is_udp, int host_port,
  26 + struct in_addr guest_addr, int guest_port);
  27 +int slirp_remove_hostfwd(int is_udp, int host_port);
27 28
28 -extern char slirp_hostname[33]; 29 +int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
  30 + int guest_port);
29 31
30 void slirp_stats(void); 32 void slirp_stats(void);
31 -void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,  
32 - int size);  
33 -size_t slirp_socket_can_recv(int addr_low_byte, int guest_port); 33 +void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
  34 + const uint8_t *buf, int size);
  35 +size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port);
34 36
35 #ifdef __cplusplus 37 #ifdef __cplusplus
36 } 38 }
slirp/main.h
@@ -47,6 +47,7 @@ extern int ppp_exit; @@ -47,6 +47,7 @@ extern int ppp_exit;
47 extern int tcp_keepintvl; 47 extern int tcp_keepintvl;
48 extern uint8_t client_ethaddr[6]; 48 extern uint8_t client_ethaddr[6];
49 extern int slirp_restrict; 49 extern int slirp_restrict;
  50 +extern char slirp_hostname[33];
50 extern char *tftp_prefix; 51 extern char *tftp_prefix;
51 extern char *bootp_filename; 52 extern char *bootp_filename;
52 53
slirp/slirp.c
@@ -173,12 +173,14 @@ static void slirp_cleanup(void) @@ -173,12 +173,14 @@ static void slirp_cleanup(void)
173 static void slirp_state_save(QEMUFile *f, void *opaque); 173 static void slirp_state_save(QEMUFile *f, void *opaque);
174 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); 174 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
175 175
176 -void slirp_init(int restricted, const char *special_ip, const char *tftp_path,  
177 - const char *bootfile) 176 +void slirp_init(int restricted, struct in_addr vnetwork,
  177 + struct in_addr vnetmask, struct in_addr vhost,
  178 + const char *vhostname, const char *tftp_path,
  179 + const char *bootfile, struct in_addr vdhcp_start,
  180 + struct in_addr vnameserver)
178 { 181 {
179 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); 182 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
180 183
181 - struct in_addr special_addr = { .s_addr = htonl(0x0a000200) };  
182 #ifdef _WIN32 184 #ifdef _WIN32
183 WSADATA Data; 185 WSADATA Data;
184 186
@@ -203,8 +205,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, @@ -203,8 +205,11 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
203 fprintf (stderr, "Warning: No DNS servers found\n"); 205 fprintf (stderr, "Warning: No DNS servers found\n");
204 } 206 }
205 207
206 - if (special_ip) {  
207 - inet_aton(special_ip, &special_addr); 208 + vnetwork_addr = vnetwork;
  209 + vnetwork_mask = vnetmask;
  210 + vhost_addr = vhost;
  211 + if (vhostname) {
  212 + pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);
208 } 213 }
209 qemu_free(tftp_prefix); 214 qemu_free(tftp_prefix);
210 tftp_prefix = NULL; 215 tftp_prefix = NULL;
@@ -216,12 +221,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path, @@ -216,12 +221,9 @@ void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
216 if (bootfile) { 221 if (bootfile) {
217 bootp_filename = qemu_strdup(bootfile); 222 bootp_filename = qemu_strdup(bootfile);
218 } 223 }
  224 + vdhcp_startaddr = vdhcp_start;
  225 + vnameserver_addr = vnameserver;
219 226
220 - vnetwork_addr = special_addr;  
221 - vnetwork_mask.s_addr = htonl(0xffffff00);  
222 - vhost_addr.s_addr = special_addr.s_addr | htonl(2);  
223 - vdhcp_startaddr.s_addr = special_addr.s_addr | htonl(15);  
224 - vnameserver_addr.s_addr = special_addr.s_addr | htonl(3);  
225 getouraddr(); 227 getouraddr();
226 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL); 228 register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
227 } 229 }
@@ -755,7 +757,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) @@ -755,7 +757,7 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
755 /* Unlistens a redirection 757 /* Unlistens a redirection
756 * 758 *
757 * Return value: number of redirs removed */ 759 * Return value: number of redirs removed */
758 -int slirp_redir_rm(int is_udp, int host_port) 760 +int slirp_remove_hostfwd(int is_udp, int host_port)
759 { 761 {
760 struct socket *so; 762 struct socket *so;
761 struct socket *head = (is_udp ? &udb : &tcb); 763 struct socket *head = (is_udp ? &udb : &tcb);
@@ -775,8 +777,8 @@ int slirp_redir_rm(int is_udp, int host_port) @@ -775,8 +777,8 @@ int slirp_redir_rm(int is_udp, int host_port)
775 return n; 777 return n;
776 } 778 }
777 779
778 -int slirp_redir(int is_udp, int host_port,  
779 - struct in_addr guest_addr, int guest_port) 780 +int slirp_add_hostfwd(int is_udp, int host_port,
  781 + struct in_addr guest_addr, int guest_port)
780 { 782 {
781 if (!guest_addr.s_addr) { 783 if (!guest_addr.s_addr) {
782 guest_addr = vdhcp_startaddr; 784 guest_addr = vdhcp_startaddr;
@@ -793,13 +795,13 @@ int slirp_redir(int is_udp, int host_port, @@ -793,13 +795,13 @@ int slirp_redir(int is_udp, int host_port,
793 return 0; 795 return 0;
794 } 796 }
795 797
796 -int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,  
797 - int guest_port) 798 +int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
  799 + int guest_port)
798 { 800 {
799 - struct in_addr guest_addr = {  
800 - .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)  
801 - };  
802 - 801 + if (!guest_addr.s_addr) {
  802 + guest_addr.s_addr =
  803 + vnetwork_addr.s_addr | (htonl(0x0204) & ~vnetwork_mask.s_addr);
  804 + }
803 if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr || 805 if ((guest_addr.s_addr & vnetwork_mask.s_addr) != vnetwork_addr.s_addr ||
804 guest_addr.s_addr == vhost_addr.s_addr || 806 guest_addr.s_addr == vhost_addr.s_addr ||
805 guest_addr.s_addr == vnameserver_addr.s_addr) { 807 guest_addr.s_addr == vnameserver_addr.s_addr) {
@@ -833,11 +835,8 @@ slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port) @@ -833,11 +835,8 @@ slirp_find_ctl_socket(struct in_addr guest_addr, int guest_port)
833 return NULL; 835 return NULL;
834 } 836 }
835 837
836 -size_t slirp_socket_can_recv(int addr_low_byte, int guest_port) 838 +size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port)
837 { 839 {
838 - struct in_addr guest_addr = {  
839 - .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)  
840 - };  
841 struct iovec iov[2]; 840 struct iovec iov[2];
842 struct socket *so; 841 struct socket *so;
843 842
@@ -855,13 +854,10 @@ size_t slirp_socket_can_recv(int addr_low_byte, int guest_port) @@ -855,13 +854,10 @@ size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
855 return sopreprbuf(so, iov, NULL); 854 return sopreprbuf(so, iov, NULL);
856 } 855 }
857 856
858 -void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,  
859 - int size) 857 +void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
  858 + const uint8_t *buf, int size)
860 { 859 {
861 int ret; 860 int ret;
862 - struct in_addr guest_addr = {  
863 - .s_addr = vnetwork_addr.s_addr | htonl(addr_low_byte)  
864 - };  
865 struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port); 861 struct socket *so = slirp_find_ctl_socket(guest_addr, guest_port);
866 862
867 if (!so) 863 if (!so)