* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static char rcsid[] = "$Id: ipcp.c,v 1.46 1999/05/13 00:35:23 paulus Exp $";
-#endif
+#define RCSID "$Id: ipcp.c,v 1.52 1999/12/23 01:25:33 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 */
+/* Hook for a plugin to know when IP protocol has come up */
+void (*ip_up_hook) __P((void)) = NULL;
+
+/* Hook for a plugin to know when IP protocol has come down */
+void (*ip_down_hook) __P((void)) = NULL;
+
/* local vars */
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 */
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 *));
struct hostent *hp;
dns = inet_addr(*argv);
- if (dns == -1) {
+ if (dns == (u_int32_t) -1) {
if ((hp = gethostbyname(*argv)) == NULL) {
option_error("invalid address parameter '%s' for ms-dns option",
*argv);
struct hostent *hp;
wins = inet_addr(*argv);
- if (wins == -1) {
+ if (wins == (u_int32_t) -1) {
if ((hp = gethostbyname(*argv)) == NULL) {
option_error("invalid address parameter '%s' for ms-wins option",
*argv);
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;
+ *go = *wo;
+ if (disable_defaultip)
+ go->ouraddr = 0;
}
* 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])
np_up(f->unit, PPP_IP);
ipcp_is_up = 1;
+ if (ip_up_hook)
+ ip_up_hook();
+
/*
* Execute the ip-up script, like this:
* /etc/ppp/ip-up interface tty speed local-IP remote-IP
/* 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 (ip_down_hook)
+ ip_down_hook();
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;