* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static const char rcsid[] = "$Id: ipcp.c,v 1.48 1999/08/12 04:25:20 paulus Exp $";
-#endif
+#define RCSID "$Id: ipcp.c,v 1.55 2000/06/30 04:54:20 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;
+
+/* Hook for a plugin to choose the remote IP address */
+void (*ip_choose_hook) __P((u_int32_t *)) = 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 */
static bool usepeerdns; /* Ask peer for DNS addrs */
static int ipcp_is_up; /* have called np_up() */
+static bool ask_for_local; /* request our address from peer */
/*
* Callbacks for fsm code. (CI = Configuration Information)
{ "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
"Disable VJ connection-ID compression", OPT_A2COPY,
&ipcp_allowoptions[0].cflag },
- { "vj-max-slots", 1, setvjslots,
+ { "vj-max-slots", 1, (void *)setvjslots,
"Set maximum VJ header slots" },
{ "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
"Accept peer's address for us", 1 },
"Set ip script parameter" },
{ "noipdefault", o_bool, &disable_defaultip,
"Don't use name for default IP adrs", 1 },
- { "ms-dns", 1, setdnsaddr,
+ { "ms-dns", 1, (void *)setdnsaddr,
"DNS address for the peer's use" },
- { "ms-wins", 1, setwinsaddr,
+ { "ms-wins", 1, (void *)setwinsaddr,
"Nameserver for SMB over TCP/IP for peer" },
{ "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
"Set timeout for IPCP" },
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);
ipcp_options *go = &ipcp_gotoptions[f->unit];
wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
- if (wo->ouraddr == 0 || disable_defaultip)
+ if (wo->ouraddr == 0)
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;
*go = *wo;
- if (disable_defaultip)
+ if (!ask_for_local)
go->ouraddr = 0;
+ if (ip_choose_hook)
+ ip_choose_hook(&wo->hisaddr);
}
* Default our local IP address based on our hostname.
* If local IP address already given, don't bother.
*/
- if (wo->ouraddr == 0) {
+ if (wo->ouraddr == 0 && !disable_defaultip) {
/*
* 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
+ ask_for_local = wo->ouraddr != 0 || !disable_defaultip;
}
{
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;
+ ask_for_local = 0; /* don't tell the peer this address */
+ }
if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
return 0;
if (!sifup(u))
if (!ho->neg_addr)
ho->hisaddr = wo->hisaddr;
- if (ho->hisaddr == 0) {
- error("Could not determine remote IP address");
- ipcp_close(f->unit, "Could not determine remote IP address");
- return;
- }
if (go->ouraddr == 0) {
error("Could not determine local IP address");
ipcp_close(f->unit, "Could not determine local IP address");
return;
}
- script_setenv("IPLOCAL", ip_ntoa(go->ouraddr));
- script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr));
+ if (ho->hisaddr == 0) {
+ ho->hisaddr = htonl(0x0a404040 + ifunit);
+ warn("Could not determine remote IP address: defaulting to %I",
+ ho->hisaddr);
+ }
+ script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
+ script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
- script_setenv("USEPEERDNS", "1");
+ script_setenv("USEPEERDNS", "1", 0);
if (go->dnsaddr[0])
- script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]));
+ script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
if (go->dnsaddr[1])
- script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]));
+ script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
}
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));
+ script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
wo->ouraddr = go->ouraddr;
} else
script_unsetenv("OLDIPLOCAL");
if (ho->hisaddr != wo->hisaddr) {
warn("Remote IP address changed to %I", ho->hisaddr);
- script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr));
+ script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
wo->hisaddr = ho->hisaddr;
} else
script_unsetenv("OLDIPREMOTE");
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_gotoptions[f->unit].ouraddr,
ipcp_hisoptions[f->unit].hisaddr);
case TERMREQ:
if (len > 0 && *p >= ' ' && *p < 0x7f) {
printer(arg, " ");
- print_string(p, len, printer, arg);
+ print_string((char *)p, len, printer, arg);
p += len;
len = 0;
}