X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fcbcp.c;h=e3566336982709115b1b121e56f3f5526401598c;hp=394f9e40869508f302e0e39e126b12975e07b00d;hb=f1e3aa2dc7e7772d8491c6ff61e4e6d28af33d4b;hpb=f53a48eb9d74db3c71938e114b7f489c339bc003 diff --git a/pppd/cbcp.c b/pppd/cbcp.c index 394f9e4..e356633 100644 --- a/pppd/cbcp.c +++ b/pppd/cbcp.c @@ -33,8 +33,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: cbcp.c,v 1.14 2002/12/04 23:03:32 paulus Exp $" - #include #include #include @@ -45,12 +43,11 @@ #include "fsm.h" #include "lcp.h" -static const char rcsid[] = RCSID; /* * Options. */ -static int setcbcp __P((char **)); +static int setcbcp (char **); static option_t cbcp_option_list[] = { { "callback", o_special, (void *)setcbcp, @@ -61,14 +58,14 @@ static option_t cbcp_option_list[] = { /* * Protocol entry points. */ -static void cbcp_init __P((int unit)); -static void cbcp_open __P((int unit)); -static void cbcp_lowerup __P((int unit)); -static void cbcp_input __P((int unit, u_char *pkt, int len)); -static void cbcp_protrej __P((int unit)); -static int cbcp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); +static void cbcp_init (int unit); +static void cbcp_open (int unit); +static void cbcp_lowerup (int unit); +static void cbcp_input (int unit, u_char *pkt, int len); +static void cbcp_protrej (int unit); +static int cbcp_printpkt (u_char *pkt, int len, + void (*printer)(void *, char *, ...), + void *arg); struct protent cbcp_protent = { PPP_CBCP, @@ -94,16 +91,15 @@ cbcp_state cbcp[NUM_PPP]; /* internal prototypes */ -static void cbcp_recvreq __P((cbcp_state *us, u_char *pckt, int len)); -static void cbcp_resp __P((cbcp_state *us)); -static void cbcp_up __P((cbcp_state *us)); -static void cbcp_recvack __P((cbcp_state *us, u_char *pckt, int len)); -static void cbcp_send __P((cbcp_state *us, int code, u_char *buf, int len)); +static void cbcp_recvreq (cbcp_state *us, u_char *pckt, int len); +static void cbcp_resp (cbcp_state *us); +static void cbcp_up (cbcp_state *us); +static void cbcp_recvack (cbcp_state *us, u_char *pckt, int len); +static void cbcp_send (cbcp_state *us, int code, u_char *buf, int len); /* option processing */ static int -setcbcp(argv) - char **argv; +setcbcp(char **argv) { lcp_wantoptions[0].neg_cbcp = 1; cbcp_protent.enabled_flag = 1; @@ -117,8 +113,7 @@ setcbcp(argv) /* init state */ static void -cbcp_init(iface) - int iface; +cbcp_init(int iface) { cbcp_state *us; @@ -130,8 +125,7 @@ cbcp_init(iface) /* lower layer is up */ static void -cbcp_lowerup(iface) - int iface; +cbcp_lowerup(int iface) { cbcp_state *us = &cbcp[iface]; @@ -143,18 +137,14 @@ cbcp_lowerup(iface) } static void -cbcp_open(unit) - int unit; +cbcp_open(int unit) { dbglog("cbcp_open"); } /* process an incomming packet */ static void -cbcp_input(unit, inpacket, pktlen) - int unit; - u_char *inpacket; - int pktlen; +cbcp_input(int unit, u_char *inpacket, int pktlen) { u_char *inp; u_char code, id; @@ -165,7 +155,8 @@ cbcp_input(unit, inpacket, pktlen) inp = inpacket; if (pktlen < CBCP_MINLEN) { - error("CBCP packet is too small"); + if (debug) + dbglog("CBCP packet is too small"); return; } @@ -173,12 +164,11 @@ cbcp_input(unit, inpacket, pktlen) GETCHAR(id, inp); GETSHORT(len, inp); -#if 0 - if (len > pktlen) { - error("CBCP packet: invalid length"); + if (len > pktlen || len < CBCP_MINLEN) { + if (debug) + dbglog("CBCP packet: invalid length %d", len); return; } -#endif len -= CBCP_MINLEN; @@ -189,11 +179,12 @@ cbcp_input(unit, inpacket, pktlen) break; case CBCP_RESP: - dbglog("CBCP_RESP received"); + if (debug) + dbglog("CBCP_RESP received"); break; case CBCP_ACK: - if (id != us->us_id) + if (debug && id != us->us_id) dbglog("id doesn't match: expected %d recv %d", us->us_id, id); @@ -223,11 +214,8 @@ char *cbcp_optionnames[] = { /* pretty print a packet */ static int -cbcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +cbcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, opt, id, len, olen, delay; u_char *pstart; @@ -301,10 +289,7 @@ cbcp_printpkt(p, plen, printer, arg) /* received CBCP request */ static void -cbcp_recvreq(us, pckt, pcktlen) - cbcp_state *us; - u_char *pckt; - int pcktlen; +cbcp_recvreq(cbcp_state *us, u_char *pckt, int pcktlen) { u_char type, opt_len, delay, addr_type; char address[256]; @@ -312,11 +297,13 @@ cbcp_recvreq(us, pckt, pcktlen) address[0] = 0; - while (len) { + while (len >= 2) { dbglog("length: %d", len); GETCHAR(type, pckt); GETCHAR(opt_len, pckt); + if (opt_len < 2 || opt_len > len) + break; if (opt_len > 2) GETCHAR(delay, pckt); @@ -348,18 +335,23 @@ cbcp_recvreq(us, pckt, pcktlen) } len -= opt_len; } + if (len != 0) { + if (debug) + dbglog("cbcp_recvreq: malformed packet (%d bytes left)", len); + return; + } cbcp_resp(us); } static void -cbcp_resp(us) - cbcp_state *us; +cbcp_resp(cbcp_state *us) { u_char cb_type; u_char buf[256]; u_char *bufp = buf; int len = 0; + int slen; cb_type = us->us_allowed & us->us_type; dbglog("cbcp_resp cb_type=%d", cb_type); @@ -371,12 +363,17 @@ cbcp_resp(us) if (cb_type & ( 1 << CB_CONF_USER ) ) { dbglog("cbcp_resp CONF_USER"); + slen = strlen(us->us_number); + if (slen > 250) { + warn("callback number truncated to 250 characters"); + slen = 250; + } PUTCHAR(CB_CONF_USER, bufp); - len = 3 + 1 + strlen(us->us_number) + 1; + len = 3 + 1 + slen + 1; PUTCHAR(len , bufp); PUTCHAR(5, bufp); /* delay */ PUTCHAR(1, bufp); - BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); + BCOPY(us->us_number, bufp, slen + 1); cbcp_send(us, CBCP_RESP, buf, len); return; } @@ -394,9 +391,8 @@ cbcp_resp(us) if (cb_type & ( 1 << CB_CONF_NO ) ) { dbglog("cbcp_resp CONF_NO"); PUTCHAR(CB_CONF_NO, bufp); - len = 3; + len = 2; PUTCHAR(len , bufp); - PUTCHAR(0, bufp); cbcp_send(us, CBCP_RESP, buf, len); start_networks(us->us_unit); return; @@ -404,11 +400,7 @@ cbcp_resp(us) } static void -cbcp_send(us, code, buf, len) - cbcp_state *us; - int code; - u_char *buf; - int len; +cbcp_send(cbcp_state *us, int code, u_char *buf, int len) { u_char *outp; int outlen; @@ -430,42 +422,42 @@ cbcp_send(us, code, buf, len) } static void -cbcp_recvack(us, pckt, len) - cbcp_state *us; - u_char *pckt; - int len; +cbcp_recvack(cbcp_state *us, u_char *pckt, int len) { u_char type, delay, addr_type; int opt_len; char address[256]; - if (len) { + if (len >= 2) { GETCHAR(type, pckt); GETCHAR(opt_len, pckt); + if (opt_len >= 2 && opt_len <= len) { - if (opt_len > 2) - GETCHAR(delay, pckt); + if (opt_len > 2) + GETCHAR(delay, pckt); - if (opt_len > 4) { - GETCHAR(addr_type, pckt); - memcpy(address, pckt, opt_len - 4); - address[opt_len - 4] = 0; - if (address[0]) - dbglog("peer will call: %s", address); - } - if (type == CB_CONF_NO) - return; - } + if (opt_len > 4) { + GETCHAR(addr_type, pckt); + memcpy(address, pckt, opt_len - 4); + address[opt_len - 4] = 0; + if (address[0]) + dbglog("peer will call: %s", address); + } + if (type == CB_CONF_NO) + return; + + cbcp_up(us); - cbcp_up(us); + } else if (debug) + dbglog("cbcp_recvack: malformed packet"); + } } /* ok peer will do callback */ static void -cbcp_up(us) - cbcp_state *us; +cbcp_up(cbcp_state *us) { persist = 0; - lcp_close(0, "Call me back, please"); status = EXIT_CALLBACK; + lcp_close(0, "Call me back, please"); }