Commit a9ba3a856d8e84f4c32bcfa2b92727b7add4996c
1 parent
e1c5a2b3
Add slirp_restrict option (Gleb Natapov)
Add "slirp firewall" to permit connection only to vmchannel addresses. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6241 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
60 additions
and
17 deletions
net.c
| @@ -483,7 +483,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name) | @@ -483,7 +483,7 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name) | ||
| 483 | { | 483 | { |
| 484 | if (!slirp_inited) { | 484 | if (!slirp_inited) { |
| 485 | slirp_inited = 1; | 485 | slirp_inited = 1; |
| 486 | - slirp_init(); | 486 | + slirp_init(0, NULL); |
| 487 | } | 487 | } |
| 488 | slirp_vc = qemu_new_vlan_client(vlan, model, name, | 488 | slirp_vc = qemu_new_vlan_client(vlan, model, name, |
| 489 | slirp_receive, NULL, NULL); | 489 | slirp_receive, NULL, NULL); |
| @@ -501,7 +501,7 @@ void net_slirp_redir(const char *redir_str) | @@ -501,7 +501,7 @@ void net_slirp_redir(const char *redir_str) | ||
| 501 | 501 | ||
| 502 | if (!slirp_inited) { | 502 | if (!slirp_inited) { |
| 503 | slirp_inited = 1; | 503 | slirp_inited = 1; |
| 504 | - slirp_init(); | 504 | + slirp_init(0, NULL); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | p = redir_str; | 507 | p = redir_str; |
| @@ -587,7 +587,7 @@ void net_slirp_smb(const char *exported_dir) | @@ -587,7 +587,7 @@ void net_slirp_smb(const char *exported_dir) | ||
| 587 | 587 | ||
| 588 | if (!slirp_inited) { | 588 | if (!slirp_inited) { |
| 589 | slirp_inited = 1; | 589 | slirp_inited = 1; |
| 590 | - slirp_init(); | 590 | + slirp_init(0, NULL); |
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | /* XXX: better tmp dir construction */ | 593 | /* XXX: better tmp dir construction */ |
slirp/bootp.c
| @@ -219,16 +219,18 @@ static void bootp_reply(struct bootp_t *bp) | @@ -219,16 +219,18 @@ static void bootp_reply(struct bootp_t *bp) | ||
| 219 | *q++ = 0xff; | 219 | *q++ = 0xff; |
| 220 | *q++ = 0x00; | 220 | *q++ = 0x00; |
| 221 | 221 | ||
| 222 | - *q++ = RFC1533_GATEWAY; | ||
| 223 | - *q++ = 4; | ||
| 224 | - memcpy(q, &saddr.sin_addr, 4); | ||
| 225 | - q += 4; | ||
| 226 | - | ||
| 227 | - *q++ = RFC1533_DNS; | ||
| 228 | - *q++ = 4; | ||
| 229 | - dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); | ||
| 230 | - memcpy(q, &dns_addr, 4); | ||
| 231 | - q += 4; | 222 | + if (!slirp_restrict) { |
| 223 | + *q++ = RFC1533_GATEWAY; | ||
| 224 | + *q++ = 4; | ||
| 225 | + memcpy(q, &saddr.sin_addr, 4); | ||
| 226 | + q += 4; | ||
| 227 | + | ||
| 228 | + *q++ = RFC1533_DNS; | ||
| 229 | + *q++ = 4; | ||
| 230 | + dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); | ||
| 231 | + memcpy(q, &dns_addr, 4); | ||
| 232 | + q += 4; | ||
| 233 | + } | ||
| 232 | 234 | ||
| 233 | *q++ = RFC2132_LEASE_TIME; | 235 | *q++ = RFC2132_LEASE_TIME; |
| 234 | *q++ = 4; | 236 | *q++ = 4; |
slirp/ip_input.c
| @@ -136,6 +136,27 @@ ip_input(m) | @@ -136,6 +136,27 @@ ip_input(m) | ||
| 136 | STAT(ipstat.ips_tooshort++); | 136 | STAT(ipstat.ips_tooshort++); |
| 137 | goto bad; | 137 | goto bad; |
| 138 | } | 138 | } |
| 139 | + | ||
| 140 | + if (slirp_restrict) { | ||
| 141 | + if (memcmp(&ip->ip_dst.s_addr, &special_addr, 3)) { | ||
| 142 | + if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP) | ||
| 143 | + goto bad; | ||
| 144 | + } else { | ||
| 145 | + int host = ntohl(ip->ip_dst.s_addr) & 0xff; | ||
| 146 | + struct ex_list *ex_ptr; | ||
| 147 | + | ||
| 148 | + if (host == 0xff) | ||
| 149 | + goto bad; | ||
| 150 | + | ||
| 151 | + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) | ||
| 152 | + if (ex_ptr->ex_addr == host) | ||
| 153 | + break; | ||
| 154 | + | ||
| 155 | + if (!ex_ptr) | ||
| 156 | + goto bad; | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 139 | /* Should drop packet if mbuf too long? hmmm... */ | 160 | /* Should drop packet if mbuf too long? hmmm... */ |
| 140 | if (m->m_len > ip->ip_len) | 161 | if (m->m_len > ip->ip_len) |
| 141 | m_adj(m, ip->ip_len - m->m_len); | 162 | m_adj(m, ip->ip_len - m->m_len); |
slirp/libslirp.h
| @@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
| 5 | extern "C" { | 5 | extern "C" { |
| 6 | #endif | 6 | #endif |
| 7 | 7 | ||
| 8 | -void slirp_init(void); | 8 | +void slirp_init(int restrict, char *special_ip); |
| 9 | 9 | ||
| 10 | void slirp_select_fill(int *pnfds, | 10 | void slirp_select_fill(int *pnfds, |
| 11 | fd_set *readfds, fd_set *writefds, fd_set *xfds); | 11 | fd_set *readfds, fd_set *writefds, fd_set *xfds); |
slirp/main.h
| @@ -44,6 +44,8 @@ extern int towrite_max; | @@ -44,6 +44,8 @@ extern int towrite_max; | ||
| 44 | extern int ppp_exit; | 44 | extern int ppp_exit; |
| 45 | extern int tcp_keepintvl; | 45 | extern int tcp_keepintvl; |
| 46 | extern uint8_t client_ethaddr[6]; | 46 | extern uint8_t client_ethaddr[6]; |
| 47 | +extern char *slirp_special_ip; | ||
| 48 | +extern int slirp_restrict; | ||
| 47 | 49 | ||
| 48 | #define PROTO_SLIP 0x1 | 50 | #define PROTO_SLIP 0x1 |
| 49 | #ifdef USE_PPP | 51 | #ifdef USE_PPP |
slirp/slirp.c
| @@ -46,6 +46,8 @@ static struct in_addr client_ipaddr; | @@ -46,6 +46,8 @@ static struct in_addr client_ipaddr; | ||
| 46 | 46 | ||
| 47 | static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; | 47 | static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 }; |
| 48 | 48 | ||
| 49 | +char *slirp_special_ip = CTL_SPECIAL; | ||
| 50 | +int slirp_restrict; | ||
| 49 | int do_slowtimo; | 51 | int do_slowtimo; |
| 50 | int link_up; | 52 | int link_up; |
| 51 | struct timeval tt; | 53 | struct timeval tt; |
| @@ -164,7 +166,7 @@ static void slirp_cleanup(void) | @@ -164,7 +166,7 @@ static void slirp_cleanup(void) | ||
| 164 | } | 166 | } |
| 165 | #endif | 167 | #endif |
| 166 | 168 | ||
| 167 | -void slirp_init(void) | 169 | +void slirp_init(int restrict, char *special_ip) |
| 168 | { | 170 | { |
| 169 | // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); | 171 | // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); |
| 170 | 172 | ||
| @@ -177,6 +179,7 @@ void slirp_init(void) | @@ -177,6 +179,7 @@ void slirp_init(void) | ||
| 177 | #endif | 179 | #endif |
| 178 | 180 | ||
| 179 | link_up = 1; | 181 | link_up = 1; |
| 182 | + slirp_restrict = restrict; | ||
| 180 | 183 | ||
| 181 | if_init(); | 184 | if_init(); |
| 182 | ip_init(); | 185 | ip_init(); |
| @@ -192,7 +195,10 @@ void slirp_init(void) | @@ -192,7 +195,10 @@ void slirp_init(void) | ||
| 192 | fprintf (stderr, "Warning: No DNS servers found\n"); | 195 | fprintf (stderr, "Warning: No DNS servers found\n"); |
| 193 | } | 196 | } |
| 194 | 197 | ||
| 195 | - inet_aton(CTL_SPECIAL, &special_addr); | 198 | + if (special_ip) |
| 199 | + slirp_special_ip = special_ip; | ||
| 200 | + | ||
| 201 | + inet_aton(slirp_special_ip, &special_addr); | ||
| 196 | alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); | 202 | alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); |
| 197 | getouraddr(); | 203 | getouraddr(); |
| 198 | } | 204 | } |
slirp/tcp_input.c
| @@ -253,6 +253,7 @@ tcp_input(m, iphlen, inso) | @@ -253,6 +253,7 @@ tcp_input(m, iphlen, inso) | ||
| 253 | u_long tiwin; | 253 | u_long tiwin; |
| 254 | int ret; | 254 | int ret; |
| 255 | /* int ts_present = 0; */ | 255 | /* int ts_present = 0; */ |
| 256 | + struct ex_list *ex_ptr; | ||
| 256 | 257 | ||
| 257 | DEBUG_CALL("tcp_input"); | 258 | DEBUG_CALL("tcp_input"); |
| 258 | DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", | 259 | DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", |
| @@ -363,6 +364,15 @@ tcp_input(m, iphlen, inso) | @@ -363,6 +364,15 @@ tcp_input(m, iphlen, inso) | ||
| 363 | m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); | 364 | m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); |
| 364 | m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); | 365 | m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); |
| 365 | 366 | ||
| 367 | + if (slirp_restrict) { | ||
| 368 | + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) | ||
| 369 | + if (ex_ptr->ex_fport == ti->ti_dport && | ||
| 370 | + (ntohl(ti->ti_dst.s_addr) & 0xff) == ex_ptr->ex_addr) | ||
| 371 | + break; | ||
| 372 | + | ||
| 373 | + if (!ex_ptr) | ||
| 374 | + goto drop; | ||
| 375 | + } | ||
| 366 | /* | 376 | /* |
| 367 | * Locate pcb for segment. | 377 | * Locate pcb for segment. |
| 368 | */ | 378 | */ |
| @@ -646,7 +656,6 @@ findso: | @@ -646,7 +656,6 @@ findso: | ||
| 646 | #endif | 656 | #endif |
| 647 | { | 657 | { |
| 648 | /* May be an add exec */ | 658 | /* May be an add exec */ |
| 649 | - struct ex_list *ex_ptr; | ||
| 650 | for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { | 659 | for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { |
| 651 | if(ex_ptr->ex_fport == so->so_fport && | 660 | if(ex_ptr->ex_fport == so->so_fport && |
| 652 | lastbyte == ex_ptr->ex_addr) { | 661 | lastbyte == ex_ptr->ex_addr) { |