ipconfig(8): add -t flag to enable source address translation

This commit is contained in:
cinap_lenrek 2022-03-13 17:29:16 +00:00
parent 6e4a1fda8c
commit c8507f428f
4 changed files with 62 additions and 28 deletions

View file

@ -5,7 +5,7 @@ ipconfig, rip, linklocal \- Internet configuration and routing
.in +0.25i
.ti -0.25i
.B ip/ipconfig
.RB [ -6DGNOPdnpruX ]
.RB [ -6DGNOPdnprtuX ]
.RB [ -b
.IR baud ]
.RB [ -c
@ -223,6 +223,10 @@ This option directs
.I ipconfig
instead to fork a background process that keeps trying forever.
.TP
.B t
enable source address translation on the interface and default route.
(only usefull for IPv4).
.TP
.B u
disable IPv6 duplicate discovery detection,
which removes any existing ARP table entry for one of our IPv6 addresses

View file

@ -116,6 +116,7 @@ void usage(void);
int ip4cfg(void);
void ipunconfig(void);
void setroutetag(char*);
void adddefroute(uchar*, uchar*, uchar*, uchar*);
void removedefroute(uchar*, uchar*, uchar*, uchar*);

View file

@ -354,8 +354,8 @@ arpcheck(uchar *ip)
int
ip6cfg(void)
{
int tentative, n;
char buf[256];
int tentative, n;
if(!validip(conf.laddr) || isv4(conf.laddr))
return -1;
@ -372,12 +372,12 @@ Again:
if(!validip(conf.mask))
ipmove(conf.mask, defmask(conf.laddr));
n += snprint(buf+n, sizeof buf-n, " %M", conf.mask);
if(validip(conf.raddr)){
n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
if(conf.mtu != 0)
n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
}
if(!validip(conf.raddr) || isv4(conf.raddr))
maskip(conf.laddr, conf.mask, conf.raddr);
n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
DEBUG("ip6cfg: %.*s", n, buf);
if(write(conf.cfd, buf, n) < 0){
warning("write(%s): %r", buf);
return -1;
@ -1134,8 +1134,7 @@ startra6(void)
void
doipv6(int what)
{
fprint(conf.rfd, "tag ra6");
setroutetag("ra6");
switch (what) {
default:
sysfatal("unknown IPv6 verb");

View file

@ -24,6 +24,7 @@ int dolog;
int plan9 = 1;
int Oflag;
int rflag;
int tflag;
int dodhcp;
int nodhcpwatch;
@ -53,7 +54,7 @@ static int Ufmt(Fmt*);
void
usage(void)
{
fprint(2, "usage: %s [-6dDGnNOpPruX][-b baud][-c ctl]* [-g gw]"
fprint(2, "usage: %s [-6dDGnNOpPrtuX][-b baud][-c ctl]* [-g gw]"
"[-h host][-m mtu]\n"
"\t[-f dbfile][-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask "
"[raddr [fs [auth]]]]]\n", argv0);
@ -383,6 +384,9 @@ main(int argc, char **argv)
case 'r':
rflag = 1;
break;
case 't':
tflag = 1;
break;
case 'u': /* IPv6: duplicate neighbour disc. off */
dupl_disc = 0;
break;
@ -462,7 +466,7 @@ doadd(void)
/* run dhcp if we need something */
if(dodhcp){
fprint(conf.rfd, "tag dhcp");
setroutetag("dhcp");
dhcpquery(!noconfig, Sselecting);
}
@ -587,12 +591,14 @@ ip4cfg(void)
ipmove(conf.mask, defmask(conf.laddr));
n += snprint(buf+n, sizeof buf-n, " %M", conf.mask);
if(validip(conf.raddr)){
n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
if(conf.mtu != 0)
n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
}
if(!validip(conf.raddr) || !isv4(conf.raddr))
maskip(conf.laddr, conf.mask, conf.raddr);
n += snprint(buf+n, sizeof buf-n, " %I", conf.raddr);
n += snprint(buf+n, sizeof buf-n, " %d", conf.mtu);
if(tflag)
n += snprint(buf+n, sizeof buf-n, " trans");
DEBUG("ip4cfg: %.*s", n, buf);
if(write(conf.cfd, buf, n) < 0){
warning("write(%s): %r", buf);
return -1;
@ -602,6 +608,9 @@ ip4cfg(void)
&& ipcmp(conf.gaddr, conf.laddr) != 0)
adddefroute(conf.gaddr, conf.laddr, conf.laddr, conf.mask);
if(tflag)
fprint(conf.cfd, "iprouting 1");
return 0;
}
@ -726,6 +735,15 @@ putndb(void)
close(fd);
}
static char *routetag = "none";
void
setroutetag(char *tag)
{
routetag = tag;
fprint(conf.rfd, "tag %s", routetag);
}
static int
issrcspec(uchar *src, uchar *smask)
{
@ -733,18 +751,22 @@ issrcspec(uchar *src, uchar *smask)
}
static void
routectl(char *cmd, uchar *dst, uchar *mask, uchar *gate, uchar *ia, uchar *src, uchar *smask)
routectl(char *cmd, uchar *dst, uchar *mask, uchar *gate, char *flags, uchar *ia, uchar *src, uchar *smask)
{
char *ctl;
if(issrcspec(src, smask))
ctl = "%s %I %M %I %I %I %M";
else
ctl = "%s %I %M %I %I";
DEBUG(ctl, cmd, dst, mask, gate, ia, src, smask);
if(conf.rfd < 0)
if(*flags == '\0'){
if(!issrcspec(src, smask))
ctl = "%s %I %M %I %I";
else
ctl = "%s %I %M %I %I %I %M";
DEBUG(ctl, cmd, dst, mask, gate, ia, src, smask);
fprint(conf.rfd, ctl, cmd, dst, mask, gate, ia, src, smask);
return;
fprint(conf.rfd, ctl, cmd, dst, mask, gate, ia, src, smask);
}
ctl = "%s %I %M %I %s %s %I %I %M";
DEBUG(ctl, cmd, dst, mask, gate, flags, routetag, ia, src, smask);
fprint(conf.rfd, ctl, cmd, dst, mask, gate, flags, routetag, ia, src, smask);
}
static void
@ -765,11 +787,18 @@ defroutectl(char *cmd, uchar *gaddr, uchar *ia, uchar *src, uchar *smask)
if(smask == nil)
smask = IPnoaddr;
}
routectl(cmd, dst, mask, gaddr, ia, src, smask);
/* also add a source specific route */
if(ipcmp(src, IPnoaddr) != 0 && ipcmp(src, v4prefix) != 0)
routectl(cmd, dst, mask, gaddr, ia, src, IPallbits);
if(tflag && isv4(gaddr)){
/* add route for everyone with source translation */
routectl(cmd, dst, mask, gaddr, "4t", ia, dst, mask);
} else {
/* add route for subnet */
routectl(cmd, dst, mask, gaddr, "", ia, src, smask);
}
/* add source specific route for us */
if(validip(src))
routectl(cmd, dst, mask, gaddr, "", ia, src, IPallbits);
}
void
@ -1016,6 +1045,7 @@ ndb2conf(Ndb *db, uchar *myip)
ipmove(conf.mask, defmask(conf.laddr));
memset(conf.raddr, 0, sizeof(conf.raddr));
memset(conf.gaddr, 0, sizeof(conf.gaddr));
memset(conf.dns, 0, sizeof(conf.dns));
memset(conf.ntp, 0, sizeof(conf.ntp));