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 | 483 | { |
484 | 484 | if (!slirp_inited) { |
485 | 485 | slirp_inited = 1; |
486 | - slirp_init(); | |
486 | + slirp_init(0, NULL); | |
487 | 487 | } |
488 | 488 | slirp_vc = qemu_new_vlan_client(vlan, model, name, |
489 | 489 | slirp_receive, NULL, NULL); |
... | ... | @@ -501,7 +501,7 @@ void net_slirp_redir(const char *redir_str) |
501 | 501 | |
502 | 502 | if (!slirp_inited) { |
503 | 503 | slirp_inited = 1; |
504 | - slirp_init(); | |
504 | + slirp_init(0, NULL); | |
505 | 505 | } |
506 | 506 | |
507 | 507 | p = redir_str; |
... | ... | @@ -587,7 +587,7 @@ void net_slirp_smb(const char *exported_dir) |
587 | 587 | |
588 | 588 | if (!slirp_inited) { |
589 | 589 | slirp_inited = 1; |
590 | - slirp_init(); | |
590 | + slirp_init(0, NULL); | |
591 | 591 | } |
592 | 592 | |
593 | 593 | /* XXX: better tmp dir construction */ | ... | ... |
slirp/bootp.c
... | ... | @@ -219,16 +219,18 @@ static void bootp_reply(struct bootp_t *bp) |
219 | 219 | *q++ = 0xff; |
220 | 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 | 235 | *q++ = RFC2132_LEASE_TIME; |
234 | 236 | *q++ = 4; | ... | ... |
slirp/ip_input.c
... | ... | @@ -136,6 +136,27 @@ ip_input(m) |
136 | 136 | STAT(ipstat.ips_tooshort++); |
137 | 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 | 160 | /* Should drop packet if mbuf too long? hmmm... */ |
140 | 161 | if (m->m_len > ip->ip_len) |
141 | 162 | m_adj(m, ip->ip_len - m->m_len); | ... | ... |
slirp/libslirp.h
slirp/main.h
slirp/slirp.c
... | ... | @@ -46,6 +46,8 @@ static struct in_addr client_ipaddr; |
46 | 46 | |
47 | 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 | 51 | int do_slowtimo; |
50 | 52 | int link_up; |
51 | 53 | struct timeval tt; |
... | ... | @@ -164,7 +166,7 @@ static void slirp_cleanup(void) |
164 | 166 | } |
165 | 167 | #endif |
166 | 168 | |
167 | -void slirp_init(void) | |
169 | +void slirp_init(int restrict, char *special_ip) | |
168 | 170 | { |
169 | 171 | // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); |
170 | 172 | |
... | ... | @@ -177,6 +179,7 @@ void slirp_init(void) |
177 | 179 | #endif |
178 | 180 | |
179 | 181 | link_up = 1; |
182 | + slirp_restrict = restrict; | |
180 | 183 | |
181 | 184 | if_init(); |
182 | 185 | ip_init(); |
... | ... | @@ -192,7 +195,10 @@ void slirp_init(void) |
192 | 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 | 202 | alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); |
197 | 203 | getouraddr(); |
198 | 204 | } | ... | ... |
slirp/tcp_input.c
... | ... | @@ -253,6 +253,7 @@ tcp_input(m, iphlen, inso) |
253 | 253 | u_long tiwin; |
254 | 254 | int ret; |
255 | 255 | /* int ts_present = 0; */ |
256 | + struct ex_list *ex_ptr; | |
256 | 257 | |
257 | 258 | DEBUG_CALL("tcp_input"); |
258 | 259 | DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", |
... | ... | @@ -363,6 +364,15 @@ tcp_input(m, iphlen, inso) |
363 | 364 | m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); |
364 | 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 | 377 | * Locate pcb for segment. |
368 | 378 | */ |
... | ... | @@ -646,7 +656,6 @@ findso: |
646 | 656 | #endif |
647 | 657 | { |
648 | 658 | /* May be an add exec */ |
649 | - struct ex_list *ex_ptr; | |
650 | 659 | for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { |
651 | 660 | if(ex_ptr->ex_fport == so->so_fport && |
652 | 661 | lastbyte == ex_ptr->ex_addr) { | ... | ... |