* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static char rcsid[] = "$Id: ipcp.c,v 1.44 1999/04/12 06:24:45 paulus Exp $";
-#endif
+#define RCSID "$Id: ipcp.c,v 1.50 1999/08/24 05:31:09 paulus Exp $"
/*
* TODO:
#include "ipcp.h"
#include "pathnames.h"
+static const char rcsid[] = RCSID;
+
/* global vars */
ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
/* local vars */
-static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
static int default_route_set[NUM_PPP]; /* Have set up a default route */
static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
static bool usepeerdns; /* Ask peer for DNS addrs */
ip_active_pkt
};
-static void ipcp_clear_addrs __P((int));
+static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
static void ipcp_script __P((char *)); /* Run an up/down script */
static void ipcp_script_done __P((void *));
fsm *f;
{
ipcp_options *wo = &ipcp_wantoptions[f->unit];
+ ipcp_options *go = &ipcp_gotoptions[f->unit];
wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
- if (wo->ouraddr == 0)
+ if (wo->ouraddr == 0 || disable_defaultip)
wo->accept_local = 1;
if (wo->hisaddr == 0)
wo->accept_remote = 1;
wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */
wo->req_dns2 = usepeerdns;
- ipcp_gotoptions[f->unit] = *wo;
- cis_received[f->unit] = 0;
+ *go = *wo;
+ if (disable_defaultip)
+ go->ouraddr = 0;
}
}
if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
/* try an older style of VJ negotiation */
- if (cis_received[f->unit] == 0) {
- /* keep trying the new style until we see some CI from the peer */
+ /* use the old style only if the peer did */
+ if (ho->neg_vj && ho->old_vj) {
go->neg_vj = 1;
- } else {
- /* use the old style only if the peer did */
- if (ho->neg_vj && ho->old_vj) {
- go->neg_vj = 1;
- go->old_vj = 1;
- go->vj_protocol = ho->vj_protocol;
- }
+ go->old_vj = 1;
+ go->vj_protocol = ho->vj_protocol;
}
}
u_char maxslotindex, cflag;
int d;
- cis_received[f->unit] = 1;
-
/*
* Reset all his options.
*/
* Default our local IP address based on our hostname.
* If local IP address already given, don't bother.
*/
- if (wo->ouraddr == 0 && !disable_defaultip) {
+ if (wo->ouraddr == 0) {
/*
* Look up our hostname (possibly with domain name appended)
* and take the first IP address as our local IP address.
wo->ouraddr = local;
}
}
-
- if (demand && wo->hisaddr == 0) {
- option_error("remote IP address required for demand-dialling\n");
- exit(1);
- }
-#if 0
- if (demand && wo->accept_remote) {
- option_error("ipcp-accept-remote is incompatible with demand\n");
- exit(1);
- }
-#endif
}
{
ipcp_options *wo = &ipcp_wantoptions[u];
+ if (wo->hisaddr == 0) {
+ /* make up an arbitrary address for the peer */
+ wo->hisaddr = htonl(0x0a707070 + ifunit);
+ wo->accept_remote = 1;
+ }
+ if (wo->ouraddr == 0) {
+ /* make up an arbitrary address for us */
+ wo->ouraddr = htonl(0x0a404040 + ifunit);
+ wo->accept_local = 1;
+ disable_defaultip = 1; /* don't tell the peer this address */
+ }
if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
return 0;
if (!sifup(u))
*/
if (demand) {
if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
+ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
if (go->ouraddr != wo->ouraddr) {
warn("Local IP address changed to %I", go->ouraddr);
script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr));
wo->hisaddr = ho->hisaddr;
} else
script_unsetenv("OLDIPREMOTE");
- ipcp_clear_addrs(f->unit);
/* Set the interface to the new addresses */
mask = GetMask(go->ouraddr);
if (sifproxyarp(f->unit, ho->hisaddr))
proxy_arp_set[f->unit] = 1;
+ ipcp_wantoptions[0].ouraddr = go->ouraddr;
+
notice("local IP address %I", go->ouraddr);
notice("remote IP address %I", ho->hisaddr);
if (go->dnsaddr[0])
fsm *f;
{
IPCPDEBUG(("ipcp: down"));
- if (get_ppp_stats(f->unit, &link_stats))
- link_stats_valid = 1;
+ /* XXX a bit IPv4-centric here, we only need to get the stats
+ * before the interface is marked down. */
+ update_link_stats(f->unit);
if (ipcp_is_up) {
ipcp_is_up = 0;
np_down(f->unit, PPP_IP);
if (demand) {
sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
} else {
+ sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
sifdown(f->unit);
- ipcp_clear_addrs(f->unit);
+ ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
+ ipcp_hisoptions[f->unit].hisaddr);
}
/* Execute the ip-down script */
* proxy arp entries, etc.
*/
static void
-ipcp_clear_addrs(unit)
+ipcp_clear_addrs(unit, ouraddr, hisaddr)
int unit;
+ u_int32_t ouraddr; /* local address */
+ u_int32_t hisaddr; /* remote address */
{
- u_int32_t ouraddr, hisaddr;
-
- ouraddr = ipcp_gotoptions[unit].ouraddr;
- hisaddr = ipcp_hisoptions[unit].hisaddr;
if (proxy_arp_set[unit]) {
cifproxyarp(unit, hisaddr);
proxy_arp_set[unit] = 0;
case CI_MS_DNS2:
p += 2;
GETLONG(cilong, p);
- printer(arg, "ms-dns %I", htonl(cilong));
+ printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1,
+ htonl(cilong));
break;
case CI_MS_WINS1:
case CI_MS_WINS2: