diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 39aeb58e1853..179d51be64ce 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.c,v 1.1.2.70 1998/05/03 22:13:11 brian Exp $ + * $Id: bundle.c,v 1.1.2.71 1998/05/05 03:01:24 brian Exp $ */ #include @@ -522,7 +522,8 @@ bundle_Create(const char *prefix, struct prompt *prompt, int type) bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT; *bundle.cfg.auth.name = '\0'; *bundle.cfg.auth.key = '\0'; - bundle.cfg.opt = OPT_IDCHECK | OPT_LOOPBACK | OPT_THROUGHPUT | OPT_UTMP; + bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK | + OPT_THROUGHPUT | OPT_UTMP; *bundle.cfg.label = '\0'; bundle.cfg.mtu = DEF_MTU; bundle.phys_type = type; @@ -642,7 +643,7 @@ struct rtmsg { char m_space[64]; }; -void +int bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, struct in_addr gateway, struct in_addr mask, int bang) { @@ -651,6 +652,7 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, char *cp; const char *cmdstr; struct sockaddr_in rtdata; + int result = 1; if (bang) cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!"); @@ -659,7 +661,7 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, s = ID0socket(PF_ROUTE, SOCK_RAW, 0); if (s < 0) { log_Printf(LogERROR, "bundle_SetRoute: socket(): %s\n", strerror(errno)); - return; + return result; } memset(&rtmes, '\0', sizeof rtmes); rtmes.m_rtm.rtm_version = RTM_VERSION; @@ -728,10 +730,11 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, failed: if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST || (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) { - if (!bang) + if (!bang) { log_Printf(LogWARN, "Add route failed: %s already exists\n", inet_ntoa(dst)); - else { + result = 0; /* Don't add to our dynamic list */ + } else { rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE; if ((wb = ID0write(s, &rtmes, nb)) < 0) goto failed; @@ -752,6 +755,8 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst, log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n", wb, cmdstr, (unsigned)dst.s_addr, (unsigned)gateway.s_addr); close(s); + + return result; } void @@ -861,12 +866,13 @@ bundle_ShowStatus(struct cmdargs const *arg) int remaining; prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle)); - prompt_Printf(arg->prompt, " Interface: %s\n", arg->bundle->dev); + prompt_Printf(arg->prompt, " Interface: %s\n", arg->bundle->dev); prompt_Printf(arg->prompt, "\nDefaults:\n"); - prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label); - prompt_Printf(arg->prompt, " Auth name: %s\n", arg->bundle->cfg.auth.name); - prompt_Printf(arg->prompt, " Idle Timer: "); + prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label); + prompt_Printf(arg->prompt, " Auth name: %s\n", + arg->bundle->cfg.auth.name); + prompt_Printf(arg->prompt, " Idle Timer: "); if (arg->bundle->cfg.idle_timeout) { prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout); remaining = bundle_RemainingIdleTime(arg->bundle); @@ -875,23 +881,25 @@ bundle_ShowStatus(struct cmdargs const *arg) prompt_Printf(arg->prompt, "\n"); } else prompt_Printf(arg->prompt, "disabled\n"); - prompt_Printf(arg->prompt, " MTU: "); + prompt_Printf(arg->prompt, " MTU: "); if (arg->bundle->cfg.mtu) prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu); else prompt_Printf(arg->prompt, "unspecified\n"); - prompt_Printf(arg->prompt, " ID check: %s\n", + prompt_Printf(arg->prompt, " Sticky Routes: %s\n", + optval(arg->bundle, OPT_SROUTES)); + prompt_Printf(arg->prompt, " ID check: %s\n", optval(arg->bundle, OPT_IDCHECK)); - prompt_Printf(arg->prompt, " Loopback: %s\n", + prompt_Printf(arg->prompt, " Loopback: %s\n", optval(arg->bundle, OPT_LOOPBACK)); - prompt_Printf(arg->prompt, " PasswdAuth: %s\n", + prompt_Printf(arg->prompt, " PasswdAuth: %s\n", optval(arg->bundle, OPT_PASSWDAUTH)); - prompt_Printf(arg->prompt, " Proxy: %s\n", + prompt_Printf(arg->prompt, " Proxy: %s\n", optval(arg->bundle, OPT_PROXY)); - prompt_Printf(arg->prompt, " Throughput: %s\n", + prompt_Printf(arg->prompt, " Throughput: %s\n", optval(arg->bundle, OPT_THROUGHPUT)); - prompt_Printf(arg->prompt, " Utmp: %s\n", + prompt_Printf(arg->prompt, " Utmp Logging: %s\n", optval(arg->bundle, OPT_UTMP)); return 0; diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h index 0676c6be3d40..b89e8908bd53 100644 --- a/usr.sbin/ppp/bundle.h +++ b/usr.sbin/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.h,v 1.1.2.34 1998/04/30 23:53:22 brian Exp $ + * $Id: bundle.h,v 1.1.2.35 1998/05/02 21:57:44 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -37,8 +37,9 @@ #define OPT_LOOPBACK 0x02 #define OPT_PASSWDAUTH 0x04 #define OPT_PROXY 0x08 -#define OPT_THROUGHPUT 0x10 -#define OPT_UTMP 0x20 +#define OPT_SROUTES 0x10 +#define OPT_THROUGHPUT 0x20 +#define OPT_UTMP 0x40 #define MAX_ENDDISC_CLASS 5 @@ -109,8 +110,8 @@ extern const char *bundle_PhaseName(struct bundle *); #define bundle_Phase(b) ((b)->phase) extern void bundle_NewPhase(struct bundle *, u_int); extern int bundle_LinkIsUp(const struct bundle *); -extern void bundle_SetRoute(struct bundle *, int, struct in_addr, - struct in_addr, struct in_addr, int); +extern int bundle_SetRoute(struct bundle *, int, struct in_addr, + struct in_addr, struct in_addr, int); extern void bundle_Close(struct bundle *, const char *, int); extern void bundle_Open(struct bundle *, const char *, int); extern void bundle_LinkClosed(struct bundle *, struct datalink *); diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index b066e8459a8b..a1f9a8c4a1a7 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -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.131.2.76 1998/05/01 19:22:16 brian Exp $ + * $Id: command.c,v 1.131.2.77 1998/05/01 19:24:16 brian Exp $ * */ #include @@ -123,7 +123,7 @@ #define NEG_DNS 50 const char Version[] = "2.0-beta"; -const char VersionDate[] = "$Date: 1998/05/01 19:22:16 $"; +const char VersionDate[] = "$Date: 1998/05/01 19:24:16 $"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -1404,36 +1404,39 @@ static int AddCommand(struct cmdargs const *arg) { struct in_addr dest, gateway, netmask; - int gw; + int gw, addrs; if (arg->argc != arg->argn+3 && arg->argc != arg->argn+2) return -1; + addrs = 0; if (arg->argc == arg->argn+2) { if (strcasecmp(arg->argv[arg->argn], "default")) return -1; - else { - dest.s_addr = netmask.s_addr = INADDR_ANY; - gw = 1; - } + dest.s_addr = netmask.s_addr = INADDR_ANY; + gw = 1; } else { - if (strcasecmp(arg->argv[arg->argn], "MYADDR") == 0) + if (strcasecmp(arg->argv[arg->argn], "MYADDR") == 0) { + addrs = ROUTE_DSTMYADDR; dest = arg->bundle->ncp.ipcp.my_ip; - else if (strcasecmp(arg->argv[arg->argn], "HISADDR") == 0) + } else if (strcasecmp(arg->argv[arg->argn], "HISADDR") == 0) { + addrs = ROUTE_DSTHISADDR; dest = arg->bundle->ncp.ipcp.peer_ip; - else + } else dest = GetIpAddr(arg->argv[arg->argn]); netmask = GetIpAddr(arg->argv[arg->argn+1]); gw = 2; } - if (strcasecmp(arg->argv[arg->argn+gw], "HISADDR") == 0) + if (strcasecmp(arg->argv[arg->argn+gw], "HISADDR") == 0) { gateway = arg->bundle->ncp.ipcp.peer_ip; - else if (strcasecmp(arg->argv[arg->argn+gw], "INTERFACE") == 0) + addrs |= ROUTE_GWHISADDR; + } else if (strcasecmp(arg->argv[arg->argn+gw], "INTERFACE") == 0) gateway.s_addr = INADDR_ANY; else gateway = GetIpAddr(arg->argv[arg->argn+gw]); - bundle_SetRoute(arg->bundle, RTM_ADD, dest, gateway, netmask, - arg->cmd->args ? 1 : 0); + if (bundle_SetRoute(arg->bundle, RTM_ADD, dest, gateway, netmask, + arg->cmd->args ? 1 : 0)) + route_Add(&arg->bundle->ncp.ipcp.route, addrs, dest, netmask, gateway); return 0; } @@ -1441,20 +1444,31 @@ static int DeleteCommand(struct cmdargs const *arg) { struct in_addr dest, none; + int addrs; if (arg->argc == arg->argn+1) { - if(strcasecmp(arg->argv[arg->argn], "all") == 0) + if(strcasecmp(arg->argv[arg->argn], "all") == 0) { route_IfDelete(arg->bundle, 0); - else { - if (strcasecmp(arg->argv[arg->argn], "MYADDR") == 0) + route_DeleteAll(&arg->bundle->ncp.ipcp.route); + } else { + addrs = 0; + if (strcasecmp(arg->argv[arg->argn], "MYADDR") == 0) { dest = arg->bundle->ncp.ipcp.my_ip; - else if (strcasecmp(arg->argv[arg->argn], "default") == 0) - dest.s_addr = INADDR_ANY; - else - dest = GetIpAddr(arg->argv[arg->argn]); + addrs = ROUTE_DSTMYADDR; + } else if (strcasecmp(arg->argv[arg->argn], "HISADDR") == 0) { + dest = arg->bundle->ncp.ipcp.peer_ip; + addrs = ROUTE_DSTHISADDR; + } else { + if (strcasecmp(arg->argv[arg->argn], "default") == 0) + dest.s_addr = INADDR_ANY; + else + dest = GetIpAddr(arg->argv[arg->argn]); + addrs = ROUTE_STATIC; + } none.s_addr = INADDR_ANY; bundle_SetRoute(arg->bundle, RTM_DELETE, dest, none, none, arg->cmd->args ? 1 : 0); + route_Delete(&arg->bundle->ncp.ipcp.route, addrs, dest); } } else return -1; @@ -1757,12 +1771,14 @@ static struct cmdtab const NegotiateCommands[] = { "disable|enable", (const void *)OPT_PASSWDAUTH}, {"proxy", NULL, OptSet, LOCAL_AUTH, "Create proxy ARP entry", "disable|enable", (const void *)OPT_PROXY}, + {"sroutes", NULL, OptSet, LOCAL_AUTH, "Use sticky routes", + "disable|enable", (const void *)OPT_SROUTES}, {"throughput", NULL, OptSet, LOCAL_AUTH, "Rolling throughput", "disable|enable", (const void *)OPT_THROUGHPUT}, {"utmp", NULL, OptSet, LOCAL_AUTH, "Log connections in utmp", "disable|enable", (const void *)OPT_UTMP}, -#define OPT_MAX 6 /* accept/deny allowed below and not above */ +#define OPT_MAX 7 /* accept/deny allowed below and not above */ {"acfcomp", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX, "Address & Control field compression", "accept|deny|disable|enable", diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index 2ac5ba227cd9..591d4d9e5b01 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.50.2.48 1998/04/30 23:53:40 brian Exp $ + * $Id: ipcp.c,v 1.50.2.49 1998/05/01 19:24:49 brian Exp $ * * TODO: * o More RFC1772 backwoard compatibility @@ -69,6 +69,7 @@ #include "arp.h" #include "systems.h" #include "prompt.h" +#include "route.h" #undef REJECTED #define REJECTED(p, x) ((p)->peer_reject & (1<<(x))) @@ -254,51 +255,51 @@ setdns(struct ipcp *ipcp, struct in_addr addr[2]) int ipcp_Show(struct cmdargs const *arg) { - prompt_Printf(arg->prompt, "%s [%s]\n", arg->bundle->ncp.ipcp.fsm.name, - State2Nam(arg->bundle->ncp.ipcp.fsm.state)); - if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED) { + struct ipcp *ipcp = &arg->bundle->ncp.ipcp; + + prompt_Printf(arg->prompt, "%s [%s]\n", ipcp->fsm.name, + State2Nam(ipcp->fsm.state)); + if (ipcp->fsm.state == ST_OPENED) { prompt_Printf(arg->prompt, " His side: %s, %s\n", - inet_ntoa(arg->bundle->ncp.ipcp.peer_ip), - vj2asc(arg->bundle->ncp.ipcp.peer_compproto)); + inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); prompt_Printf(arg->prompt, " My side: %s, %s\n", - inet_ntoa(arg->bundle->ncp.ipcp.my_ip), - vj2asc(arg->bundle->ncp.ipcp.my_compproto)); + inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); + } + + if (ipcp->route) { + prompt_Printf(arg->prompt, "\n"); + route_ShowSticky(arg->prompt, ipcp->route); } prompt_Printf(arg->prompt, "\nDefaults:\n"); prompt_Printf(arg->prompt, " My Address: %s/%d", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.my_range.ipaddr), - arg->bundle->ncp.ipcp.cfg.my_range.width); + inet_ntoa(ipcp->cfg.my_range.ipaddr), ipcp->cfg.my_range.width); - if (arg->bundle->ncp.ipcp.cfg.HaveTriggerAddress) + if (ipcp->cfg.HaveTriggerAddress) prompt_Printf(arg->prompt, " (trigger with %s)", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.TriggerAddress)); + inet_ntoa(ipcp->cfg.TriggerAddress)); prompt_Printf(arg->prompt, "\n VJ compression: %s (%d slots %s slot " - "compression)\n", - command_ShowNegval(arg->bundle->ncp.ipcp.cfg.vj.neg), - arg->bundle->ncp.ipcp.cfg.vj.slots, - arg->bundle->ncp.ipcp.cfg.vj.slotcomp ? "with" : "without"); + "compression)\n", command_ShowNegval(ipcp->cfg.vj.neg), + ipcp->cfg.vj.slots, ipcp->cfg.vj.slotcomp ? "with" : "without"); - if (iplist_isvalid(&arg->bundle->ncp.ipcp.cfg.peer_list)) + if (iplist_isvalid(&ipcp->cfg.peer_list)) prompt_Printf(arg->prompt, " His Address: %s\n", - arg->bundle->ncp.ipcp.cfg.peer_list.src); + ipcp->cfg.peer_list.src); else prompt_Printf(arg->prompt, " His Address: %s/%d\n", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.peer_range.ipaddr), - arg->bundle->ncp.ipcp.cfg.peer_range.width); + inet_ntoa(ipcp->cfg.peer_range.ipaddr), + ipcp->cfg.peer_range.width); prompt_Printf(arg->prompt, " DNS: %s, ", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.ns.dns[0])); - prompt_Printf(arg->prompt, "%s, %s\n", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.ns.dns[1]), - command_ShowNegval(arg->bundle->ncp.ipcp.cfg.ns.dns_neg)); + inet_ntoa(ipcp->cfg.ns.dns[0])); + prompt_Printf(arg->prompt, "%s, %s\n", inet_ntoa(ipcp->cfg.ns.dns[1]), + command_ShowNegval(ipcp->cfg.ns.dns_neg)); prompt_Printf(arg->prompt, " NetBIOS NS: %s, ", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.ns.nbns[0])); - prompt_Printf(arg->prompt, "%s\n", - inet_ntoa(arg->bundle->ncp.ipcp.cfg.ns.nbns[1])); + inet_ntoa(ipcp->cfg.ns.nbns[0])); + prompt_Printf(arg->prompt, "%s\n", inet_ntoa(ipcp->cfg.ns.nbns[1])); prompt_Printf(arg->prompt, "\n"); - throughput_disp(&arg->bundle->ncp.ipcp.throughput, arg->prompt); + throughput_disp(&ipcp->throughput, arg->prompt); return 0; } @@ -340,6 +341,7 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l, fsm_Init(&ipcp->fsm, "IPCP", PROTO_IPCP, 1, IPCP_MAXCODE, 10, LogIPCP, bundle, l, parent, &ipcp_Callbacks, timer_names); + ipcp->route = NULL; ipcp->cfg.vj.slots = DEF_VJ_STATES; ipcp->cfg.vj.slotcomp = 1; memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range); @@ -503,6 +505,9 @@ ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr, return (-1); } + if (Enabled(bundle, OPT_SROUTES)) + route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr); + bundle->ncp.ipcp.peer_ifip.s_addr = hisaddr.s_addr; bundle->ncp.ipcp.my_ifip.s_addr = myaddr.s_addr; @@ -629,6 +634,8 @@ ipcp_CleanInterface(struct ipcp *ipcp) return; } + route_Clean(ipcp->fsm.bundle, ipcp->route); + if (Enabled(ipcp->fsm.bundle, OPT_PROXY)) arp_ClearProxy(ipcp->fsm.bundle, ipcp->peer_ifip, s); diff --git a/usr.sbin/ppp/ipcp.h b/usr.sbin/ppp/ipcp.h index 87e78eda1e09..110bb5db7810 100644 --- a/usr.sbin/ppp/ipcp.h +++ b/usr.sbin/ppp/ipcp.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.h,v 1.18.2.24 1998/04/23 18:56:18 brian Exp $ + * $Id: ipcp.h,v 1.18.2.25 1998/05/01 19:24:53 brian Exp $ * * TODO: */ @@ -34,6 +34,8 @@ #define TY_SECONDARY_NBNS 132 #define TY_ADJUST_NS 119 /* subtract from NS val for REJECT bit */ +struct sticky_route; + struct in_range { struct in_addr ipaddr; struct in_addr mask; @@ -72,6 +74,7 @@ struct ipcp { struct slstat slstat; /* VJ statistics */ } vj; + struct sticky_route *route; /* List of dynamic routes */ unsigned heis1172 : 1; /* True if he is speaking rfc1172 */ diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8 index 0f22f4b19679..e454313f37fb 100644 --- a/usr.sbin/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.97.2.26 1998/05/01 22:39:38 brian Exp $ +.\" $Id: ppp.8,v 1.97.2.27 1998/05/03 22:13:14 brian Exp $ .Dd 20 September 1995 .Os FreeBSD .Dt PPP 8 @@ -486,18 +486,37 @@ connection is established. See the provided .Dq pmdemand example in .Pa /etc/ppp/ppp.conf.sample -which adds a default route. The strings +which runs a script in the background after the connection is established. +The literal strings .Dv HISADDR , .Dv MYADDR and .Dv INTERFACE -are available as the relevent IP addresses and interface name. -Similarly, when a connection is closed, the +may be used, and will be replaced with the relevent IP addresses and interface +name. Similarly, when a connection is closed, the contents of the .Pa /etc/ppp/ppp.linkdown file are executed. Both of these files have the same format as .Pa /etc/ppp/ppp.conf . +.Pp +In previous versions of +.Nm ppp , +it was necessary to re-add routes such as the default route in the +.Pa ppp.linkup +file. +.Nm Ppp +now supports +.Sq sticky routes , +where all routes that contain the +.Dv HISADDR +or +.Dv MYADDR +literals will automatically be updated when the values of +.Dv HISADDR +and/or +.Dv MYADDR +change. .Sh BACKGROUND DIALING If you want to establish a connection using .Nm @@ -507,12 +526,7 @@ entry or an .Xr at 1 job) you should use the .Fl background -option. You must also specify the destination label in -.Pa /etc/ppp/ppp.conf -to use. This label must contain the -.Dq set ifaddr -command to define the remote peers IP address. (refer to -.Pa /etc/ppp/ppp.conf.sample ) +option. When .Fl background is specified, @@ -1214,15 +1228,18 @@ is the IP address which the remote side should use and .Sq netmask is the netmask that should be used. .Sq Src_addr -and +defaults to the current +.Xr hostname 1 , .Sq dst_addr -default to 0.0.0.0, and +defaults to 0.0.0.0, and .Sq netmask defaults to whatever mask is appropriate for .Sq src_addr . It is only possible to make .Sq netmask -smaller than the default. The usual value is 255.255.255.255. +smaller than the default. The usual value is 255.255.255.255, as +most kernels ignore the netmask of a POINTOPOINT interface. +.Pp Some incorrect .Em PPP implementations require that the peer negotiates a specific IP @@ -1458,11 +1475,8 @@ set ifaddr 10.0.0.1/0 10.0.0.2/0 0.0.0.0 0.0.0.0 .Pp .It In most cases, your ISP will also be your default router. If this is -the case, and if you're using -.Fl auto -mode, add the lines +the case, add the line .Bd -literal -offset indent -delete ALL add default HISADDR .Ed .Pp @@ -1471,43 +1485,21 @@ to .Pp This tells .Nm -to delete all non-direct routing entries for the tun interface that -.Nm -is running on, then to add a default route to 10.0.0.2. If you're -not using -.Fl auto -mode, this isn't necessary as -.Nm -will dial immediately and may negotiate new IP numbers with the peer. +to add a default route to whatever the peer address is +.Pq 10.0.0.2 in this example . +This route is +.Sq sticky , +meaning that should the value of +.Dv HISADDR +change, the route will be updated accordingly. .Pp -If you're not using -.Fl auto -mode, or if you're using dynamic IP numbers, you must also put these -two lines in the +Previous versions of +.Nm +required a similar entry in the .Pa /etc/ppp/ppp.linkup -file: -.Bd -literal -offset indent -delete ALL -add default HISADDR -.Ed -.Pp -HISADDR is a macro meaning the "other side"s IP number, and is -available once an IP number has been agreed (using IPCP) or set -.Pq using Dq set ifaddr . -Now, once a connection is established, -.Nm -will delete all non-direct interface routes, and add a default route -pointing at the peers IP number. You should use the same label as the -one used in -.Pa /etc/ppp/ppp.conf . -.Pp -If commands are being typed interactively, the only requirement is -to type -.Bd -literal -offset indent -add default HISADDR -.Ed -.Pp -after a successful dial. +file. Since the advent of +.Sq sticky routes , +his is no longer required. .It If your provider requests that you use PAP/CHAP authentication methods, add the next lines to your @@ -1872,6 +1864,25 @@ is checked before Default: Disabled. Enabling this option will tell .Nm to proxy ARP for the peer. +.It sroutes +Default: Enabled. When the +.Dq add +command is used with the +.Dv HISADDR +or +.Dv MYADDR +values, entries are stored in the +.Sq stick route +list. Each time +.Dv HISADDR +or +.Dv MYADDR +change, this list is re-applied to the routing table. +.Pp +Disabling this option will prevent the re-application of sticky routes, +altough the +.Sq stick route +list will still be maintained. .It throughput Default: Enabled. This option tells .Nm @@ -1903,7 +1914,7 @@ you require the user to both login and authenticate themselves. .Ar Dest is the destination IP address and .Ar mask -is its mask. +is its netmask. .Ar 0 0 refers to the default route, and it is possible to use the symbolic name .Sq default @@ -1915,9 +1926,13 @@ arguments. .Ar Gateway is the next hop gateway to get to the given .Ar dest -machine/network. It is possible to use the symbolic names +machine/network. Refer to the +.Xr route 8 +command for further details. +.Pp +It is possible to use the symbolic names .Sq MYADDR -and +or .Sq HISADDR as the destination, and either .Sq HISADDR @@ -1928,7 +1943,7 @@ as the .Sq MYADDR is replaced with the interface address, .Sq HISADDR -is replaced with the interfaces destination address and +is replaced with the interface destination address and .Sq INTERFACE is replaced with the current interface name. If the interfaces destination address has not yet been assigned @@ -1938,22 +1953,31 @@ the current is used instead of .Sq HISADDR . .Pp -Refer to the -.Dq set ifaddr -command below for details of some restrictions regarding the use of this -command in the -.Pa ppp.conf -file. -.Pp If the .Ar add! command is used -.Pq note the following Dq \&! , +.Pq note the trailing Dq \&! , then if the route already exists, it will be updated as with the .Sq route change command (see .Xr route 8 for further details). +.Pp +Routes that contain the +.Dq HISADDR +or +.Dq MYADDR +constants are considered +.Sq sticky . +They are stored in a list (use +.Dq show ipcp +to see the list), and each time the value of +.Dv HISADDR +or +.Dv MYADDR +changes, the appropriate routing table entries are updated. This facility +may be disabled using +.Dq disable sroutes . .It allow Ar command Op Ar args This command controls access to .Nm @@ -2126,10 +2150,10 @@ 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. If +all non-direct entries in the routing table for the current interface, +and all +.Sq sticky route +entries are deleted. If .Ar dest is specified as .Sq default , @@ -2138,7 +2162,7 @@ the default route is deleted. If the .Ar delete! command is used -.Pq note the following Dq \&! , +.Pq note the trailing Dq \&! , .Nm will not complain if the route does not already exist. .It dial|call Op Ar label @@ -2557,7 +2581,7 @@ and that number is not already in use, .Nm will grant the peers request. This is useful if the peer wants to re-establish a link using the same IP number as was previously -allocated. +allocated (thus maintaining any existing tcp connections). .Pp If the peer requests an IP number that's either outside of this range or is already in use, @@ -2571,8 +2595,9 @@ is specified, it is used in place of in the initial IPCP negotiation. However, only an address in the .Ar myaddr range will be accepted. This is useful when negotiating with some -.Dv PPP implementations that will not assign an IP number unless -their peer requests +.Dv PPP +implementations that will not assign an IP number unless their peer +requests .Ar 0.0.0.0 . .Pp It should be noted that in @@ -2583,27 +2608,15 @@ will configure the interface immediately upon reading the .Dq set ifaddr line in the config file. In any other mode, these values are just used for IPCP negotiations, and the interface isn't configured -until the IPCP layer is up. As a result, it is impossible -.Pq or at least unwise -to use the -.Dq add -command in -.Pa ppp.conf -unless using -.Fl auto -mode (the -.Pa ppp.linkup -file should be used instead). Use -.Dq allow mode auto -to restrict the current profile to -.Fl auto -mode only. +until the IPCP layer is up. .Pp -Note also that the -.Ar hisaddr -argument may be overridden in the +Note that the +.Ar HISADDR +argument may be overridden by the third field in the .Pa ppp.secret -file once the client has authenticated themself. Refer to the +file once the client has authenticated themself +.Pq if PAP or CHAP are Dq enabled . +Refer to the .Em AUTHENTICATING INCOMING CONNECTIONS section for details. .Pp @@ -2987,6 +3000,7 @@ Get port number if port number is using service name. .Xr getty 8 , .Xr group 5 , .Xr gzip 1 , +.Xr hostname 1 , .Xr inetd 8 , .Xr init 8 , .Xr login 1 , diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c index 47fcc36469c2..6bc2d528f465 100644 --- a/usr.sbin/ppp/route.c +++ b/usr.sbin/ppp/route.c @@ -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.42.2.20 1998/04/28 01:25:39 brian Exp $ + * $Id: route.c,v 1.42.2.21 1998/05/01 19:25:46 brian Exp $ * */ @@ -434,3 +434,129 @@ GetIfIndex(char *name) idx++; return -1; } + +void +route_Change(struct bundle *bundle, struct sticky_route *r, + struct in_addr me, struct in_addr peer) +{ + struct in_addr none, del; + + none.s_addr = INADDR_ANY; + for (; r; r = r->next) { + if ((r->type & ROUTE_DSTMYADDR) && r->dst.s_addr != me.s_addr) { + del.s_addr = r->dst.s_addr & r->mask.s_addr; + bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1); + r->dst = me; + if (r->type & ROUTE_GWHISADDR) + r->gw = peer; + } else if ((r->type & ROUTE_DSTHISADDR) && r->dst.s_addr != peer.s_addr) { + del.s_addr = r->dst.s_addr & r->mask.s_addr; + bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1); + r->dst = peer; + if (r->type & ROUTE_GWHISADDR) + r->gw = peer; + } else if ((r->type & ROUTE_GWHISADDR) && r->gw.s_addr != peer.s_addr) + r->gw = peer; + else + continue; + bundle_SetRoute(bundle, RTM_ADD, r->dst, r->gw, r->mask, 1); + } +} + +void +route_Clean(struct bundle *bundle, struct sticky_route *r) +{ + struct in_addr none, del; + + none.s_addr = INADDR_ANY; + for (; r; r = r->next) { + del.s_addr = r->dst.s_addr & r->mask.s_addr; + bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1); + } +} + +void +route_Add(struct sticky_route **rp, int type, struct in_addr dst, + struct in_addr mask, struct in_addr gw) +{ + if (type != ROUTE_STATIC) { + struct sticky_route *r; + int dsttype = type & ROUTE_DSTANY; + + r = NULL; + while (*rp) { + if (dsttype && dsttype == ((*rp)->type & ROUTE_DSTANY)) { + r = *rp; + *rp = r->next; + } else + rp = &(*rp)->next; + } + + if (!r) + r = (struct sticky_route *)malloc(sizeof(struct sticky_route)); + r->type = type; + r->next = NULL; + r->dst = dst; + r->mask = mask; + r->gw = gw; + *rp = r; + } +} + +void +route_Delete(struct sticky_route **rp, int type, struct in_addr dst) +{ + struct sticky_route *r; + int dsttype = type & ROUTE_DSTANY; + + for (; *rp; rp = &(*rp)->next) { + if ((dsttype && dsttype == ((*rp)->type & ROUTE_DSTANY)) || + (!dsttype && dst.s_addr == ((*rp)->dst.s_addr & (*rp)->mask.s_addr))) { + r = *rp; + *rp = r->next; + free(r); + break; + } + } +} + +void +route_DeleteAll(struct sticky_route **rp) +{ + struct sticky_route *r, *rn; + + for (r = *rp; r; r = rn) { + rn = r->next; + free(r); + } + *rp = NULL; +} + +void +route_ShowSticky(struct prompt *p, struct sticky_route *r) +{ + int def; + + prompt_Printf(p, "Sticky routes:\n"); + for (; r; r = r->next) { + def = r->dst.s_addr == INADDR_ANY && r->mask.s_addr == INADDR_ANY; + + prompt_Printf(p, " add "); + if (r->type & ROUTE_DSTMYADDR) + prompt_Printf(p, "MYADDR"); + else if (r->type & ROUTE_DSTHISADDR) + prompt_Printf(p, "HISADDR"); + else if (!def) + prompt_Printf(p, "%s", inet_ntoa(r->dst)); + + if (def) + prompt_Printf(p, "default "); + else + prompt_Printf(p, " %s ", inet_ntoa(r->mask)); + + if (r->type & ROUTE_GWHISADDR) + prompt_Printf(p, "HISADDR\n"); + else + prompt_Printf(p, "%s\n", inet_ntoa(r->gw)); + } +} diff --git a/usr.sbin/ppp/route.h b/usr.sbin/ppp/route.h index 09bade57b3a1..18281d37d3ee 100644 --- a/usr.sbin/ppp/route.h +++ b/usr.sbin/ppp/route.h @@ -17,14 +17,37 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: route.h,v 1.10.2.4 1998/04/07 00:54:17 brian Exp $ + * $Id: route.h,v 1.10.2.5 1998/05/01 19:25:48 brian Exp $ * */ struct bundle; struct cmdargs; +#define ROUTE_STATIC 0 +#define ROUTE_DSTMYADDR 1 +#define ROUTE_DSTHISADDR 2 +#define ROUTE_DSTANY 3 +#define ROUTE_GWHISADDR 4 /* May be ORd with DST_MYADDR */ + +struct sticky_route { + int type; /* ROUTE_* value (not _STATIC) */ + struct sticky_route *next; /* next in list */ + + struct in_addr dst; + struct in_addr mask; + struct in_addr gw; +}; + extern int GetIfIndex(char *); extern int route_Show(struct cmdargs const *); extern void route_IfDelete(struct bundle *, int); extern const char *Index2Nam(int); +extern void route_Change(struct bundle *, struct sticky_route *, + struct in_addr, struct in_addr); +extern void route_Add(struct sticky_route **, int, struct in_addr, + struct in_addr, struct in_addr); +extern void route_Delete(struct sticky_route **, int, struct in_addr); +extern void route_DeleteAll(struct sticky_route **); +extern void route_Clean(struct bundle *, struct sticky_route *); +extern void route_ShowSticky(struct prompt *, struct sticky_route *);