Version of http://mbed.org/cookbook/NetServicesTribute with setting set the same for LPC2368

Dependents:   UDPSocketExample 24LCxx_I2CApp WeatherPlatform_pachube HvZServerLib ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pap.c Source File

pap.c

00001 /*****************************************************************************
00002 * pap.c - Network Password Authentication Protocol program file.
00003 *
00004 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
00005 * portions Copyright (c) 1997 by Global Election Systems Inc.
00006 *
00007 * The authors hereby grant permission to use, copy, modify, distribute,
00008 * and license this software and its documentation for any purpose, provided
00009 * that existing copyright notices are retained in all copies and that this
00010 * notice and the following disclaimer are included verbatim in any 
00011 * distributions. No written agreement, license, or royalty fee is required
00012 * for any of the authorized uses.
00013 *
00014 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
00015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
00017 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024 *
00025 ******************************************************************************
00026 * REVISION HISTORY
00027 *
00028 * 03-01-01 Marc Boucher <marc@mbsi.ca>
00029 *   Ported to lwIP.
00030 * 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
00031 *   Original.
00032 *****************************************************************************/
00033 /*
00034  * upap.c - User/Password Authentication Protocol.
00035  *
00036  * Copyright (c) 1989 Carnegie Mellon University.
00037  * All rights reserved.
00038  *
00039  * Redistribution and use in source and binary forms are permitted
00040  * provided that the above copyright notice and this paragraph are
00041  * duplicated in all such forms and that any documentation,
00042  * advertising materials, and other materials related to such
00043  * distribution and use acknowledge that the software was developed
00044  * by Carnegie Mellon University.  The name of the
00045  * University may not be used to endorse or promote products derived
00046  * from this software without specific prior written permission.
00047  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00048  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00049  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00050  */
00051 
00052 #include "lwip/opt.h"
00053 
00054 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
00055 
00056 #if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
00057 
00058 #include "ppp.h"
00059 #include "pppdebug.h"
00060 
00061 #include "auth.h"
00062 #include "pap.h"
00063 
00064 #include <string.h>
00065 
00066 #if 0 /* UNUSED */
00067 static bool hide_password = 1;
00068 
00069 /*
00070  * Command-line options.
00071  */
00072 static option_t pap_option_list[] = {
00073     { "hide-password", o_bool, &hide_password,
00074       "Don't output passwords to log", 1 },
00075     { "show-password", o_bool, &hide_password,
00076       "Show password string in debug log messages", 0 },
00077     { "pap-restart", o_int, &upap[0].us_timeouttime,
00078       "Set retransmit timeout for PAP" },
00079     { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
00080       "Set max number of transmissions for auth-reqs" },
00081     { "pap-timeout", o_int, &upap[0].us_reqtimeout,
00082       "Set time limit for peer PAP authentication" },
00083     { NULL }
00084 };
00085 #endif
00086 
00087 /*
00088  * Protocol entry points.
00089  */
00090 static void upap_init      (int);
00091 static void upap_lowerup   (int);
00092 static void upap_lowerdown (int);
00093 static void upap_input     (int, u_char *, int);
00094 static void upap_protrej   (int);
00095 #if PPP_ADDITIONAL_CALLBACKS
00096 static int  upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
00097 #endif /* PPP_ADDITIONAL_CALLBACKS */
00098 
00099 struct protent pap_protent = {
00100   PPP_PAP,
00101   upap_init,
00102   upap_input,
00103   upap_protrej,
00104   upap_lowerup,
00105   upap_lowerdown,
00106   NULL,
00107   NULL,
00108 #if PPP_ADDITIONAL_CALLBACKS
00109   upap_printpkt,
00110   NULL,
00111 #endif /* PPP_ADDITIONAL_CALLBACKS */
00112   1,
00113   "PAP",
00114 #if PPP_ADDITIONAL_CALLBACKS
00115   NULL,
00116   NULL,
00117   NULL
00118 #endif /* PPP_ADDITIONAL_CALLBACKS */
00119 };
00120 
00121 upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
00122 
00123 static void upap_timeout   (void *);
00124 static void upap_reqtimeout(void *);
00125 static void upap_rauthreq  (upap_state *, u_char *, u_char, int);
00126 static void upap_rauthack  (upap_state *, u_char *, int, int);
00127 static void upap_rauthnak  (upap_state *, u_char *, int, int);
00128 static void upap_sauthreq  (upap_state *);
00129 static void upap_sresp     (upap_state *, u_char, u_char, char *, int);
00130 
00131 
00132 /*
00133  * upap_init - Initialize a UPAP unit.
00134  */
00135 static void
00136 upap_init(int unit)
00137 {
00138   upap_state *u = &upap[unit];
00139 
00140   UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
00141   u->us_unit         = unit;
00142   u->us_user         = NULL;
00143   u->us_userlen      = 0;
00144   u->us_passwd       = NULL;
00145   u->us_passwdlen    = 0;
00146   u->us_clientstate  = UPAPCS_INITIAL;
00147   u->us_serverstate  = UPAPSS_INITIAL;
00148   u->us_id           = 0;
00149   u->us_timeouttime  = UPAP_DEFTIMEOUT;
00150   u->us_maxtransmits = 10;
00151   u->us_reqtimeout   = UPAP_DEFREQTIME;
00152 }
00153 
00154 /*
00155  * upap_authwithpeer - Authenticate us with our peer (start client).
00156  *
00157  * Set new state and send authenticate's.
00158  */
00159 void
00160 upap_authwithpeer(int unit, char *user, char *password)
00161 {
00162   upap_state *u = &upap[unit];
00163 
00164   UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
00165              unit, user, password, u->us_clientstate));
00166 
00167   /* Save the username and password we're given */
00168   u->us_user = user;
00169   u->us_userlen = (int)strlen(user);
00170   u->us_passwd = password;
00171   u->us_passwdlen = (int)strlen(password);
00172 
00173   u->us_transmits = 0;
00174 
00175   /* Lower layer up yet? */
00176   if (u->us_clientstate == UPAPCS_INITIAL ||
00177       u->us_clientstate == UPAPCS_PENDING) {
00178     u->us_clientstate = UPAPCS_PENDING;
00179     return;
00180   }
00181 
00182   upap_sauthreq(u);      /* Start protocol */
00183 }
00184 
00185 
00186 /*
00187  * upap_authpeer - Authenticate our peer (start server).
00188  *
00189  * Set new state.
00190  */
00191 void
00192 upap_authpeer(int unit)
00193 {
00194   upap_state *u = &upap[unit];
00195 
00196   /* Lower layer up yet? */
00197   if (u->us_serverstate == UPAPSS_INITIAL ||
00198       u->us_serverstate == UPAPSS_PENDING) {
00199     u->us_serverstate = UPAPSS_PENDING;
00200     return;
00201   }
00202 
00203   u->us_serverstate = UPAPSS_LISTEN;
00204   if (u->us_reqtimeout > 0) {
00205     TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
00206   }
00207 }
00208 
00209 /*
00210  * upap_timeout - Retransmission timer for sending auth-reqs expired.
00211  */
00212 static void
00213 upap_timeout(void *arg)
00214 {
00215   upap_state *u = (upap_state *) arg;
00216 
00217   UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n", 
00218         u->us_unit, u->us_timeouttime, u->us_clientstate));
00219 
00220   if (u->us_clientstate != UPAPCS_AUTHREQ) {
00221     UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
00222     return;
00223   }
00224 
00225   if (u->us_transmits >= u->us_maxtransmits) {
00226     /* give up in disgust */
00227     UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
00228     u->us_clientstate = UPAPCS_BADAUTH;
00229     auth_withpeer_fail(u->us_unit, PPP_PAP);
00230     return;
00231   }
00232 
00233   upap_sauthreq(u);    /* Send Authenticate-Request and set upap timeout*/
00234 }
00235 
00236 
00237 /*
00238  * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
00239  */
00240 static void
00241 upap_reqtimeout(void *arg)
00242 {
00243   upap_state *u = (upap_state *) arg;
00244 
00245   if (u->us_serverstate != UPAPSS_LISTEN) {
00246     return; /* huh?? */
00247   }
00248 
00249   auth_peer_fail(u->us_unit, PPP_PAP);
00250   u->us_serverstate = UPAPSS_BADAUTH;
00251 }
00252 
00253 
00254 /*
00255  * upap_lowerup - The lower layer is up.
00256  *
00257  * Start authenticating if pending.
00258  */
00259 static void
00260 upap_lowerup(int unit)
00261 {
00262   upap_state *u = &upap[unit];
00263 
00264   UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
00265 
00266   if (u->us_clientstate == UPAPCS_INITIAL) {
00267     u->us_clientstate = UPAPCS_CLOSED;
00268   } else if (u->us_clientstate == UPAPCS_PENDING) {
00269     upap_sauthreq(u);  /* send an auth-request */
00270     /* now client state is UPAPCS__AUTHREQ */
00271   }
00272 
00273   if (u->us_serverstate == UPAPSS_INITIAL) {
00274     u->us_serverstate = UPAPSS_CLOSED;
00275   } else if (u->us_serverstate == UPAPSS_PENDING) {
00276     u->us_serverstate = UPAPSS_LISTEN;
00277     if (u->us_reqtimeout > 0) {
00278       TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
00279     }
00280   }
00281 }
00282 
00283 
00284 /*
00285  * upap_lowerdown - The lower layer is down.
00286  *
00287  * Cancel all timeouts.
00288  */
00289 static void
00290 upap_lowerdown(int unit)
00291 {
00292   upap_state *u = &upap[unit];
00293 
00294   UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
00295 
00296   if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
00297     UNTIMEOUT(upap_timeout, u);    /* Cancel timeout */
00298   }
00299   if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
00300     UNTIMEOUT(upap_reqtimeout, u);
00301   }
00302 
00303   u->us_clientstate = UPAPCS_INITIAL;
00304   u->us_serverstate = UPAPSS_INITIAL;
00305 }
00306 
00307 
00308 /*
00309  * upap_protrej - Peer doesn't speak this protocol.
00310  *
00311  * This shouldn't happen.  In any case, pretend lower layer went down.
00312  */
00313 static void
00314 upap_protrej(int unit)
00315 {
00316   upap_state *u = &upap[unit];
00317 
00318   if (u->us_clientstate == UPAPCS_AUTHREQ) {
00319     UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
00320     auth_withpeer_fail(unit, PPP_PAP);
00321   }
00322   if (u->us_serverstate == UPAPSS_LISTEN) {
00323     UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
00324     auth_peer_fail(unit, PPP_PAP);
00325   }
00326   upap_lowerdown(unit);
00327 }
00328 
00329 
00330 /*
00331  * upap_input - Input UPAP packet.
00332  */
00333 static void
00334 upap_input(int unit, u_char *inpacket, int l)
00335 {
00336   upap_state *u = &upap[unit];
00337   u_char *inp;
00338   u_char code, id;
00339   int len;
00340 
00341   /*
00342    * Parse header (code, id and length).
00343    * If packet too short, drop it.
00344    */
00345   inp = inpacket;
00346   if (l < (int)UPAP_HEADERLEN) {
00347     UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
00348     return;
00349   }
00350   GETCHAR(code, inp);
00351   GETCHAR(id, inp);
00352   GETSHORT(len, inp);
00353   if (len < (int)UPAP_HEADERLEN) {
00354     UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
00355     return;
00356   }
00357   if (len > l) {
00358     UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
00359     return;
00360   }
00361   len -= UPAP_HEADERLEN;
00362 
00363   /*
00364    * Action depends on code.
00365    */
00366   switch (code) {
00367     case UPAP_AUTHREQ:
00368       upap_rauthreq(u, inp, id, len);
00369       break;
00370 
00371     case UPAP_AUTHACK:
00372       upap_rauthack(u, inp, id, len);
00373       break;
00374 
00375     case UPAP_AUTHNAK:
00376       upap_rauthnak(u, inp, id, len);
00377       break;
00378 
00379     default:        /* XXX Need code reject */
00380       UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
00381       break;
00382   }
00383 }
00384 
00385 
00386 /*
00387  * upap_rauth - Receive Authenticate.
00388  */
00389 static void
00390 upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
00391 {
00392   u_char ruserlen, rpasswdlen;
00393   char *ruser, *rpasswd;
00394   u_char retcode;
00395   char *msg;
00396   int msglen;
00397 
00398   UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
00399 
00400   if (u->us_serverstate < UPAPSS_LISTEN) {
00401     return;
00402   }
00403 
00404   /*
00405    * If we receive a duplicate authenticate-request, we are
00406    * supposed to return the same status as for the first request.
00407    */
00408   if (u->us_serverstate == UPAPSS_OPEN) {
00409     upap_sresp(u, UPAP_AUTHACK, id, "", 0);  /* return auth-ack */
00410     return;
00411   }
00412   if (u->us_serverstate == UPAPSS_BADAUTH) {
00413     upap_sresp(u, UPAP_AUTHNAK, id, "", 0);  /* return auth-nak */
00414     return;
00415   }
00416 
00417   /*
00418    * Parse user/passwd.
00419    */
00420   if (len < (int)sizeof (u_char)) {
00421     UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00422     return;
00423   }
00424   GETCHAR(ruserlen, inp);
00425   len -= sizeof (u_char) + ruserlen + sizeof (u_char);
00426   if (len < 0) {
00427     UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00428     return;
00429   }
00430   ruser = (char *) inp;
00431   INCPTR(ruserlen, inp);
00432   GETCHAR(rpasswdlen, inp);
00433   if (len < rpasswdlen) {
00434     UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
00435     return;
00436   }
00437   rpasswd = (char *) inp;
00438 
00439   /*
00440    * Check the username and password given.
00441    */
00442   retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
00443   /* lwip: currently retcode is always UPAP_AUTHACK */
00444   BZERO(rpasswd, rpasswdlen);
00445 
00446   upap_sresp(u, retcode, id, msg, msglen);
00447 
00448   if (retcode == UPAP_AUTHACK) {
00449     u->us_serverstate = UPAPSS_OPEN;
00450     auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
00451   } else {
00452     u->us_serverstate = UPAPSS_BADAUTH;
00453     auth_peer_fail(u->us_unit, PPP_PAP);
00454   }
00455 
00456   if (u->us_reqtimeout > 0) {
00457     UNTIMEOUT(upap_reqtimeout, u);
00458   }
00459 }
00460 
00461 
00462 /*
00463  * upap_rauthack - Receive Authenticate-Ack.
00464  */
00465 static void
00466 upap_rauthack(upap_state *u, u_char *inp, int id, int len)
00467 {
00468   u_char msglen;
00469   char *msg;
00470 
00471   LWIP_UNUSED_ARG(id);
00472 
00473   UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
00474 
00475   if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
00476     UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
00477     return;
00478   }
00479 
00480   /*
00481    * Parse message.
00482    */
00483   if (len < (int)sizeof (u_char)) {
00484     UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
00485   } else {
00486     GETCHAR(msglen, inp);
00487     if (msglen > 0) {
00488       len -= sizeof (u_char);
00489       if (len < msglen) {
00490         UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
00491         return;
00492       }
00493       msg = (char *) inp;
00494       PRINTMSG(msg, msglen);
00495     }
00496   }
00497   UNTIMEOUT(upap_timeout, u);    /* Cancel timeout */
00498   u->us_clientstate = UPAPCS_OPEN;
00499 
00500   auth_withpeer_success(u->us_unit, PPP_PAP);
00501 }
00502 
00503 
00504 /*
00505  * upap_rauthnak - Receive Authenticate-Nak.
00506  */
00507 static void
00508 upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
00509 {
00510   u_char msglen;
00511   char *msg;
00512 
00513   LWIP_UNUSED_ARG(id);
00514 
00515   UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
00516 
00517   if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
00518     return;
00519   }
00520 
00521   /*
00522    * Parse message.
00523    */
00524   if (len < sizeof (u_char)) {
00525     UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
00526   } else {
00527     GETCHAR(msglen, inp);
00528     if(msglen > 0) {
00529       len -= sizeof (u_char);
00530       if (len < msglen) {
00531         UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
00532         return;
00533       }
00534       msg = (char *) inp;
00535       PRINTMSG(msg, msglen);
00536     }
00537   }
00538 
00539   u->us_clientstate = UPAPCS_BADAUTH;
00540 
00541   UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
00542   auth_withpeer_fail(u->us_unit, PPP_PAP);
00543 }
00544 
00545 
00546 /*
00547  * upap_sauthreq - Send an Authenticate-Request.
00548  */
00549 static void
00550 upap_sauthreq(upap_state *u)
00551 {
00552   u_char *outp;
00553   int outlen;
00554 
00555   outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) 
00556          + u->us_userlen + u->us_passwdlen;
00557   outp = outpacket_buf[u->us_unit];
00558 
00559   MAKEHEADER(outp, PPP_PAP);
00560 
00561   PUTCHAR(UPAP_AUTHREQ, outp);
00562   PUTCHAR(++u->us_id, outp);
00563   PUTSHORT(outlen, outp);
00564   PUTCHAR(u->us_userlen, outp);
00565   BCOPY(u->us_user, outp, u->us_userlen);
00566   INCPTR(u->us_userlen, outp);
00567   PUTCHAR(u->us_passwdlen, outp);
00568   BCOPY(u->us_passwd, outp, u->us_passwdlen);
00569 
00570   pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
00571 
00572   UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
00573 
00574   TIMEOUT(upap_timeout, u, u->us_timeouttime);
00575   ++u->us_transmits;
00576   u->us_clientstate = UPAPCS_AUTHREQ;
00577 }
00578 
00579 
00580 /*
00581  * upap_sresp - Send a response (ack or nak).
00582  */
00583 static void
00584 upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
00585 {
00586   u_char *outp;
00587   int outlen;
00588 
00589   outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
00590   outp = outpacket_buf[u->us_unit];
00591   MAKEHEADER(outp, PPP_PAP);
00592 
00593   PUTCHAR(code, outp);
00594   PUTCHAR(id, outp);
00595   PUTSHORT(outlen, outp);
00596   PUTCHAR(msglen, outp);
00597   BCOPY(msg, outp, msglen);
00598   pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
00599 
00600   UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
00601 }
00602 
00603 #if PPP_ADDITIONAL_CALLBACKS
00604 static char *upap_codenames[] = {
00605     "AuthReq", "AuthAck", "AuthNak"
00606 };
00607 
00608 /*
00609  * upap_printpkt - print the contents of a PAP packet.
00610  */
00611 static int upap_printpkt(
00612   u_char *p,
00613   int plen,
00614   void (*printer) (void *, char *, ...),
00615   void *arg
00616 )
00617 {
00618   LWIP_UNUSED_ARG(p);
00619   LWIP_UNUSED_ARG(plen);
00620   LWIP_UNUSED_ARG(printer);
00621   LWIP_UNUSED_ARG(arg);
00622   return 0;
00623 }
00624 #endif /* PPP_ADDITIONAL_CALLBACKS */
00625 
00626 #endif /* PAP_SUPPORT */
00627 
00628 #endif /* PPP_SUPPORT */