Because the host and guest share the same IP address with passt/pasta, it's not possible for the guest to directly address the host. Therefore we allow packets from the guest going to a special "NAT to host" address to be redirected to the host, appearing there as though they have both source and destination address of loopback. Currently that special address is always the address of the default gateway. That can be a problem if we want that gateway to be addressable by the guest. Therefore, allow the special "NAT to host" address to be overridden on the command line. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- conf.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/conf.c b/conf.c index 45f49eb..ea56003 100644 --- a/conf.c +++ b/conf.c @@ -849,6 +849,12 @@ static void usage(const char *name) else info(" --no-dhcp-search No list in DHCP/DHCPv6/NDP"); + info( " -H, --nat-to-host ADDR NAT packets sent to ADDR to go to host"); + info( " NATted packets will appear on the host to have come from"); + info( " foopback. Can be specified zero to two times (for IPv4 and IPv6)"); + info( " default: gateway address, or no NAT if --no-map-gw is also"); + info( " specified"); + info( " --dns-forward ADDR Forward DNS queries sent to ADDR"); info( " can be specified zero to two times (for IPv4 and IPv6)"); info( " default: don't forward DNS queries"); @@ -987,6 +993,11 @@ static void conf_print(const struct ctx *c) c->mac[3], c->mac[4], c->mac[5]); if (c->ifi4) { + if (!IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost)) + info(" NAT for host 127.0.0.1: %s", + inet_ntop(AF_INET, &c->ip4.nattohost, + buf4, sizeof(buf4))); + if (!c->no_dhcp) { uint32_t mask; @@ -1016,6 +1027,11 @@ static void conf_print(const struct ctx *c) } if (c->ifi6) { + if (!IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost)) + info(" NAT for host ::1: %s", + inet_ntop(AF_INET6, &c->ip6.nattohost, + buf6, sizeof(buf6))); + if (!c->no_ndp && !c->no_dhcpv6) info("NDP/DHCPv6:"); else if (!c->no_ndp) @@ -1191,6 +1207,7 @@ void conf(struct ctx *c, int argc, char **argv) {"netmask", required_argument, NULL, 'n' }, {"mac-addr", required_argument, NULL, 'M' }, {"gateway", required_argument, NULL, 'g' }, + {"host", required_argument, NULL, 'H' }, {"interface", required_argument, NULL, 'i' }, {"outbound", required_argument, NULL, 'o' }, {"dns", required_argument, NULL, 'D' }, @@ -1245,9 +1262,9 @@ void conf(struct ctx *c, int argc, char **argv) if (c->mode == MODE_PASTA) { c->no_dhcp_dns = c->no_dhcp_dns_search = 1; - optstring = "dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:"; + optstring = "dqfel:hF:I:p:P:m:a:n:M:g:i:o:D:S:46t:u:T:U:H:"; } else { - optstring = "dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:"; + optstring = "dqfel:hs:F:p:P:m:a:n:M:g:i:o:D:S:461t:u:H:"; } c->tcp.fwd_in.mode = c->tcp.fwd_out.mode = 0; @@ -1548,6 +1565,23 @@ void conf(struct ctx *c, int argc, char **argv) die("Invalid gateway address: %s", optarg); break; + case 'H': + if (IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost) && + inet_pton(AF_INET6, optarg, &c->ip6.nattohost)&& + !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.nattohost) && + !IN6_IS_ADDR_LOOPBACK(&c->ip6.nattohost)) + break; + + if (IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost) && + inet_pton(AF_INET, optarg, &c->ip4.nattohost) && + !IN4_IS_ADDR_UNSPECIFIED(&c->ip4.nattohost) && + !IN4_IS_ADDR_BROADCAST(&c->ip4.nattohost) && + !IN4_IS_ADDR_LOOPBACK(&c->ip4.nattohost)) + break; + + err("Invalid host remap address: %s", optarg); + usage(argv[0]); + break; case 'i': if (ifi4 || ifi6) die("Redundant interface: %s", optarg); -- 2.40.1