Only allow one arg to `delete' - the mask & gateway aren't necessary.

Delete AF_LINK routes as well as AF_INET.
Allow the word `default' as the arg to `delete' or in place of the
first two args (dest & netmask) to `add'.
Accept INTERFACE as the third arg to `add'.

  You can now say `add default interface' to create a default route
  through the tun interface.  It's reported that subsequent bind()s
  will bind to a broadcast address and not to the address currently
  assigned to the tun device - this is the first step towards
  supporting that first connection that was around from before the
  dynamic IP negotiation....
This commit is contained in:
Brian Somers 1997-12-07 04:09:15 +00:00
parent 20fa828fac
commit f01e577b07
4 changed files with 170 additions and 126 deletions

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.105 1997/11/22 03:37:28 brian Exp $
* $Id: command.c,v 1.106 1997/11/23 20:05:18 brian Exp $
*
*/
#include <sys/param.h>
@ -1461,51 +1461,55 @@ static int
AddCommand(struct cmdargs const *arg)
{
struct in_addr dest, gateway, netmask;
int gw;
if (arg->argc == 3) {
if (arg->argc != 3 && arg->argc != 2)
return -1;
if (arg->argc == 2)
if (strcasecmp(arg->argv[0], "default"))
return -1;
else {
dest.s_addr = netmask.s_addr = INADDR_ANY;
gw = 1;
}
else {
if (strcasecmp(arg->argv[0], "MYADDR") == 0)
dest = IpcpInfo.want_ipaddr;
else
dest = GetIpAddr(arg->argv[0]);
netmask = GetIpAddr(arg->argv[1]);
if (strcasecmp(arg->argv[2], "HISADDR") == 0)
gateway = IpcpInfo.his_ipaddr;
else
gateway = GetIpAddr(arg->argv[2]);
OsSetRoute(RTM_ADD, dest, gateway, netmask);
return 0;
gw = 2;
}
return -1;
if (strcasecmp(arg->argv[gw], "HISADDR") == 0)
gateway = IpcpInfo.his_ipaddr;
else if (strcasecmp(arg->argv[gw], "INTERFACE") == 0)
gateway.s_addr = INADDR_ANY;
else
gateway = GetIpAddr(arg->argv[gw]);
OsSetRoute(RTM_ADD, dest, gateway, netmask);
return 0;
}
static int
DeleteCommand(struct cmdargs const *arg)
{
struct in_addr dest, gateway, netmask;
struct in_addr dest, none;
if (arg->argc == 1 && strcasecmp(arg->argv[0], "all") == 0)
DeleteIfRoutes(0);
else if (arg->argc > 0 && arg->argc < 4) {
if (strcasecmp(arg->argv[0], "MYADDR") == 0)
dest = IpcpInfo.want_ipaddr;
else
dest = GetIpAddr(arg->argv[0]);
netmask.s_addr = INADDR_ANY;
if (arg->argc > 1) {
if (strcasecmp(arg->argv[1], "HISADDR") == 0)
gateway = IpcpInfo.his_ipaddr;
if (arg->argc == 1)
if(strcasecmp(arg->argv[0], "all") == 0)
DeleteIfRoutes(0);
else {
if (strcasecmp(arg->argv[0], "MYADDR") == 0)
dest = IpcpInfo.want_ipaddr;
else if (strcasecmp(arg->argv[0], "default") == 0)
dest.s_addr = INADDR_ANY;
else
gateway = GetIpAddr(arg->argv[1]);
if (arg->argc == 3) {
if (inet_aton(arg->argv[2], &netmask) == 0) {
LogPrintf(LogWARN, "Bad netmask value.\n");
return -1;
}
}
} else
gateway.s_addr = INADDR_ANY;
OsSetRoute(RTM_DELETE, dest, gateway, netmask);
} else
dest = GetIpAddr(arg->argv[0]);
none.s_addr = INADDR_ANY;
OsSetRoute(RTM_DELETE, dest, none, none);
}
else
return -1;
return 0;

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.81 1997/12/03 10:23:51 brian Exp $
.\" $Id: ppp.8,v 1.82 1997/12/03 23:27:59 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -353,12 +353,12 @@ PPP ON awfulhak> add 0 0 HISADDR
The string
.Sq HISADDR
represents the IP address of the connected peer. This variable is only
available once a connection has been established. A common error
is to specify the above command in your
.Pa /etc/ppp/ppp.conf
file. This won't work as the remote IP address hasn't been
established when this file is read.
represents the IP address of the connected peer. It is possible to
use the keyword
.Sq INTERFACE
in place of
.Sq HISADDR .
This will create a direct route on the tun interface.
You can now use your network applications (ping, telnet, ftp etc.)
in other windows on your machine.
@ -1738,16 +1738,34 @@ you require the user to both login and authenticate themselves.
.El
.It add dest mask gateway
.Dq Dest
.Ar Dest
is the destination IP address and
.Dq mask
.Ar mask
is its mask.
.Dq 0 0
refers to the default route.
.Dq Gateway
.Ar 0 0
refers to the default route, and it is possible to use the symbolic name
.Sq default
in place of both the
.Ar dest
and
.Ar mask
arguments.
.Ar Gateway
is the next hop gateway to get to the given
.Dq dest
machine/network.
.Ar dest
machine/network. It is possible to use the symbolic names
.Sq HISADDR
or
.Sq INTERFACE
as the
.Ar gateway .
.Sq INTERFACE
is replaced with the current interface name and
.Sq HISADDR
is replaced with the current interface address. If the current interface
address has not yet been assigned, the current
.Sq INTERFACE
is used instead.
.It allow .....
This command controls access to
@ -1895,24 +1913,21 @@ command instead.
.It close
Close the current connection (but don't quit).
.It delete ALL | dest [gateway [mask]]
If
.Dq ALL
is specified, all non-direct entries in the routing for the interface
that
.It delete dest
This command deletes the route with the given
.Ar dest
IP address. If
.Ar dest
is specified as
.Sq ALL ,
all non-direct entries in the routing for the current interface that
.Nm
is using are deleted. This means all entries for tunN, except the entry
representing the actual link. When
.Dq ALL
is not used, any existing route with the given
.Dq dest ,
destination network
.Dq mask
and
.Dq gateway
is deleted. The default
.Dq mask
value is 0.0.0.0.
representing the actual link. If
.Ar dest
is specified as
.Sq default ,
the default route is deleted.
.It dial|call [remote]
If

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.81 1997/12/03 10:23:51 brian Exp $
.\" $Id: ppp.8,v 1.82 1997/12/03 23:27:59 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -353,12 +353,12 @@ PPP ON awfulhak> add 0 0 HISADDR
The string
.Sq HISADDR
represents the IP address of the connected peer. This variable is only
available once a connection has been established. A common error
is to specify the above command in your
.Pa /etc/ppp/ppp.conf
file. This won't work as the remote IP address hasn't been
established when this file is read.
represents the IP address of the connected peer. It is possible to
use the keyword
.Sq INTERFACE
in place of
.Sq HISADDR .
This will create a direct route on the tun interface.
You can now use your network applications (ping, telnet, ftp etc.)
in other windows on your machine.
@ -1738,16 +1738,34 @@ you require the user to both login and authenticate themselves.
.El
.It add dest mask gateway
.Dq Dest
.Ar Dest
is the destination IP address and
.Dq mask
.Ar mask
is its mask.
.Dq 0 0
refers to the default route.
.Dq Gateway
.Ar 0 0
refers to the default route, and it is possible to use the symbolic name
.Sq default
in place of both the
.Ar dest
and
.Ar mask
arguments.
.Ar Gateway
is the next hop gateway to get to the given
.Dq dest
machine/network.
.Ar dest
machine/network. It is possible to use the symbolic names
.Sq HISADDR
or
.Sq INTERFACE
as the
.Ar gateway .
.Sq INTERFACE
is replaced with the current interface name and
.Sq HISADDR
is replaced with the current interface address. If the current interface
address has not yet been assigned, the current
.Sq INTERFACE
is used instead.
.It allow .....
This command controls access to
@ -1895,24 +1913,21 @@ command instead.
.It close
Close the current connection (but don't quit).
.It delete ALL | dest [gateway [mask]]
If
.Dq ALL
is specified, all non-direct entries in the routing for the interface
that
.It delete dest
This command deletes the route with the given
.Ar dest
IP address. If
.Ar dest
is specified as
.Sq ALL ,
all non-direct entries in the routing for the current interface that
.Nm
is using are deleted. This means all entries for tunN, except the entry
representing the actual link. When
.Dq ALL
is not used, any existing route with the given
.Dq dest ,
destination network
.Dq mask
and
.Dq gateway
is deleted. The default
.Dq mask
value is 0.0.0.0.
representing the actual link. If
.Ar dest
is specified as
.Sq default ,
the default route is deleted.
.It dial|call [remote]
If

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: route.c,v 1.28 1997/11/22 13:46:02 brian Exp $
* $Id: route.c,v 1.29 1997/12/04 18:49:39 brian Exp $
*
*/
@ -51,6 +51,7 @@
#include "route.h"
static int IfIndex;
static const char *Index2Nam(int);
struct rtmsg {
struct rt_msghdr m_rtm;
@ -69,7 +70,6 @@ OsSetRoute(int cmd,
int s, nb, wb;
char *cp;
const char *cmdstr;
u_long *lp;
struct sockaddr_in rtdata;
cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
@ -81,7 +81,7 @@ OsSetRoute(int cmd,
memset(&rtmes, '\0', sizeof(rtmes));
rtmes.m_rtm.rtm_version = RTM_VERSION;
rtmes.m_rtm.rtm_type = cmd;
rtmes.m_rtm.rtm_addrs = RTA_DST | RTA_NETMASK;
rtmes.m_rtm.rtm_addrs = RTA_DST;
rtmes.m_rtm.rtm_seq = ++seqno;
rtmes.m_rtm.rtm_pid = getpid();
rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
@ -95,24 +95,43 @@ OsSetRoute(int cmd,
cp = rtmes.m_space;
memcpy(cp, &rtdata, 16);
cp += 16;
if (gateway.s_addr) {
rtdata.sin_addr = gateway;
memcpy(cp, &rtdata, 16);
cp += 16;
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
}
if (cmd == RTM_ADD)
if (gateway.s_addr == INADDR_ANY) {
/* Add a route through the interface */
struct sockaddr_dl dl;
const char *iname;
int ilen;
iname = Index2Nam(IfIndex);
ilen = strlen(iname);
dl.sdl_len = sizeof(dl)-sizeof(dl.sdl_data)+ilen;
dl.sdl_family = AF_LINK;
dl.sdl_index = IfIndex;
dl.sdl_type = 0;
dl.sdl_nlen = ilen;
dl.sdl_alen = 0;
dl.sdl_slen = 0;
strcpy(dl.sdl_data, iname);
memcpy(cp, &dl, dl.sdl_len);
cp += dl.sdl_len;
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
} else {
rtdata.sin_addr = gateway;
memcpy(cp, &rtdata, 16);
cp += 16;
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
}
if (dst.s_addr == INADDR_ANY)
mask.s_addr = INADDR_ANY;
lp = (u_long *) cp;
if (mask.s_addr) {
*lp++ = 8;
cp += sizeof(int);
*lp = mask.s_addr;
} else
*lp = 0;
cp += sizeof(u_long);
if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
rtdata.sin_addr = mask;
memcpy(cp, &rtdata, 16);
cp += 16;
rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
}
nb = cp - (char *) &rtmes;
rtmes.m_rtm.rtm_msglen = nb;
@ -401,13 +420,13 @@ DeleteIfRoutes(int all)
{
struct rt_msghdr *rtm;
struct sockaddr *sa;
struct in_addr sa_dst, sa_gw, sa_mask;
struct in_addr sa_dst, sa_none;
int needed;
char *sp, *cp, *ep;
u_char *wp;
int mib[6];
LogPrintf(LogDEBUG, "DeleteIfRoutes (%d)\n", IfIndex);
sa_none.s_addr = INADDR_ANY;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
@ -446,24 +465,15 @@ DeleteIfRoutes(int all)
rtm->rtm_index == IfIndex &&
(all || (rtm->rtm_flags & RTF_GATEWAY))) {
sa_dst.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
wp = (u_char *) cp + rtm->rtm_msglen;
sa = (struct sockaddr *)((char *)sa + sa->sa_len);
if (sa->sa_family == AF_INET) {
if (sa->sa_family == AF_INET || sa->sa_family == AF_LINK) {
LogPrintf(LogDEBUG, "DeleteIfRoutes: Remove it\n");
sa_gw.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
sa = (struct sockaddr *)((char *)sa + sa->sa_len);
if (rtm->rtm_addrs & RTA_NETMASK)
sa_mask.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
else
sa_mask.s_addr = 0xffffffff;
if (sa_dst.s_addr == INADDR_ANY)
sa_mask.s_addr = INADDR_ANY;
LogPrintf(LogDEBUG, "DeleteIfRoutes: Dst: %s\n", inet_ntoa(sa_dst));
LogPrintf(LogDEBUG, "DeleteIfRoutes: Gw: %s\n", inet_ntoa(sa_gw));
LogPrintf(LogDEBUG, "DeleteIfRoutes: Index: %d\n", rtm->rtm_index);
OsSetRoute(RTM_DELETE, sa_dst, sa_gw, sa_mask);
OsSetRoute(RTM_DELETE, sa_dst, sa_none, sa_none);
} else
LogPrintf(LogDEBUG, "DeleteIfRoutes: Can't remove an AF_LINK !\n");
LogPrintf(LogDEBUG,
"DeleteIfRoutes: Can't remove routes of %d family !\n",
sa->sa_family);
}
}
free(sp);