X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fipcp.c;h=334d8922a2e6046e147b151bfd563d66438bdc05;hp=36d53829e3090490e8fe087800297515f1e044d1;hb=1b9f7635dd45d643b2fb7cf496f67789892897c5;hpb=cfeda08c9caa6410ce3a5ebab961e6f571512206 diff --git a/pppd/ipcp.c b/pppd/ipcp.c index 36d5382..334d892 100644 --- a/pppd/ipcp.c +++ b/pppd/ipcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: ipcp.c,v 1.2 1994/02/08 23:49:52 paulus Exp $"; +static char rcsid[] = "$Id: ipcp.c,v 1.10 1994/09/01 00:22:38 paulus Exp $"; #endif /* @@ -26,24 +26,16 @@ static char rcsid[] = "$Id: ipcp.c,v 1.2 1994/02/08 23:49:52 paulus Exp $"; */ #include +#include #include -#include #include #include -#include - -#include -#include -#include -#include - -#include #include "pppd.h" #include "ppp.h" #include "fsm.h" #include "ipcp.h" - +#include "pathnames.h" /* global vars */ ipcp_options ipcp_wantoptions[NPPP]; /* Options that we want to request */ @@ -66,7 +58,7 @@ static int ipcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */ static int ipcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv CI */ static void ipcp_up __ARGS((fsm *)); /* We're UP */ static void ipcp_down __ARGS((fsm *)); /* We're DOWN */ - +static void ipcp_script __ARGS((fsm *, char *)); /* Run an up/down script */ fsm ipcp_fsm[NPPP]; /* IPCP fsm structure */ @@ -107,7 +99,7 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ */ char * ip_ntoa(ipaddr) -u_long ipaddr; +uint32 ipaddr; { static char b[64]; @@ -300,7 +292,7 @@ ipcp_addci(f, ucp, lenp) if (neg) { \ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ if (len >= addrlen) { \ - u_long l; \ + uint32 l; \ PUTCHAR(opt, ucp); \ PUTCHAR(addrlen, ucp); \ l = ntohl(val1); \ @@ -363,7 +355,7 @@ ipcp_ackci(f, p, len) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_short cilen, citype, cishort; - u_long cilong; + uint32 cilong; u_char cimaxslotindex, cicflag; /* @@ -398,7 +390,7 @@ ipcp_ackci(f, p, len) #define ACKCIADDR(opt, neg, old, val1, val2) \ if (neg) { \ int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - u_long l; \ + uint32 l; \ if ((len -= addrlen) < 0) \ goto bad; \ GETCHAR(citype, p); \ @@ -455,7 +447,7 @@ ipcp_nakci(f, p, len) u_char cimaxslotindex, cicflag; u_char citype, cilen, *next; u_short cishort; - u_long ciaddr1, ciaddr2, l; + uint32 ciaddr1, ciaddr2, l; ipcp_options no; /* options we've seen Naks for */ ipcp_options try; /* options to request next time */ @@ -494,10 +486,6 @@ ipcp_nakci(f, p, len) len -= cilen; \ INCPTR(2, p); \ GETSHORT(cishort, p); \ - if (cilen == CILEN_VJ) { \ - GETCHAR(cimaxslotindex, p); \ - GETCHAR(cicflag, p); \ - } \ no.neg = 1; \ code \ } @@ -508,12 +496,12 @@ ipcp_nakci(f, p, len) */ NAKCIADDR(CI_ADDR, neg_addr, go->old_addrs, if (go->accept_local && ciaddr1) { /* Do we know our address? */ - go->ouraddr = ciaddr1; + try.ouraddr = ciaddr1; IPCPDEBUG((LOG_INFO, "local IP address %s", ip_ntoa(ciaddr1))); } if (go->accept_remote && ciaddr2) { /* Does he know his? */ - go->hisaddr = ciaddr2; + try.hisaddr = ciaddr2; IPCPDEBUG((LOG_INFO, "remote IP address %s", ip_ntoa(ciaddr2))); } @@ -527,6 +515,8 @@ ipcp_nakci(f, p, len) */ NAKCIVJ(CI_COMPRESSTYPE, neg_vj, if (cilen == CILEN_VJ) { + GETCHAR(cimaxslotindex, p); + GETCHAR(cicflag, p); if (cishort == IPCP_VJ_COMP) { try.old_vj = 0; if (cimaxslotindex < go->maxslotindex) @@ -629,7 +619,7 @@ ipcp_rejci(f, p, len) ipcp_options *go = &ipcp_gotoptions[f->unit]; u_char cimaxslotindex, ciflag, cilen; u_short cishort; - u_long cilong; + uint32 cilong; ipcp_options try; /* options to request next time */ try = *go; @@ -643,7 +633,7 @@ ipcp_rejci(f, p, len) len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ p[1] == cilen && \ p[0] == opt) { \ - u_long l; \ + uint32 l; \ len -= cilen; \ INCPTR(2, p); \ GETLONG(l, p); \ @@ -728,7 +718,7 @@ ipcp_reqci(f, inp, len, reject_if_disagree) u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ u_short cishort; /* Parsed short value */ - u_long tl, ciaddr1, ciaddr2;/* Parsed address values */ + uint32 tl, ciaddr1, ciaddr2;/* Parsed address values */ int rc = CONFACK; /* Final packet return code */ int orc; /* Individual option return code */ u_char *p; /* Pointer to next char to parse */ @@ -809,8 +799,6 @@ ipcp_reqci(f, inp, len, reject_if_disagree) go->ouraddr = ciaddr2; /* accept peer's idea */ } } - if (orc == CONFNAK) - break; ho->neg_addr = 1; ho->old_addrs = 1; @@ -846,9 +834,6 @@ ipcp_reqci(f, inp, len, reject_if_disagree) } } - if (orc == CONFNAK) - break; - ho->neg_addr = 1; ho->hisaddr = ciaddr1; break; @@ -888,10 +873,12 @@ ipcp_reqci(f, inp, len, reject_if_disagree) PUTCHAR(wo->cflag, p); } } - if (orc == CONFNAK) - break; ho->maxslotindex = maxslotindex; ho->cflag = wo->cflag; + } else { + ho->old_vj = 1; + ho->maxslotindex = MAX_STATES - 1; + ho->cflag = 1; } break; @@ -969,7 +956,7 @@ static void ipcp_up(f) fsm *f; { - u_long mask; + uint32 mask; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; @@ -995,7 +982,7 @@ ipcp_up(f) } /* - * Check that the peer is allowed to use the IP address he wants. + * Check that the peer is allowed to use the IP address it wants. */ if (!auth_ip_addr(f->unit, ho->hisaddr)) { syslog(LOG_ERR, "Peer is not authorized to use remote address %s", @@ -1018,7 +1005,7 @@ ipcp_up(f) } /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag); + sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); /* bring the interface up for IP */ if (!sifup(f->unit)) { @@ -1036,6 +1023,13 @@ ipcp_up(f) if (ipcp_wantoptions[f->unit].proxy_arp) if (sifproxyarp(f->unit, ho->hisaddr)) go->proxy_arp = 1; + + /* + * Execute the ip-up script, like this: + * /etc/ppp/ip-up interface tty speed local-IP remote-IP + */ + ipcp_script(f, _PATH_IPUP); + } @@ -1049,7 +1043,7 @@ static void ipcp_down(f) fsm *f; { - u_long ouraddr, hisaddr; + uint32 ouraddr, hisaddr; IPCPDEBUG((LOG_INFO, "ipcp: down")); @@ -1061,4 +1055,138 @@ ipcp_down(f) cifdefaultroute(f->unit, hisaddr); sifdown(f->unit); cifaddr(f->unit, ouraddr, hisaddr); + + /* Execute the ip-down script */ + ipcp_script(f, _PATH_IPDOWN); +} + + +/* + * ipcp_script - Execute a script with arguments + * interface-name tty-name speed local-IP remote-IP. + */ +static void +ipcp_script(f, script) + fsm *f; + char *script; +{ + char strspeed[32], strlocal[32], strremote[32]; + char *argv[8]; + + sprintf(strspeed, "%d", baud_rate); + strcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr)); + strcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr)); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strlocal; + argv[5] = strremote; + argv[6] = NULL; + run_program(script, argv, 0); +} + +/* + * ipcp_printpkt - print the contents of an IPCP packet. + */ +char *ipcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +int +ipcp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer)(); + void *arg; +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + uint32 cilong; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) + printer(arg, " %s", ipcp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_ADDRS: + if (olen == CILEN_ADDRS) { + p += 2; + GETLONG(cilong, p); + printer(arg, "addrs %s", ip_ntoa(htonl(cilong))); + GETLONG(cilong, p); + printer(arg, " %s", ip_ntoa(htonl(cilong))); + } + break; + case CI_COMPRESSTYPE: + if (olen >= CILEN_COMPRESS) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "compress "); + switch (cishort) { + case IPCP_VJ_COMP: + printer(arg, "VJ"); + break; + case IPCP_VJ_COMP_OLD: + printer(arg, "old-VJ"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_ADDR: + if (olen == CILEN_ADDR) { + p += 2; + GETLONG(cilong, p); + printer(arg, "addr %s", ip_ntoa(htonl(cilong))); + } + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; }