X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fcbcp.c;h=ab069d4b9bfaec77e832a5aca50cc1020c55048e;hp=8add25f09b63887d6e793699afafb6b154530e9f;hb=6e6bb3246106e680463c106d1ee6b773fc4f9c5a;hpb=50f06d79e6f4c457a68929df21d4c71b9d2dade1 diff --git a/pppd/cbcp.c b/pppd/cbcp.c index 8add25f..ab069d4 100644 --- a/pppd/cbcp.c +++ b/pppd/cbcp.c @@ -1,38 +1,51 @@ /* * cbcp - Call Back Configuration Protocol. * - * Copyright (c) 1995 Pedro Roque Marques - * All rights reserved. + * Copyright (c) 1995 Pedro Roque Marques. All rights reserved. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Pedro Roque Marques. The name of the author may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Pedro Roque Marques + * " + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef lint -static char rcsid[] = "$Id: cbcp.c,v 1.4 1999/03/02 05:34:16 paulus Exp $"; -#endif +#define RCSID "$Id: cbcp.c,v 1.16 2004/10/28 00:15:36 paulus Exp $" #include #include #include #include -#include #include "pppd.h" #include "cbcp.h" #include "fsm.h" #include "lcp.h" -#include "ipcp.h" + +static const char rcsid[] = RCSID; /* * Options. @@ -40,8 +53,8 @@ static char rcsid[] = "$Id: cbcp.c,v 1.4 1999/03/02 05:34:16 paulus Exp $"; static int setcbcp __P((char **)); static option_t cbcp_option_list[] = { - { "callback", o_special, setcbcp, - "Ask for callback" }, + { "callback", o_special, (void *)setcbcp, + "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number }, { NULL } }; @@ -70,8 +83,8 @@ struct protent cbcp_protent = { NULL, 0, "CBCP", - cbcp_option_list, NULL, + cbcp_option_list, NULL, NULL, NULL @@ -81,11 +94,11 @@ cbcp_state cbcp[NUM_PPP]; /* internal prototypes */ -static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len)); +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, char *pckt, int len)); -static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len)); +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)); /* option processing */ static int @@ -122,18 +135,18 @@ cbcp_lowerup(iface) { cbcp_state *us = &cbcp[iface]; - syslog(LOG_DEBUG, "cbcp_lowerup"); - syslog(LOG_DEBUG, "want: %d", us->us_type); + dbglog("cbcp_lowerup"); + dbglog("want: %d", us->us_type); if (us->us_type == CB_CONF_USER) - syslog(LOG_DEBUG, "phone no: %s", us->us_number); + dbglog("phone no: %s", us->us_number); } static void cbcp_open(unit) int unit; { - syslog(LOG_DEBUG, "cbcp_open"); + dbglog("cbcp_open"); } /* process an incomming packet */ @@ -152,7 +165,8 @@ cbcp_input(unit, inpacket, pktlen) inp = inpacket; if (pktlen < CBCP_MINLEN) { - syslog(LOG_ERR, "CBCP packet is too small"); + if (debug) + dbglog("CBCP packet is too small"); return; } @@ -160,12 +174,11 @@ cbcp_input(unit, inpacket, pktlen) GETCHAR(id, inp); GETSHORT(len, inp); -#if 0 - if (len > pktlen) { - syslog(LOG_ERR, "CBCP packet: invalid length"); + if (len > pktlen || len < CBCP_MINLEN) { + if (debug) + dbglog("CBCP packet: invalid length %d", len); return; } -#endif len -= CBCP_MINLEN; @@ -176,12 +189,13 @@ cbcp_input(unit, inpacket, pktlen) break; case CBCP_RESP: - syslog(LOG_DEBUG, "CBCP_RESP received"); + if (debug) + dbglog("CBCP_RESP received"); break; case CBCP_ACK: - if (id != us->us_id) - syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d", + if (debug && id != us->us_id) + dbglog("id doesn't match: expected %d recv %d", us->us_id, id); cbcp_recvack(us, inp, len); @@ -271,8 +285,8 @@ cbcp_printpkt(p, plen, printer, arg) printer(arg, " number = %s", str); } printer(arg, ">"); - break; } + break; default: break; @@ -290,7 +304,7 @@ cbcp_printpkt(p, plen, printer, arg) static void cbcp_recvreq(us, pckt, pcktlen) cbcp_state *us; - char *pckt; + u_char *pckt; int pcktlen; { u_char type, opt_len, delay, addr_type; @@ -299,11 +313,13 @@ cbcp_recvreq(us, pckt, pcktlen) address[0] = 0; - while (len) { - syslog(LOG_DEBUG, "length: %d", 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); @@ -312,22 +328,22 @@ cbcp_recvreq(us, pckt, pcktlen) switch(type) { case CB_CONF_NO: - syslog(LOG_DEBUG, "no callback allowed"); + dbglog("no callback allowed"); break; case CB_CONF_USER: - syslog(LOG_DEBUG, "user callback allowed"); + dbglog("user callback allowed"); if (opt_len > 4) { GETCHAR(addr_type, pckt); memcpy(address, pckt, opt_len - 4); address[opt_len - 4] = 0; if (address[0]) - syslog(LOG_DEBUG, "address: %s", address); + dbglog("address: %s", address); } break; case CB_CONF_ADMIN: - syslog(LOG_DEBUG, "user admin defined allowed"); + dbglog("user admin defined allowed"); break; case CB_CONF_LIST: @@ -335,6 +351,11 @@ 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); } @@ -347,9 +368,10 @@ cbcp_resp(us) u_char buf[256]; u_char *bufp = buf; int len = 0; + int slen; cb_type = us->us_allowed & us->us_type; - syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type); + dbglog("cbcp_resp cb_type=%d", cb_type); #if 0 if (!cb_type) @@ -357,19 +379,24 @@ cbcp_resp(us) #endif if (cb_type & ( 1 << CB_CONF_USER ) ) { - syslog(LOG_DEBUG, "cbcp_resp 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; } if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { - syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN"); + dbglog("cbcp_resp CONF_ADMIN"); PUTCHAR(CB_CONF_ADMIN, bufp); len = 3; PUTCHAR(len, bufp); @@ -379,13 +406,12 @@ cbcp_resp(us) } if (cb_type & ( 1 << CB_CONF_NO ) ) { - syslog(LOG_DEBUG, "cbcp_resp 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); - (*ipcp_protent.open)(us->us_unit); + start_networks(us->us_unit); return; } } @@ -393,7 +419,7 @@ cbcp_resp(us) static void cbcp_send(us, code, buf, len) cbcp_state *us; - u_char code; + int code; u_char *buf; int len; { @@ -419,33 +445,37 @@ cbcp_send(us, code, buf, len) static void cbcp_recvack(us, pckt, len) cbcp_state *us; - char *pckt; + 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]) - syslog(LOG_DEBUG, "peer will call: %s", address); - } - } + 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); -extern int persist; + } else if (debug) + dbglog("cbcp_recvack: malformed packet"); + } +} /* ok peer will do callback */ static void @@ -454,4 +484,5 @@ cbcp_up(us) { persist = 0; lcp_close(0, "Call me back, please"); + status = EXIT_CALLBACK; }