pap.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /*****************************************************************************
  2. * pap.c - Network Password Authentication Protocol program file.
  3. *
  4. * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
  5. * portions Copyright (c) 1997 by Global Election Systems Inc.
  6. *
  7. * The authors hereby grant permission to use, copy, modify, distribute,
  8. * and license this software and its documentation for any purpose, provided
  9. * that existing copyright notices are retained in all copies and that this
  10. * notice and the following disclaimer are included verbatim in any
  11. * distributions. No written agreement, license, or royalty fee is required
  12. * for any of the authorized uses.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. *
  25. ******************************************************************************
  26. * REVISION HISTORY
  27. *
  28. * 03-01-01 Marc Boucher <marc@mbsi.ca>
  29. * Ported to lwIP.
  30. * 97-12-12 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
  31. * Original.
  32. *****************************************************************************/
  33. /*
  34. * upap.c - User/Password Authentication Protocol.
  35. *
  36. * Copyright (c) 1989 Carnegie Mellon University.
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms are permitted
  40. * provided that the above copyright notice and this paragraph are
  41. * duplicated in all such forms and that any documentation,
  42. * advertising materials, and other materials related to such
  43. * distribution and use acknowledge that the software was developed
  44. * by Carnegie Mellon University. The name of the
  45. * University may not be used to endorse or promote products derived
  46. * from this software without specific prior written permission.
  47. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  48. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  49. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  50. */
  51. #include "lwip/opt.h"
  52. #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
  53. #if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
  54. #include "ppp_impl.h"
  55. #include "pppdebug.h"
  56. #include "auth.h"
  57. #include "pap.h"
  58. #include <string.h>
  59. #if 0 /* UNUSED */
  60. static bool hide_password = 1;
  61. /*
  62. * Command-line options.
  63. */
  64. static option_t pap_option_list[] = {
  65. { "hide-password", o_bool, &hide_password,
  66. "Don't output passwords to log", 1 },
  67. { "show-password", o_bool, &hide_password,
  68. "Show password string in debug log messages", 0 },
  69. { "pap-restart", o_int, &upap[0].us_timeouttime,
  70. "Set retransmit timeout for PAP" },
  71. { "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
  72. "Set max number of transmissions for auth-reqs" },
  73. { "pap-timeout", o_int, &upap[0].us_reqtimeout,
  74. "Set time limit for peer PAP authentication" },
  75. { NULL }
  76. };
  77. #endif
  78. /*
  79. * Protocol entry points.
  80. */
  81. static void upap_init (int);
  82. static void upap_lowerup (int);
  83. static void upap_lowerdown (int);
  84. static void upap_input (int, u_char *, int);
  85. static void upap_protrej (int);
  86. #if PPP_ADDITIONAL_CALLBACKS
  87. static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
  88. #endif /* PPP_ADDITIONAL_CALLBACKS */
  89. struct protent pap_protent = {
  90. PPP_PAP,
  91. upap_init,
  92. upap_input,
  93. upap_protrej,
  94. upap_lowerup,
  95. upap_lowerdown,
  96. NULL,
  97. NULL,
  98. #if PPP_ADDITIONAL_CALLBACKS
  99. upap_printpkt,
  100. NULL,
  101. #endif /* PPP_ADDITIONAL_CALLBACKS */
  102. 1,
  103. "PAP",
  104. #if PPP_ADDITIONAL_CALLBACKS
  105. NULL,
  106. NULL,
  107. NULL
  108. #endif /* PPP_ADDITIONAL_CALLBACKS */
  109. };
  110. upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
  111. static void upap_timeout (void *);
  112. static void upap_reqtimeout(void *);
  113. static void upap_rauthreq (upap_state *, u_char *, u_char, int);
  114. static void upap_rauthack (upap_state *, u_char *, int, int);
  115. static void upap_rauthnak (upap_state *, u_char *, int, int);
  116. static void upap_sauthreq (upap_state *);
  117. static void upap_sresp (upap_state *, u_char, u_char, char *, int);
  118. /*
  119. * upap_init - Initialize a UPAP unit.
  120. */
  121. static void
  122. upap_init(int unit)
  123. {
  124. upap_state *u = &upap[unit];
  125. UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
  126. u->us_unit = unit;
  127. u->us_user = NULL;
  128. u->us_userlen = 0;
  129. u->us_passwd = NULL;
  130. u->us_passwdlen = 0;
  131. u->us_clientstate = UPAPCS_INITIAL;
  132. u->us_serverstate = UPAPSS_INITIAL;
  133. u->us_id = 0;
  134. u->us_timeouttime = UPAP_DEFTIMEOUT;
  135. u->us_maxtransmits = 10;
  136. u->us_reqtimeout = UPAP_DEFREQTIME;
  137. }
  138. /*
  139. * upap_authwithpeer - Authenticate us with our peer (start client).
  140. *
  141. * Set new state and send authenticate's.
  142. */
  143. void
  144. upap_authwithpeer(int unit, char *user, char *password)
  145. {
  146. upap_state *u = &upap[unit];
  147. UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
  148. unit, user, password, u->us_clientstate));
  149. /* Save the username and password we're given */
  150. u->us_user = user;
  151. u->us_userlen = (int)strlen(user);
  152. u->us_passwd = password;
  153. u->us_passwdlen = (int)strlen(password);
  154. u->us_transmits = 0;
  155. /* Lower layer up yet? */
  156. if (u->us_clientstate == UPAPCS_INITIAL ||
  157. u->us_clientstate == UPAPCS_PENDING) {
  158. u->us_clientstate = UPAPCS_PENDING;
  159. return;
  160. }
  161. upap_sauthreq(u); /* Start protocol */
  162. }
  163. /*
  164. * upap_authpeer - Authenticate our peer (start server).
  165. *
  166. * Set new state.
  167. */
  168. void
  169. upap_authpeer(int unit)
  170. {
  171. upap_state *u = &upap[unit];
  172. /* Lower layer up yet? */
  173. if (u->us_serverstate == UPAPSS_INITIAL ||
  174. u->us_serverstate == UPAPSS_PENDING) {
  175. u->us_serverstate = UPAPSS_PENDING;
  176. return;
  177. }
  178. u->us_serverstate = UPAPSS_LISTEN;
  179. if (u->us_reqtimeout > 0) {
  180. TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
  181. }
  182. }
  183. /*
  184. * upap_timeout - Retransmission timer for sending auth-reqs expired.
  185. */
  186. static void
  187. upap_timeout(void *arg)
  188. {
  189. upap_state *u = (upap_state *) arg;
  190. UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n",
  191. u->us_unit, u->us_timeouttime, u->us_clientstate));
  192. if (u->us_clientstate != UPAPCS_AUTHREQ) {
  193. UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
  194. return;
  195. }
  196. if (u->us_transmits >= u->us_maxtransmits) {
  197. /* give up in disgust */
  198. UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
  199. u->us_clientstate = UPAPCS_BADAUTH;
  200. auth_withpeer_fail(u->us_unit, PPP_PAP);
  201. return;
  202. }
  203. upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/
  204. }
  205. /*
  206. * upap_reqtimeout - Give up waiting for the peer to send an auth-req.
  207. */
  208. static void
  209. upap_reqtimeout(void *arg)
  210. {
  211. upap_state *u = (upap_state *) arg;
  212. if (u->us_serverstate != UPAPSS_LISTEN) {
  213. return; /* huh?? */
  214. }
  215. auth_peer_fail(u->us_unit, PPP_PAP);
  216. u->us_serverstate = UPAPSS_BADAUTH;
  217. }
  218. /*
  219. * upap_lowerup - The lower layer is up.
  220. *
  221. * Start authenticating if pending.
  222. */
  223. static void
  224. upap_lowerup(int unit)
  225. {
  226. upap_state *u = &upap[unit];
  227. UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
  228. if (u->us_clientstate == UPAPCS_INITIAL) {
  229. u->us_clientstate = UPAPCS_CLOSED;
  230. } else if (u->us_clientstate == UPAPCS_PENDING) {
  231. upap_sauthreq(u); /* send an auth-request */
  232. /* now client state is UPAPCS__AUTHREQ */
  233. }
  234. if (u->us_serverstate == UPAPSS_INITIAL) {
  235. u->us_serverstate = UPAPSS_CLOSED;
  236. } else if (u->us_serverstate == UPAPSS_PENDING) {
  237. u->us_serverstate = UPAPSS_LISTEN;
  238. if (u->us_reqtimeout > 0) {
  239. TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout);
  240. }
  241. }
  242. }
  243. /*
  244. * upap_lowerdown - The lower layer is down.
  245. *
  246. * Cancel all timeouts.
  247. */
  248. static void
  249. upap_lowerdown(int unit)
  250. {
  251. upap_state *u = &upap[unit];
  252. UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
  253. if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
  254. UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
  255. }
  256. if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) {
  257. UNTIMEOUT(upap_reqtimeout, u);
  258. }
  259. u->us_clientstate = UPAPCS_INITIAL;
  260. u->us_serverstate = UPAPSS_INITIAL;
  261. }
  262. /*
  263. * upap_protrej - Peer doesn't speak this protocol.
  264. *
  265. * This shouldn't happen. In any case, pretend lower layer went down.
  266. */
  267. static void
  268. upap_protrej(int unit)
  269. {
  270. upap_state *u = &upap[unit];
  271. if (u->us_clientstate == UPAPCS_AUTHREQ) {
  272. UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
  273. auth_withpeer_fail(unit, PPP_PAP);
  274. }
  275. if (u->us_serverstate == UPAPSS_LISTEN) {
  276. UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
  277. auth_peer_fail(unit, PPP_PAP);
  278. }
  279. upap_lowerdown(unit);
  280. }
  281. /*
  282. * upap_input - Input UPAP packet.
  283. */
  284. static void
  285. upap_input(int unit, u_char *inpacket, int l)
  286. {
  287. upap_state *u = &upap[unit];
  288. u_char *inp;
  289. u_char code, id;
  290. int len;
  291. /*
  292. * Parse header (code, id and length).
  293. * If packet too short, drop it.
  294. */
  295. inp = inpacket;
  296. if (l < (int)UPAP_HEADERLEN) {
  297. UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
  298. return;
  299. }
  300. GETCHAR(code, inp);
  301. GETCHAR(id, inp);
  302. GETSHORT(len, inp);
  303. if (len < (int)UPAP_HEADERLEN) {
  304. UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
  305. return;
  306. }
  307. if (len > l) {
  308. UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
  309. return;
  310. }
  311. len -= UPAP_HEADERLEN;
  312. /*
  313. * Action depends on code.
  314. */
  315. switch (code) {
  316. case UPAP_AUTHREQ:
  317. upap_rauthreq(u, inp, id, len);
  318. break;
  319. case UPAP_AUTHACK:
  320. upap_rauthack(u, inp, id, len);
  321. break;
  322. case UPAP_AUTHNAK:
  323. upap_rauthnak(u, inp, id, len);
  324. break;
  325. default: /* XXX Need code reject */
  326. UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
  327. break;
  328. }
  329. }
  330. /*
  331. * upap_rauth - Receive Authenticate.
  332. */
  333. static void
  334. upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
  335. {
  336. u_char ruserlen, rpasswdlen;
  337. char *ruser, *rpasswd;
  338. u_char retcode;
  339. char *msg;
  340. int msglen;
  341. UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
  342. if (u->us_serverstate < UPAPSS_LISTEN) {
  343. return;
  344. }
  345. /*
  346. * If we receive a duplicate authenticate-request, we are
  347. * supposed to return the same status as for the first request.
  348. */
  349. if (u->us_serverstate == UPAPSS_OPEN) {
  350. upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */
  351. return;
  352. }
  353. if (u->us_serverstate == UPAPSS_BADAUTH) {
  354. upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */
  355. return;
  356. }
  357. /*
  358. * Parse user/passwd.
  359. */
  360. if (len < (int)sizeof (u_char)) {
  361. UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
  362. return;
  363. }
  364. GETCHAR(ruserlen, inp);
  365. len -= sizeof (u_char) + ruserlen + sizeof (u_char);
  366. if (len < 0) {
  367. UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
  368. return;
  369. }
  370. ruser = (char *) inp;
  371. INCPTR(ruserlen, inp);
  372. GETCHAR(rpasswdlen, inp);
  373. if (len < rpasswdlen) {
  374. UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
  375. return;
  376. }
  377. rpasswd = (char *) inp;
  378. /*
  379. * Check the username and password given.
  380. */
  381. retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
  382. /* lwip: currently retcode is always UPAP_AUTHACK */
  383. BZERO(rpasswd, rpasswdlen);
  384. upap_sresp(u, retcode, id, msg, msglen);
  385. if (retcode == UPAP_AUTHACK) {
  386. u->us_serverstate = UPAPSS_OPEN;
  387. auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen);
  388. } else {
  389. u->us_serverstate = UPAPSS_BADAUTH;
  390. auth_peer_fail(u->us_unit, PPP_PAP);
  391. }
  392. if (u->us_reqtimeout > 0) {
  393. UNTIMEOUT(upap_reqtimeout, u);
  394. }
  395. }
  396. /*
  397. * upap_rauthack - Receive Authenticate-Ack.
  398. */
  399. static void
  400. upap_rauthack(upap_state *u, u_char *inp, int id, int len)
  401. {
  402. u_char msglen;
  403. char *msg;
  404. LWIP_UNUSED_ARG(id);
  405. UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
  406. if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
  407. UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
  408. return;
  409. }
  410. /*
  411. * Parse message.
  412. */
  413. if (len < (int)sizeof (u_char)) {
  414. UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
  415. } else {
  416. GETCHAR(msglen, inp);
  417. if (msglen > 0) {
  418. len -= sizeof (u_char);
  419. if (len < msglen) {
  420. UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
  421. return;
  422. }
  423. msg = (char *) inp;
  424. PRINTMSG(msg, msglen);
  425. }
  426. }
  427. UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
  428. u->us_clientstate = UPAPCS_OPEN;
  429. auth_withpeer_success(u->us_unit, PPP_PAP);
  430. }
  431. /*
  432. * upap_rauthnak - Receive Authenticate-Nak.
  433. */
  434. static void
  435. upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
  436. {
  437. u_char msglen;
  438. char *msg;
  439. LWIP_UNUSED_ARG(id);
  440. UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
  441. if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
  442. return;
  443. }
  444. /*
  445. * Parse message.
  446. */
  447. if (len < sizeof (u_char)) {
  448. UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
  449. } else {
  450. GETCHAR(msglen, inp);
  451. if(msglen > 0) {
  452. len -= sizeof (u_char);
  453. if (len < msglen) {
  454. UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
  455. return;
  456. }
  457. msg = (char *) inp;
  458. PRINTMSG(msg, msglen);
  459. }
  460. }
  461. u->us_clientstate = UPAPCS_BADAUTH;
  462. UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
  463. auth_withpeer_fail(u->us_unit, PPP_PAP);
  464. }
  465. /*
  466. * upap_sauthreq - Send an Authenticate-Request.
  467. */
  468. static void
  469. upap_sauthreq(upap_state *u)
  470. {
  471. u_char *outp;
  472. int outlen;
  473. outlen = UPAP_HEADERLEN + 2 * sizeof (u_char)
  474. + u->us_userlen + u->us_passwdlen;
  475. outp = outpacket_buf[u->us_unit];
  476. MAKEHEADER(outp, PPP_PAP);
  477. PUTCHAR(UPAP_AUTHREQ, outp);
  478. PUTCHAR(++u->us_id, outp);
  479. PUTSHORT(outlen, outp);
  480. PUTCHAR(u->us_userlen, outp);
  481. BCOPY(u->us_user, outp, u->us_userlen);
  482. INCPTR(u->us_userlen, outp);
  483. PUTCHAR(u->us_passwdlen, outp);
  484. BCOPY(u->us_passwd, outp, u->us_passwdlen);
  485. pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
  486. UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
  487. TIMEOUT(upap_timeout, u, u->us_timeouttime);
  488. ++u->us_transmits;
  489. u->us_clientstate = UPAPCS_AUTHREQ;
  490. }
  491. /*
  492. * upap_sresp - Send a response (ack or nak).
  493. */
  494. static void
  495. upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
  496. {
  497. u_char *outp;
  498. int outlen;
  499. outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen;
  500. outp = outpacket_buf[u->us_unit];
  501. MAKEHEADER(outp, PPP_PAP);
  502. PUTCHAR(code, outp);
  503. PUTCHAR(id, outp);
  504. PUTSHORT(outlen, outp);
  505. PUTCHAR(msglen, outp);
  506. BCOPY(msg, outp, msglen);
  507. pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
  508. UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
  509. }
  510. #if PPP_ADDITIONAL_CALLBACKS
  511. static char *upap_codenames[] = {
  512. "AuthReq", "AuthAck", "AuthNak"
  513. };
  514. /*
  515. * upap_printpkt - print the contents of a PAP packet.
  516. */
  517. static int upap_printpkt(
  518. u_char *p,
  519. int plen,
  520. void (*printer) (void *, char *, ...),
  521. void *arg
  522. )
  523. {
  524. LWIP_UNUSED_ARG(p);
  525. LWIP_UNUSED_ARG(plen);
  526. LWIP_UNUSED_ARG(printer);
  527. LWIP_UNUSED_ARG(arg);
  528. return 0;
  529. }
  530. #endif /* PPP_ADDITIONAL_CALLBACKS */
  531. #endif /* PAP_SUPPORT */
  532. #endif /* PPP_SUPPORT */