VirtualBox

source: vbox/trunk/src/VBox/NetworkServices/NAT/pxremap.c@ 49828

最後變更 在這個檔案從49828是 49692,由 vboxsync 提交於 11 年 前

G/c unused variable.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 7.9 KB
 
1/** -*- indent-tabs-mode: nil; -*-
2 *
3 * This file contains functions pertinent to magic address remapping.
4 *
5 * We want to expose host's loopback interfaces to the guest by
6 * mapping them to the addresses from the same prefix/subnet, so if,
7 * for example proxy interface is 10.0.2.1, we redirect traffic to
8 * 10.0.2.2 to host's 127.0.0.1 loopback. If need be, we may extend
9 * this to provide additional mappings, e.g. 127.0.1.1 loopback
10 * address is used on Ubuntu 12.10+ for NetworkManager's dnsmasq.
11 *
12 * Ditto for IPv6, except that IPv6 only has one loopback address.
13 */
14#include "winutils.h"
15#include "pxremap.h"
16#include "proxy.h"
17
18#include "lwip/netif.h"
19#include "netif/etharp.h" /* proxy arp hook */
20
21#include "lwip/ip4.h" /* IPv4 divert hook */
22#include "lwip/ip6.h" /* IPv6 divert hook */
23
24#include <string.h>
25
26
27/**
28 * Check if "dst" is an IPv4 address that proxy remaps to host's
29 * loopback.
30 */
31static int
32proxy_ip4_is_mapped_loopback(struct netif *netif, const ip_addr_t *dst, ip_addr_t *lo)
33{
34 u32_t off;
35 const struct ip4_lomap *lomap;
36 size_t i;
37
38 LWIP_ASSERT1(dst != NULL);
39
40 if (g_proxy_options->lomap_desc == NULL) {
41 return 0;
42 }
43
44 if (!ip_addr_netcmp(dst, &netif->ip_addr, &netif->netmask)) {
45 return 0;
46 }
47
48 /* XXX: TODO: check netif is a proxying netif! */
49
50 off = ntohl(ip4_addr_get_u32(dst) & ~ip4_addr_get_u32(&netif->netmask));
51 lomap = g_proxy_options->lomap_desc->lomap;
52 for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) {
53 if (off == lomap[i].off) {
54 if (lo != NULL) {
55 ip_addr_copy(*lo, lomap[i].loaddr);
56 }
57 return 1;
58 }
59 }
60 return 0;
61}
62
63
64#if ARP_PROXY
65/**
66 * Hook function for etharp_arp_input() - returns true to cause proxy
67 * ARP reply to be generated for "dst".
68 */
69int
70pxremap_proxy_arp(struct netif *netif, ip_addr_t *dst)
71{
72 return proxy_ip4_is_mapped_loopback(netif, dst, NULL);
73}
74#endif /* ARP_PROXY */
75
76
77/**
78 * Hook function for ip_forward() - returns true to divert packets to
79 * "dst" to proxy (instead of forwarding them via "netif" or dropping).
80 */
81int
82pxremap_ip4_divert(struct netif *netif, ip_addr_t *dst)
83{
84 return proxy_ip4_is_mapped_loopback(netif, dst, NULL);
85}
86
87
88/**
89 * Mapping from local network to loopback for outbound connections.
90 *
91 * Copy "src" to "dst" with ip_addr_set(dst, src), but if "src" is a
92 * local network address that maps host's loopback address, copy
93 * loopback address to "dst".
94 */
95int
96pxremap_outbound_ip4(ip_addr_t *dst, ip_addr_t *src)
97{
98 struct netif *netif;
99
100 LWIP_ASSERT1(dst != NULL);
101 LWIP_ASSERT1(src != NULL);
102
103 for (netif = netif_list; netif != NULL; netif = netif->next) {
104 if (netif_is_up(netif) /* && this is a proxy netif */) {
105 if (proxy_ip4_is_mapped_loopback(netif, src, dst)) {
106 return PXREMAP_MAPPED;
107 }
108 }
109 }
110
111 /* not remapped, just copy src */
112 ip_addr_set(dst, src);
113 return PXREMAP_ASIS;
114}
115
116
117/**
118 * Mapping from loopback to local network for inbound (port-forwarded)
119 * connections.
120 *
121 * Copy "src" to "dst" with ip_addr_set(dst, src), but if "src" is a
122 * host's loopback address, copy local network address that maps it to
123 * "dst".
124 */
125int
126pxremap_inbound_ip4(ip_addr_t *dst, ip_addr_t *src)
127{
128 struct netif *netif;
129 const struct ip4_lomap *lomap;
130 unsigned int i;
131
132 if (ip4_addr1(src) != IP_LOOPBACKNET) {
133 ip_addr_set(dst, src);
134 return PXREMAP_ASIS;
135 }
136
137 if (g_proxy_options->lomap_desc == NULL) {
138 return PXREMAP_FAILED;
139 }
140
141#if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */
142 netif = ip_route(target);
143 if (netif == NULL) {
144 return PXREMAP_FAILED;
145 }
146#else
147 netif = netif_list;
148 LWIP_ASSERT1(netif != NULL);
149 LWIP_ASSERT1(netif->next == NULL);
150#endif
151
152 lomap = g_proxy_options->lomap_desc->lomap;
153 for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) {
154 if (ip_addr_cmp(src, &lomap[i].loaddr)) {
155 ip_addr_t net;
156
157 ip_addr_get_network(&net, &netif->ip_addr, &netif->netmask);
158 ip4_addr_set_u32(dst,
159 htonl(ntohl(ip4_addr_get_u32(&net))
160 + lomap[i].off));
161 return PXREMAP_MAPPED;
162 }
163 }
164
165 return PXREMAP_FAILED;
166}
167
168
169static int
170proxy_ip6_is_mapped_loopback(struct netif *netif, ip6_addr_t *dst)
171{
172 int i;
173
174 /* XXX: TODO: check netif is a proxying netif! */
175
176 LWIP_ASSERT1(dst != NULL);
177
178 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
179 if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i))
180 && ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)))
181 {
182 ip6_addr_t *ifaddr = netif_ip6_addr(netif, i);
183 if (memcmp(dst, ifaddr, sizeof(ip6_addr_t) - 1) == 0
184 && ((IP6_ADDR_BLOCK8(dst) & 0xff)
185 == (IP6_ADDR_BLOCK8(ifaddr) & 0xff) + 1))
186 {
187 return 1;
188 }
189 }
190 }
191
192 return 0;
193}
194
195
196/**
197 * Hook function for nd6_input() - returns true to cause proxy NA
198 * reply to be generated for "dst".
199 */
200int
201pxremap_proxy_na(struct netif *netif, ip6_addr_t *dst)
202{
203 return proxy_ip6_is_mapped_loopback(netif, dst);
204}
205
206
207/**
208 * Hook function for ip6_forward() - returns true to divert packets to
209 * "dst" to proxy (instead of forwarding them via "netif" or dropping).
210 */
211int
212pxremap_ip6_divert(struct netif *netif, ip6_addr_t *dst)
213{
214 return proxy_ip6_is_mapped_loopback(netif, dst);
215}
216
217
218/**
219 * Mapping from local network to loopback for outbound connections.
220 *
221 * Copy "src" to "dst" with ip6_addr_set(dst, src), but if "src" is a
222 * local network address that maps host's loopback address, copy IPv6
223 * loopback address to "dst".
224 */
225int
226pxremap_outbound_ip6(ip6_addr_t *dst, ip6_addr_t *src)
227{
228 struct netif *netif;
229 int i;
230
231 LWIP_ASSERT1(dst != NULL);
232 LWIP_ASSERT1(src != NULL);
233
234 for (netif = netif_list; netif != NULL; netif = netif->next) {
235 if (!netif_is_up(netif) /* || this is not a proxy netif */) {
236 continue;
237 }
238
239 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
240 if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i))
241 && ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)))
242 {
243 ip6_addr_t *ifaddr = netif_ip6_addr(netif, i);
244 if (memcmp(src, ifaddr, sizeof(ip6_addr_t) - 1) == 0
245 && ((IP6_ADDR_BLOCK8(src) & 0xff)
246 == (IP6_ADDR_BLOCK8(ifaddr) & 0xff) + 1))
247 {
248 ip6_addr_set_loopback(dst);
249 return PXREMAP_MAPPED;
250 }
251 }
252 }
253 }
254
255 /* not remapped, just copy src */
256 ip6_addr_set(dst, src);
257 return PXREMAP_ASIS;
258}
259
260
261/**
262 * Mapping from loopback to local network for inbound (port-forwarded)
263 * connections.
264 *
265 * Copy "src" to "dst" with ip6_addr_set(dst, src), but if "src" is a
266 * host's loopback address, copy local network address that maps it to
267 * "dst".
268 */
269int
270pxremap_inbound_ip6(ip6_addr_t *dst, ip6_addr_t *src)
271{
272 ip6_addr_t loopback;
273 struct netif *netif;
274 int i;
275
276 ip6_addr_set_loopback(&loopback);
277 if (!ip6_addr_cmp(src, &loopback)) {
278 ip6_addr_set(dst, src);
279 return PXREMAP_ASIS;
280 }
281
282#if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */
283 netif = ip6_route_fwd(target);
284 if (netif == NULL) {
285 return PXREMAP_FAILED;
286 }
287#else
288 netif = netif_list;
289 LWIP_ASSERT1(netif != NULL);
290 LWIP_ASSERT1(netif->next == NULL);
291#endif
292
293 for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
294 ip6_addr_t *ifaddr = netif_ip6_addr(netif, i);
295 if (ip6_addr_ispreferred(netif_ip6_addr_state(netif, i))
296 && ip6_addr_isuniquelocal(ifaddr))
297 {
298 ip6_addr_set(dst, ifaddr);
299 ++((u8_t *)&dst->addr[3])[3];
300 return PXREMAP_MAPPED;
301 }
302 }
303
304 return PXREMAP_FAILED;
305}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette