X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipcp.c;h=734f7413e013024ff464894b383f72d0ac028253;hp=f20257931721952fb8b7a967c7d3d739f12c35eb;hb=9420784901517dbd06185b874d2a2bed3b8f6e25;hpb=6a34bc9a3edf435bc67e81755b65acb6786c98b3 diff --git a/pppd/ipcp.c b/pppd/ipcp.c index f202579..734f741 100644 --- a/pppd/ipcp.c +++ b/pppd/ipcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: ipcp.c,v 1.13 1994/10/22 11:54:04 paulus Exp $"; +static char rcsid[] = "$Id: ipcp.c,v 1.22 1995/12/18 03:45:56 paulus Exp $"; #endif /* @@ -38,13 +38,13 @@ static char rcsid[] = "$Id: ipcp.c,v 1.13 1994/10/22 11:54:04 paulus Exp $"; #include "pathnames.h" /* global vars */ -ipcp_options ipcp_wantoptions[N_PPP]; /* Options that we want to request */ -ipcp_options ipcp_gotoptions[N_PPP]; /* Options that peer ack'd */ -ipcp_options ipcp_allowoptions[N_PPP]; /* Options we allow peer to request */ -ipcp_options ipcp_hisoptions[N_PPP]; /* Options that we ack'd */ +ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ /* local vars */ -static int cis_received[N_PPP]; /* # Conf-Reqs received */ +static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ /* * Callbacks for fsm code. (CI = Configuration Information) @@ -60,7 +60,7 @@ static void ipcp_up __P((fsm *)); /* We're UP */ static void ipcp_down __P((fsm *)); /* We're DOWN */ static void ipcp_script __P((fsm *, char *)); /* Run an up/down script */ -fsm ipcp_fsm[N_PPP]; /* IPCP fsm structure */ +fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ ipcp_resetci, /* Reset our Configuration Information */ @@ -80,6 +80,12 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ "IPCP" /* String name of protocol */ }; +struct protent ipcp_protent = { + PPP_IPCP, ipcp_init, ipcp_input, ipcp_protrej, + ipcp_lowerup, ipcp_lowerdown, ipcp_open, ipcp_close, + ipcp_printpkt, NULL, 1, "IPCP" +}; + /* * Lengths of configuration options. */ @@ -130,13 +136,11 @@ ipcp_init(unit) f->callbacks = &ipcp_callbacks; fsm_init(&ipcp_fsm[unit]); - wo->neg_addr = 1; - wo->old_addrs = 0; - wo->ouraddr = 0; - wo->hisaddr = 0; + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + wo->neg_addr = 1; wo->neg_vj = 1; - wo->old_vj = 0; wo->vj_protocol = IPCP_VJ_COMP; wo->maxslotindex = MAX_STATES - 1; /* really max index */ wo->cflag = 1; @@ -149,6 +153,13 @@ ipcp_init(unit) ao->neg_vj = 1; ao->maxslotindex = MAX_STATES - 1; ao->cflag = 1; + + /* + * XXX These control whether the user may use the proxyarp + * and defaultroute options. + */ + ao->proxy_arp = 1; + ao->default_route = 1; } @@ -167,10 +178,11 @@ ipcp_open(unit) * ipcp_close - Take IPCP down. */ void -ipcp_close(unit) +ipcp_close(unit, reason) int unit; + char *reason; { - fsm_close(&ipcp_fsm[unit]); + fsm_close(&ipcp_fsm[unit], reason); } @@ -575,16 +587,15 @@ ipcp_nakci(f, p, len) case CI_ADDR: if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) goto bad; - try.neg_addr = 1; try.old_addrs = 0; GETLONG(l, p); ciaddr1 = htonl(l); if (ciaddr1 && go->accept_local) try.ouraddr = ciaddr1; + if (try.ouraddr != 0) + try.neg_addr = 1; no.neg_addr = 1; break; - default: - goto bad; } p = next; } @@ -774,10 +785,17 @@ ipcp_reqci(f, inp, len, reject_if_disagree) && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof (long), p); + DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * If neither we nor he knows his address, reject the option. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; } /* @@ -791,7 +809,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree) if (ciaddr2 == 0 || !wo->accept_local) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof (long), p); + DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->ouraddr); PUTLONG(tl, p); } @@ -828,15 +846,62 @@ ipcp_reqci(f, inp, len, reject_if_disagree) && (ciaddr1 == 0 || !wo->accept_remote)) { orc = CONFNAK; if (!reject_if_disagree) { - DECPTR(sizeof (long), p); + DECPTR(sizeof(u_int32_t), p); tl = ntohl(wo->hisaddr); PUTLONG(tl, p); } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * Don't ACK an address of 0.0.0.0 - reject it instead. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; } ho->neg_addr = 1; ho->hisaddr = ciaddr1; break; + +#ifdef USE_MS_DNS + case CI_MS_DNS1: + /* Microsoft primary DNS request */ + IPCPDEBUG((LOG_INFO, "ipcp: received DNS1 Request ")); + + /* If we do not have a DNS address then we cannot send it */ + if (ao->dnsaddr[0] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->dnsaddr[0]) { + DECPTR(sizeof(u_int32_t), p); + tl = ntohl(ao->dnsaddr[0]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; + + case CI_MS_DNS2: + /* Microsoft secondary DNS request */ + IPCPDEBUG((LOG_INFO, "ipcp: received DNS2 Request ")); + + /* If we do not have a DNS address then we cannot send it */ + if (ao->dnsaddr[1] == 0 || /* Yes, this is the first one! */ + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->dnsaddr[1]) { /* and this is the 2nd one */ + DECPTR(sizeof(u_int32_t), p); + tl = ntohl(ao->dnsaddr[1]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; +#endif case CI_COMPRESSTYPE: IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE ")); @@ -874,7 +939,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree) } } ho->maxslotindex = maxslotindex; - ho->cflag = wo->cflag; + ho->cflag = cflag; } else { ho->old_vj = 1; ho->maxslotindex = MAX_STATES - 1; @@ -972,12 +1037,12 @@ ipcp_up(f) if (ho->hisaddr == 0) { syslog(LOG_ERR, "Could not determine remote IP address"); - ipcp_close(f->unit); + ipcp_close(f->unit, "Could not determine remote IP address"); return; } if (go->ouraddr == 0) { syslog(LOG_ERR, "Could not determine local IP address"); - ipcp_close(f->unit); + ipcp_close(f->unit, "Could not determine local IP address"); return; } @@ -987,7 +1052,7 @@ ipcp_up(f) if (!auth_ip_addr(f->unit, ho->hisaddr)) { syslog(LOG_ERR, "Peer is not authorized to use remote address %s", ip_ntoa(ho->hisaddr)); - ipcp_close(f->unit); + ipcp_close(f->unit, "Unauthorized remote IP address"); return; } @@ -1000,7 +1065,7 @@ ipcp_up(f) mask = GetMask(go->ouraddr); if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { IPCPDEBUG((LOG_WARNING, "sifaddr failed")); - ipcp_close(f->unit); + ipcp_close(f->unit, "Interface configuration failed"); return; } @@ -1010,7 +1075,7 @@ ipcp_up(f) /* bring the interface up for IP */ if (!sifup(f->unit)) { IPCPDEBUG((LOG_WARNING, "sifup failed")); - ipcp_close(f->unit); + ipcp_close(f->unit, "Interface configuration failed"); return; } @@ -1083,7 +1148,8 @@ ipcp_script(f, script) argv[3] = strspeed; argv[4] = strlocal; argv[5] = strremote; - argv[6] = NULL; + argv[6] = ipparam; + argv[7] = NULL; run_program(script, argv, 0); }