lcp.c 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
  1. /*
  2. * lcp.c - PPP Link Control Protocol.
  3. *
  4. * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. *
  18. * 3. The name "Carnegie Mellon University" must not be used to
  19. * endorse or promote products derived from this software without
  20. * prior written permission. For permission or any legal
  21. * details, please contact
  22. * Office of Technology Transfer
  23. * Carnegie Mellon University
  24. * 5000 Forbes Avenue
  25. * Pittsburgh, PA 15213-3890
  26. * (412) 268-4387, fax: (412) 268-7395
  27. * tech-transfer@andrew.cmu.edu
  28. *
  29. * 4. Redistributions of any form whatsoever must retain the following
  30. * acknowledgment:
  31. * "This product includes software developed by Computing Services
  32. * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
  33. *
  34. * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
  35. * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  36. * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
  37. * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  38. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  39. * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  40. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  41. */
  42. #define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $"
  43. /*
  44. * TODO:
  45. */
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <stdlib.h>
  49. #include "pppd.h"
  50. #include "fsm.h"
  51. #include "lcp.h"
  52. #include "chap-new.h"
  53. #include "magic.h"
  54. static const char rcsid[] = RCSID;
  55. /*
  56. * When the link comes up we want to be able to wait for a short while,
  57. * or until seeing some input from the peer, before starting to send
  58. * configure-requests. We do this by delaying the fsm_lowerup call.
  59. */
  60. /* steal a bit in fsm flags word */
  61. #define DELAYED_UP 0x100
  62. static void lcp_delayed_up __P((void *));
  63. /*
  64. * LCP-related command-line options.
  65. */
  66. int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
  67. int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
  68. bool lax_recv = 0; /* accept control chars in asyncmap */
  69. bool noendpoint = 0; /* don't send/accept endpoint discriminator */
  70. static int noopt __P((char **));
  71. #ifdef HAVE_MULTILINK
  72. static int setendpoint __P((char **));
  73. static void printendpoint __P((option_t *, void (*)(void *, char *, ...),
  74. void *));
  75. #endif /* HAVE_MULTILINK */
  76. static option_t lcp_option_list[] = {
  77. /* LCP options */
  78. { "-all", o_special_noarg, (void *)noopt,
  79. "Don't request/allow any LCP options" },
  80. { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
  81. "Disable address/control compression",
  82. OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
  83. { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
  84. "Disable address/control compression",
  85. OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
  86. { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
  87. "Set asyncmap (for received packets)",
  88. OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
  89. { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
  90. "Set asyncmap (for received packets)",
  91. OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
  92. { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
  93. "Disable asyncmap negotiation",
  94. OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
  95. &lcp_allowoptions[0].neg_asyncmap },
  96. { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
  97. "Disable asyncmap negotiation",
  98. OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
  99. &lcp_allowoptions[0].neg_asyncmap },
  100. { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
  101. "Disable magic number negotiation (looped-back line detection)",
  102. OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
  103. { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
  104. "Disable magic number negotiation (looped-back line detection)",
  105. OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
  106. { "mru", o_int, &lcp_wantoptions[0].mru,
  107. "Set MRU (maximum received packet size) for negotiation",
  108. OPT_PRIO, &lcp_wantoptions[0].neg_mru },
  109. { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
  110. "Disable MRU negotiation (use default 1500)",
  111. OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
  112. { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
  113. "Disable MRU negotiation (use default 1500)",
  114. OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
  115. { "mtu", o_int, &lcp_allowoptions[0].mru,
  116. "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
  117. { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
  118. "Disable protocol field compression",
  119. OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
  120. { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
  121. "Disable protocol field compression",
  122. OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
  123. { "passive", o_bool, &lcp_wantoptions[0].passive,
  124. "Set passive mode", 1 },
  125. { "-p", o_bool, &lcp_wantoptions[0].passive,
  126. "Set passive mode", OPT_ALIAS | 1 },
  127. { "silent", o_bool, &lcp_wantoptions[0].silent,
  128. "Set silent mode", 1 },
  129. { "lcp-echo-failure", o_int, &lcp_echo_fails,
  130. "Set number of consecutive echo failures to indicate link failure",
  131. OPT_PRIO },
  132. { "lcp-echo-interval", o_int, &lcp_echo_interval,
  133. "Set time in seconds between LCP echo requests", OPT_PRIO },
  134. { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
  135. "Set time in seconds between LCP retransmissions", OPT_PRIO },
  136. { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
  137. "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
  138. { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
  139. "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
  140. { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
  141. "Set limit on number of LCP configure-naks", OPT_PRIO },
  142. { "receive-all", o_bool, &lax_recv,
  143. "Accept all received control characters", 1 },
  144. #ifdef HAVE_MULTILINK
  145. { "mrru", o_int, &lcp_wantoptions[0].mrru,
  146. "Maximum received packet size for multilink bundle",
  147. OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
  148. { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
  149. "Use short sequence numbers in multilink headers",
  150. OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
  151. { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
  152. "Don't use short sequence numbers in multilink headers",
  153. OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
  154. { "endpoint", o_special, (void *) setendpoint,
  155. "Endpoint discriminator for multilink",
  156. OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
  157. #endif /* HAVE_MULTILINK */
  158. { "noendpoint", o_bool, &noendpoint,
  159. "Don't send or accept multilink endpoint discriminator", 1 },
  160. {NULL}
  161. };
  162. /* global vars */
  163. fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
  164. lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
  165. lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
  166. lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
  167. lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
  168. static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */
  169. static int lcp_echo_number = 0; /* ID number of next echo frame */
  170. static int lcp_echo_timer_running = 0; /* set if a timer is running */
  171. static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
  172. /*
  173. * Callbacks for fsm code. (CI = Configuration Information)
  174. */
  175. static void lcp_resetci __P((fsm *)); /* Reset our CI */
  176. static int lcp_cilen __P((fsm *)); /* Return length of our CI */
  177. static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
  178. static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
  179. static int lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */
  180. static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
  181. static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
  182. static void lcp_up __P((fsm *)); /* We're UP */
  183. static void lcp_down __P((fsm *)); /* We're DOWN */
  184. static void lcp_starting __P((fsm *)); /* We need lower layer up */
  185. static void lcp_finished __P((fsm *)); /* We need lower layer down */
  186. static int lcp_extcode __P((fsm *, int, int, u_char *, int));
  187. static void lcp_rprotrej __P((fsm *, u_char *, int));
  188. /*
  189. * routines to send LCP echos to peer
  190. */
  191. static void lcp_echo_lowerup __P((int));
  192. static void lcp_echo_lowerdown __P((int));
  193. static void LcpEchoTimeout __P((void *));
  194. static void lcp_received_echo_reply __P((fsm *, int, u_char *, int));
  195. static void LcpSendEchoRequest __P((fsm *));
  196. static void LcpLinkFailure __P((fsm *));
  197. static void LcpEchoCheck __P((fsm *));
  198. static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
  199. lcp_resetci, /* Reset our Configuration Information */
  200. lcp_cilen, /* Length of our Configuration Information */
  201. lcp_addci, /* Add our Configuration Information */
  202. lcp_ackci, /* ACK our Configuration Information */
  203. lcp_nakci, /* NAK our Configuration Information */
  204. lcp_rejci, /* Reject our Configuration Information */
  205. lcp_reqci, /* Request peer's Configuration Information */
  206. lcp_up, /* Called when fsm reaches OPENED state */
  207. lcp_down, /* Called when fsm leaves OPENED state */
  208. lcp_starting, /* Called when we want the lower layer up */
  209. lcp_finished, /* Called when we want the lower layer down */
  210. NULL, /* Called when Protocol-Reject received */
  211. NULL, /* Retransmission is necessary */
  212. lcp_extcode, /* Called to handle LCP-specific codes */
  213. "LCP" /* String name of protocol */
  214. };
  215. /*
  216. * Protocol entry points.
  217. * Some of these are called directly.
  218. */
  219. static void lcp_init __P((int));
  220. static void lcp_input __P((int, u_char *, int));
  221. static void lcp_protrej __P((int));
  222. static int lcp_printpkt __P((u_char *, int,
  223. void (*) __P((void *, char *, ...)), void *));
  224. struct protent lcp_protent = {
  225. PPP_LCP,
  226. lcp_init,
  227. lcp_input,
  228. lcp_protrej,
  229. lcp_lowerup,
  230. lcp_lowerdown,
  231. lcp_open,
  232. lcp_close,
  233. lcp_printpkt,
  234. NULL,
  235. 1,
  236. "LCP",
  237. NULL,
  238. lcp_option_list,
  239. NULL,
  240. NULL,
  241. NULL
  242. };
  243. int lcp_loopbackfail = DEFLOOPBACKFAIL;
  244. /*
  245. * Length of each type of configuration option (in octets)
  246. */
  247. #define CILEN_VOID 2
  248. #define CILEN_CHAR 3
  249. #define CILEN_SHORT 4 /* CILEN_VOID + 2 */
  250. #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */
  251. #define CILEN_LONG 6 /* CILEN_VOID + 4 */
  252. #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */
  253. #define CILEN_CBCP 3
  254. #define CODENAME(x) ((x) == CONFACK ? "ACK" : \
  255. (x) == CONFNAK ? "NAK" : "REJ")
  256. /*
  257. * noopt - Disable all options (why?).
  258. */
  259. static int
  260. noopt(argv)
  261. char **argv;
  262. {
  263. BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
  264. BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
  265. return (1);
  266. }
  267. #ifdef HAVE_MULTILINK
  268. static int
  269. setendpoint(argv)
  270. char **argv;
  271. {
  272. if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
  273. lcp_wantoptions[0].neg_endpoint = 1;
  274. return 1;
  275. }
  276. option_error("Can't parse '%s' as an endpoint discriminator", *argv);
  277. return 0;
  278. }
  279. static void
  280. printendpoint(opt, printer, arg)
  281. option_t *opt;
  282. void (*printer) __P((void *, char *, ...));
  283. void *arg;
  284. {
  285. printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
  286. }
  287. #endif /* HAVE_MULTILINK */
  288. /*
  289. * lcp_init - Initialize LCP.
  290. */
  291. static void
  292. lcp_init(unit)
  293. int unit;
  294. {
  295. fsm *f = &lcp_fsm[unit];
  296. lcp_options *wo = &lcp_wantoptions[unit];
  297. lcp_options *ao = &lcp_allowoptions[unit];
  298. f->unit = unit;
  299. f->protocol = PPP_LCP;
  300. f->callbacks = &lcp_callbacks;
  301. fsm_init(f);
  302. BZERO(wo, sizeof(*wo));
  303. wo->neg_mru = 1;
  304. wo->mru = DEFMRU;
  305. wo->neg_asyncmap = 1;
  306. wo->neg_magicnumber = 1;
  307. wo->neg_pcompression = 1;
  308. wo->neg_accompression = 1;
  309. BZERO(ao, sizeof(*ao));
  310. ao->neg_mru = 1;
  311. ao->mru = MAXMRU;
  312. ao->neg_asyncmap = 1;
  313. ao->neg_chap = 1;
  314. ao->chap_mdtype = chap_mdtype_all;
  315. ao->neg_upap = 1;
  316. ao->neg_eap = 1;
  317. ao->neg_magicnumber = 1;
  318. ao->neg_pcompression = 1;
  319. ao->neg_accompression = 1;
  320. ao->neg_endpoint = 1;
  321. }
  322. /*
  323. * lcp_open - LCP is allowed to come up.
  324. */
  325. void
  326. lcp_open(unit)
  327. int unit;
  328. {
  329. fsm *f = &lcp_fsm[unit];
  330. lcp_options *wo = &lcp_wantoptions[unit];
  331. f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
  332. if (wo->passive)
  333. f->flags |= OPT_PASSIVE;
  334. if (wo->silent)
  335. f->flags |= OPT_SILENT;
  336. fsm_open(f);
  337. }
  338. /*
  339. * lcp_close - Take LCP down.
  340. */
  341. void
  342. lcp_close(unit, reason)
  343. int unit;
  344. char *reason;
  345. {
  346. fsm *f = &lcp_fsm[unit];
  347. int oldstate;
  348. if (phase != PHASE_DEAD && phase != PHASE_MASTER)
  349. new_phase(PHASE_TERMINATE);
  350. if (f->flags & DELAYED_UP) {
  351. untimeout(lcp_delayed_up, f);
  352. f->state = STOPPED;
  353. }
  354. oldstate = f->state;
  355. fsm_close(f, reason);
  356. if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
  357. /*
  358. * This action is not strictly according to the FSM in RFC1548,
  359. * but it does mean that the program terminates if you do a
  360. * lcp_close() when a connection hasn't been established
  361. * because we are in passive/silent mode or because we have
  362. * delayed the fsm_lowerup() call and it hasn't happened yet.
  363. */
  364. f->flags &= ~DELAYED_UP;
  365. lcp_finished(f);
  366. }
  367. }
  368. /*
  369. * lcp_lowerup - The lower layer is up.
  370. */
  371. void
  372. lcp_lowerup(unit)
  373. int unit;
  374. {
  375. lcp_options *wo = &lcp_wantoptions[unit];
  376. fsm *f = &lcp_fsm[unit];
  377. /*
  378. * Don't use A/C or protocol compression on transmission,
  379. * but accept A/C and protocol compressed packets
  380. * if we are going to ask for A/C and protocol compression.
  381. */
  382. if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
  383. || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
  384. wo->neg_pcompression, wo->neg_accompression) < 0)
  385. return;
  386. peer_mru[unit] = PPP_MRU;
  387. if (listen_time != 0) {
  388. f->flags |= DELAYED_UP;
  389. timeout(lcp_delayed_up, f, 0, listen_time * 1000);
  390. } else
  391. fsm_lowerup(f);
  392. }
  393. /*
  394. * lcp_lowerdown - The lower layer is down.
  395. */
  396. void
  397. lcp_lowerdown(unit)
  398. int unit;
  399. {
  400. fsm *f = &lcp_fsm[unit];
  401. if (f->flags & DELAYED_UP) {
  402. f->flags &= ~DELAYED_UP;
  403. untimeout(lcp_delayed_up, f);
  404. } else
  405. fsm_lowerdown(&lcp_fsm[unit]);
  406. }
  407. /*
  408. * lcp_delayed_up - Bring the lower layer up now.
  409. */
  410. static void
  411. lcp_delayed_up(arg)
  412. void *arg;
  413. {
  414. fsm *f = arg;
  415. if (f->flags & DELAYED_UP) {
  416. f->flags &= ~DELAYED_UP;
  417. fsm_lowerup(f);
  418. }
  419. }
  420. /*
  421. * lcp_input - Input LCP packet.
  422. */
  423. static void
  424. lcp_input(unit, p, len)
  425. int unit;
  426. u_char *p;
  427. int len;
  428. {
  429. fsm *f = &lcp_fsm[unit];
  430. if (f->flags & DELAYED_UP) {
  431. f->flags &= ~DELAYED_UP;
  432. untimeout(lcp_delayed_up, f);
  433. fsm_lowerup(f);
  434. }
  435. fsm_input(f, p, len);
  436. }
  437. /*
  438. * lcp_extcode - Handle a LCP-specific code.
  439. */
  440. static int
  441. lcp_extcode(f, code, id, inp, len)
  442. fsm *f;
  443. int code, id;
  444. u_char *inp;
  445. int len;
  446. {
  447. u_char *magp;
  448. switch( code ){
  449. case PROTREJ:
  450. lcp_rprotrej(f, inp, len);
  451. break;
  452. case ECHOREQ:
  453. if (f->state != OPENED)
  454. break;
  455. magp = inp;
  456. PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
  457. fsm_sdata(f, ECHOREP, id, inp, len);
  458. break;
  459. case ECHOREP:
  460. lcp_received_echo_reply(f, id, inp, len);
  461. break;
  462. case DISCREQ:
  463. case IDENTIF:
  464. case TIMEREM:
  465. break;
  466. default:
  467. return 0;
  468. }
  469. return 1;
  470. }
  471. /*
  472. * lcp_rprotrej - Receive an Protocol-Reject.
  473. *
  474. * Figure out which protocol is rejected and inform it.
  475. */
  476. static void
  477. lcp_rprotrej(f, inp, len)
  478. fsm *f;
  479. u_char *inp;
  480. int len;
  481. {
  482. int i;
  483. struct protent *protp;
  484. u_short prot;
  485. const char *pname;
  486. if (len < 2) {
  487. LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
  488. return;
  489. }
  490. GETSHORT(prot, inp);
  491. /*
  492. * Protocol-Reject packets received in any state other than the LCP
  493. * OPENED state SHOULD be silently discarded.
  494. */
  495. if( f->state != OPENED ){
  496. LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
  497. return;
  498. }
  499. pname = protocol_name(prot);
  500. /*
  501. * Upcall the proper Protocol-Reject routine.
  502. */
  503. for (i = 0; (protp = protocols[i]) != NULL; ++i)
  504. if (protp->protocol == prot && protp->enabled_flag) {
  505. if (pname == NULL)
  506. dbglog("Protocol-Reject for 0x%x received", prot);
  507. else
  508. dbglog("Protocol-Reject for '%s' (0x%x) received", pname,
  509. prot);
  510. (*protp->protrej)(f->unit);
  511. return;
  512. }
  513. if (pname == NULL)
  514. warn("Protocol-Reject for unsupported protocol 0x%x", prot);
  515. else
  516. warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname,
  517. prot);
  518. }
  519. /*
  520. * lcp_protrej - A Protocol-Reject was received.
  521. */
  522. /*ARGSUSED*/
  523. static void
  524. lcp_protrej(unit)
  525. int unit;
  526. {
  527. /*
  528. * Can't reject LCP!
  529. */
  530. error("Received Protocol-Reject for LCP!");
  531. fsm_protreject(&lcp_fsm[unit]);
  532. }
  533. /*
  534. * lcp_sprotrej - Send a Protocol-Reject for some protocol.
  535. */
  536. void
  537. lcp_sprotrej(unit, p, len)
  538. int unit;
  539. u_char *p;
  540. int len;
  541. {
  542. /*
  543. * Send back the protocol and the information field of the
  544. * rejected packet. We only get here if LCP is in the OPENED state.
  545. */
  546. p += 2;
  547. len -= 2;
  548. fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
  549. p, len);
  550. }
  551. /*
  552. * lcp_resetci - Reset our CI.
  553. */
  554. static void
  555. lcp_resetci(f)
  556. fsm *f;
  557. {
  558. lcp_options *wo = &lcp_wantoptions[f->unit];
  559. lcp_options *go = &lcp_gotoptions[f->unit];
  560. lcp_options *ao = &lcp_allowoptions[f->unit];
  561. wo->magicnumber = magic();
  562. wo->numloops = 0;
  563. *go = *wo;
  564. if (!multilink) {
  565. go->neg_mrru = 0;
  566. go->neg_ssnhf = 0;
  567. go->neg_endpoint = 0;
  568. }
  569. if (noendpoint)
  570. ao->neg_endpoint = 0;
  571. peer_mru[f->unit] = PPP_MRU;
  572. auth_reset(f->unit);
  573. }
  574. /*
  575. * lcp_cilen - Return length of our CI.
  576. */
  577. static int
  578. lcp_cilen(f)
  579. fsm *f;
  580. {
  581. lcp_options *go = &lcp_gotoptions[f->unit];
  582. #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
  583. #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
  584. #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
  585. #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
  586. #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
  587. #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
  588. /*
  589. * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
  590. * accept more than one. We prefer EAP first, then CHAP, then
  591. * PAP.
  592. */
  593. return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
  594. LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
  595. LENCISHORT(go->neg_eap) +
  596. LENCICHAP(!go->neg_eap && go->neg_chap) +
  597. LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
  598. LENCILQR(go->neg_lqr) +
  599. LENCICBCP(go->neg_cbcp) +
  600. LENCILONG(go->neg_magicnumber) +
  601. LENCIVOID(go->neg_pcompression) +
  602. LENCIVOID(go->neg_accompression) +
  603. LENCISHORT(go->neg_mrru) +
  604. LENCIVOID(go->neg_ssnhf) +
  605. (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
  606. }
  607. /*
  608. * lcp_addci - Add our desired CIs to a packet.
  609. */
  610. static void
  611. lcp_addci(f, ucp, lenp)
  612. fsm *f;
  613. u_char *ucp;
  614. int *lenp;
  615. {
  616. lcp_options *go = &lcp_gotoptions[f->unit];
  617. u_char *start_ucp = ucp;
  618. #define ADDCIVOID(opt, neg) \
  619. if (neg) { \
  620. PUTCHAR(opt, ucp); \
  621. PUTCHAR(CILEN_VOID, ucp); \
  622. }
  623. #define ADDCISHORT(opt, neg, val) \
  624. if (neg) { \
  625. PUTCHAR(opt, ucp); \
  626. PUTCHAR(CILEN_SHORT, ucp); \
  627. PUTSHORT(val, ucp); \
  628. }
  629. #define ADDCICHAP(opt, neg, val) \
  630. if (neg) { \
  631. PUTCHAR((opt), ucp); \
  632. PUTCHAR(CILEN_CHAP, ucp); \
  633. PUTSHORT(PPP_CHAP, ucp); \
  634. PUTCHAR((CHAP_DIGEST(val)), ucp); \
  635. }
  636. #define ADDCILONG(opt, neg, val) \
  637. if (neg) { \
  638. PUTCHAR(opt, ucp); \
  639. PUTCHAR(CILEN_LONG, ucp); \
  640. PUTLONG(val, ucp); \
  641. }
  642. #define ADDCILQR(opt, neg, val) \
  643. if (neg) { \
  644. PUTCHAR(opt, ucp); \
  645. PUTCHAR(CILEN_LQR, ucp); \
  646. PUTSHORT(PPP_LQR, ucp); \
  647. PUTLONG(val, ucp); \
  648. }
  649. #define ADDCICHAR(opt, neg, val) \
  650. if (neg) { \
  651. PUTCHAR(opt, ucp); \
  652. PUTCHAR(CILEN_CHAR, ucp); \
  653. PUTCHAR(val, ucp); \
  654. }
  655. #define ADDCIENDP(opt, neg, class, val, len) \
  656. if (neg) { \
  657. int i; \
  658. PUTCHAR(opt, ucp); \
  659. PUTCHAR(CILEN_CHAR + len, ucp); \
  660. PUTCHAR(class, ucp); \
  661. for (i = 0; i < len; ++i) \
  662. PUTCHAR(val[i], ucp); \
  663. }
  664. ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
  665. ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
  666. go->asyncmap);
  667. ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
  668. ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
  669. ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
  670. PPP_PAP);
  671. ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
  672. ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
  673. ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
  674. ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
  675. ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
  676. ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
  677. ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
  678. ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
  679. go->endpoint.value, go->endpoint.length);
  680. if (ucp - start_ucp != *lenp) {
  681. /* this should never happen, because peer_mtu should be 1500 */
  682. error("Bug in lcp_addci: wrong length");
  683. }
  684. }
  685. /*
  686. * lcp_ackci - Ack our CIs.
  687. * This should not modify any state if the Ack is bad.
  688. *
  689. * Returns:
  690. * 0 - Ack was bad.
  691. * 1 - Ack was good.
  692. */
  693. static int
  694. lcp_ackci(f, p, len)
  695. fsm *f;
  696. u_char *p;
  697. int len;
  698. {
  699. lcp_options *go = &lcp_gotoptions[f->unit];
  700. u_char cilen, citype, cichar;
  701. u_short cishort;
  702. u_int32_t cilong;
  703. /*
  704. * CIs must be in exactly the same order that we sent.
  705. * Check packet length and CI length at each step.
  706. * If we find any deviations, then this packet is bad.
  707. */
  708. #define ACKCIVOID(opt, neg) \
  709. if (neg) { \
  710. if ((len -= CILEN_VOID) < 0) \
  711. goto bad; \
  712. GETCHAR(citype, p); \
  713. GETCHAR(cilen, p); \
  714. if (cilen != CILEN_VOID || \
  715. citype != opt) \
  716. goto bad; \
  717. }
  718. #define ACKCISHORT(opt, neg, val) \
  719. if (neg) { \
  720. if ((len -= CILEN_SHORT) < 0) \
  721. goto bad; \
  722. GETCHAR(citype, p); \
  723. GETCHAR(cilen, p); \
  724. if (cilen != CILEN_SHORT || \
  725. citype != opt) \
  726. goto bad; \
  727. GETSHORT(cishort, p); \
  728. if (cishort != val) \
  729. goto bad; \
  730. }
  731. #define ACKCICHAR(opt, neg, val) \
  732. if (neg) { \
  733. if ((len -= CILEN_CHAR) < 0) \
  734. goto bad; \
  735. GETCHAR(citype, p); \
  736. GETCHAR(cilen, p); \
  737. if (cilen != CILEN_CHAR || \
  738. citype != opt) \
  739. goto bad; \
  740. GETCHAR(cichar, p); \
  741. if (cichar != val) \
  742. goto bad; \
  743. }
  744. #define ACKCICHAP(opt, neg, val) \
  745. if (neg) { \
  746. if ((len -= CILEN_CHAP) < 0) \
  747. goto bad; \
  748. GETCHAR(citype, p); \
  749. GETCHAR(cilen, p); \
  750. if (cilen != CILEN_CHAP || \
  751. citype != (opt)) \
  752. goto bad; \
  753. GETSHORT(cishort, p); \
  754. if (cishort != PPP_CHAP) \
  755. goto bad; \
  756. GETCHAR(cichar, p); \
  757. if (cichar != (CHAP_DIGEST(val))) \
  758. goto bad; \
  759. }
  760. #define ACKCILONG(opt, neg, val) \
  761. if (neg) { \
  762. if ((len -= CILEN_LONG) < 0) \
  763. goto bad; \
  764. GETCHAR(citype, p); \
  765. GETCHAR(cilen, p); \
  766. if (cilen != CILEN_LONG || \
  767. citype != opt) \
  768. goto bad; \
  769. GETLONG(cilong, p); \
  770. if (cilong != val) \
  771. goto bad; \
  772. }
  773. #define ACKCILQR(opt, neg, val) \
  774. if (neg) { \
  775. if ((len -= CILEN_LQR) < 0) \
  776. goto bad; \
  777. GETCHAR(citype, p); \
  778. GETCHAR(cilen, p); \
  779. if (cilen != CILEN_LQR || \
  780. citype != opt) \
  781. goto bad; \
  782. GETSHORT(cishort, p); \
  783. if (cishort != PPP_LQR) \
  784. goto bad; \
  785. GETLONG(cilong, p); \
  786. if (cilong != val) \
  787. goto bad; \
  788. }
  789. #define ACKCIENDP(opt, neg, class, val, vlen) \
  790. if (neg) { \
  791. int i; \
  792. if ((len -= CILEN_CHAR + vlen) < 0) \
  793. goto bad; \
  794. GETCHAR(citype, p); \
  795. GETCHAR(cilen, p); \
  796. if (cilen != CILEN_CHAR + vlen || \
  797. citype != opt) \
  798. goto bad; \
  799. GETCHAR(cichar, p); \
  800. if (cichar != class) \
  801. goto bad; \
  802. for (i = 0; i < vlen; ++i) { \
  803. GETCHAR(cichar, p); \
  804. if (cichar != val[i]) \
  805. goto bad; \
  806. } \
  807. }
  808. ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
  809. ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
  810. go->asyncmap);
  811. ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
  812. ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
  813. ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
  814. PPP_PAP);
  815. ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
  816. ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
  817. ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
  818. ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
  819. ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
  820. ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
  821. ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
  822. ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
  823. go->endpoint.value, go->endpoint.length);
  824. /*
  825. * If there are any remaining CIs, then this packet is bad.
  826. */
  827. if (len != 0)
  828. goto bad;
  829. return (1);
  830. bad:
  831. LCPDEBUG(("lcp_acki: received bad Ack!"));
  832. return (0);
  833. }
  834. /*
  835. * lcp_nakci - Peer has sent a NAK for some of our CIs.
  836. * This should not modify any state if the Nak is bad
  837. * or if LCP is in the OPENED state.
  838. *
  839. * Returns:
  840. * 0 - Nak was bad.
  841. * 1 - Nak was good.
  842. */
  843. static int
  844. lcp_nakci(f, p, len, treat_as_reject)
  845. fsm *f;
  846. u_char *p;
  847. int len;
  848. int treat_as_reject;
  849. {
  850. lcp_options *go = &lcp_gotoptions[f->unit];
  851. lcp_options *wo = &lcp_wantoptions[f->unit];
  852. u_char citype, cichar, *next;
  853. u_short cishort;
  854. u_int32_t cilong;
  855. lcp_options no; /* options we've seen Naks for */
  856. lcp_options try; /* options to request next time */
  857. int looped_back = 0;
  858. int cilen;
  859. BZERO(&no, sizeof(no));
  860. try = *go;
  861. /*
  862. * Any Nak'd CIs must be in exactly the same order that we sent.
  863. * Check packet length and CI length at each step.
  864. * If we find any deviations, then this packet is bad.
  865. */
  866. #define NAKCIVOID(opt, neg) \
  867. if (go->neg && \
  868. len >= CILEN_VOID && \
  869. p[1] == CILEN_VOID && \
  870. p[0] == opt) { \
  871. len -= CILEN_VOID; \
  872. INCPTR(CILEN_VOID, p); \
  873. no.neg = 1; \
  874. try.neg = 0; \
  875. }
  876. #define NAKCICHAP(opt, neg, code) \
  877. if (go->neg && \
  878. len >= CILEN_CHAP && \
  879. p[1] == CILEN_CHAP && \
  880. p[0] == opt) { \
  881. len -= CILEN_CHAP; \
  882. INCPTR(2, p); \
  883. GETSHORT(cishort, p); \
  884. GETCHAR(cichar, p); \
  885. no.neg = 1; \
  886. code \
  887. }
  888. #define NAKCICHAR(opt, neg, code) \
  889. if (go->neg && \
  890. len >= CILEN_CHAR && \
  891. p[1] == CILEN_CHAR && \
  892. p[0] == opt) { \
  893. len -= CILEN_CHAR; \
  894. INCPTR(2, p); \
  895. GETCHAR(cichar, p); \
  896. no.neg = 1; \
  897. code \
  898. }
  899. #define NAKCISHORT(opt, neg, code) \
  900. if (go->neg && \
  901. len >= CILEN_SHORT && \
  902. p[1] == CILEN_SHORT && \
  903. p[0] == opt) { \
  904. len -= CILEN_SHORT; \
  905. INCPTR(2, p); \
  906. GETSHORT(cishort, p); \
  907. no.neg = 1; \
  908. code \
  909. }
  910. #define NAKCILONG(opt, neg, code) \
  911. if (go->neg && \
  912. len >= CILEN_LONG && \
  913. p[1] == CILEN_LONG && \
  914. p[0] == opt) { \
  915. len -= CILEN_LONG; \
  916. INCPTR(2, p); \
  917. GETLONG(cilong, p); \
  918. no.neg = 1; \
  919. code \
  920. }
  921. #define NAKCILQR(opt, neg, code) \
  922. if (go->neg && \
  923. len >= CILEN_LQR && \
  924. p[1] == CILEN_LQR && \
  925. p[0] == opt) { \
  926. len -= CILEN_LQR; \
  927. INCPTR(2, p); \
  928. GETSHORT(cishort, p); \
  929. GETLONG(cilong, p); \
  930. no.neg = 1; \
  931. code \
  932. }
  933. #define NAKCIENDP(opt, neg) \
  934. if (go->neg && \
  935. len >= CILEN_CHAR && \
  936. p[0] == opt && \
  937. p[1] >= CILEN_CHAR && \
  938. p[1] <= len) { \
  939. len -= p[1]; \
  940. INCPTR(p[1], p); \
  941. no.neg = 1; \
  942. try.neg = 0; \
  943. }
  944. /*
  945. * NOTE! There must be no assignments to individual fields of *go in
  946. * the code below. Any such assignment is a BUG!
  947. */
  948. /*
  949. * We don't care if they want to send us smaller packets than
  950. * we want. Therefore, accept any MRU less than what we asked for,
  951. * but then ignore the new value when setting the MRU in the kernel.
  952. * If they send us a bigger MRU than what we asked, accept it, up to
  953. * the limit of the default MRU we'd get if we didn't negotiate.
  954. */
  955. if (go->neg_mru && go->mru != DEFMRU) {
  956. NAKCISHORT(CI_MRU, neg_mru,
  957. if (cishort <= wo->mru || cishort <= DEFMRU)
  958. try.mru = cishort;
  959. );
  960. }
  961. /*
  962. * Add any characters they want to our (receive-side) asyncmap.
  963. */
  964. if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
  965. NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
  966. try.asyncmap = go->asyncmap | cilong;
  967. );
  968. }
  969. /*
  970. * If they've nak'd our authentication-protocol, check whether
  971. * they are proposing a different protocol, or a different
  972. * hash algorithm for CHAP.
  973. */
  974. if ((go->neg_chap || go->neg_upap || go->neg_eap)
  975. && len >= CILEN_SHORT
  976. && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
  977. cilen = p[1];
  978. len -= cilen;
  979. no.neg_chap = go->neg_chap;
  980. no.neg_upap = go->neg_upap;
  981. no.neg_eap = go->neg_eap;
  982. INCPTR(2, p);
  983. GETSHORT(cishort, p);
  984. if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
  985. /* If we were asking for EAP, then we need to stop that. */
  986. if (go->neg_eap)
  987. try.neg_eap = 0;
  988. /* If we were asking for CHAP, then we need to stop that. */
  989. else if (go->neg_chap)
  990. try.neg_chap = 0;
  991. /*
  992. * If we weren't asking for CHAP or EAP, then we were asking for
  993. * PAP, in which case this Nak is bad.
  994. */
  995. else
  996. goto bad;
  997. } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
  998. GETCHAR(cichar, p);
  999. /* Stop asking for EAP, if we were. */
  1000. if (go->neg_eap) {
  1001. try.neg_eap = 0;
  1002. /* Try to set up to use their suggestion, if possible */
  1003. if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
  1004. try.chap_mdtype = CHAP_MDTYPE_D(cichar);
  1005. } else if (go->neg_chap) {
  1006. /*
  1007. * We were asking for our preferred algorithm, they must
  1008. * want something different.
  1009. */
  1010. if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
  1011. if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
  1012. /* Use their suggestion if we support it ... */
  1013. try.chap_mdtype = CHAP_MDTYPE_D(cichar);
  1014. } else {
  1015. /* ... otherwise, try our next-preferred algorithm. */
  1016. try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype));
  1017. if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */
  1018. try.neg_chap = 0;
  1019. }
  1020. } else {
  1021. /*
  1022. * Whoops, they Nak'd our algorithm of choice
  1023. * but then suggested it back to us.
  1024. */
  1025. goto bad;
  1026. }
  1027. } else {
  1028. /*
  1029. * Stop asking for PAP if we were asking for it.
  1030. */
  1031. try.neg_upap = 0;
  1032. }
  1033. } else {
  1034. /*
  1035. * If we were asking for EAP, and they're Conf-Naking EAP,
  1036. * well, that's just strange. Nobody should do that.
  1037. */
  1038. if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
  1039. dbglog("Unexpected Conf-Nak for EAP");
  1040. /*
  1041. * We don't recognize what they're suggesting.
  1042. * Stop asking for what we were asking for.
  1043. */
  1044. if (go->neg_eap)
  1045. try.neg_eap = 0;
  1046. else if (go->neg_chap)
  1047. try.neg_chap = 0;
  1048. else
  1049. try.neg_upap = 0;
  1050. p += cilen - CILEN_SHORT;
  1051. }
  1052. }
  1053. /*
  1054. * If they can't cope with our link quality protocol, we'll have
  1055. * to stop asking for LQR. We haven't got any other protocol.
  1056. * If they Nak the reporting period, take their value XXX ?
  1057. */
  1058. NAKCILQR(CI_QUALITY, neg_lqr,
  1059. if (cishort != PPP_LQR)
  1060. try.neg_lqr = 0;
  1061. else
  1062. try.lqr_period = cilong;
  1063. );
  1064. /*
  1065. * Only implementing CBCP...not the rest of the callback options
  1066. */
  1067. NAKCICHAR(CI_CALLBACK, neg_cbcp,
  1068. try.neg_cbcp = 0;
  1069. );
  1070. /*
  1071. * Check for a looped-back line.
  1072. */
  1073. NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
  1074. try.magicnumber = magic();
  1075. looped_back = 1;
  1076. );
  1077. /*
  1078. * Peer shouldn't send Nak for protocol compression or
  1079. * address/control compression requests; they should send
  1080. * a Reject instead. If they send a Nak, treat it as a Reject.
  1081. */
  1082. NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
  1083. NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
  1084. /*
  1085. * Nak for MRRU option - accept their value if it is smaller
  1086. * than the one we want.
  1087. */
  1088. if (go->neg_mrru) {
  1089. NAKCISHORT(CI_MRRU, neg_mrru,
  1090. if (treat_as_reject)
  1091. try.neg_mrru = 0;
  1092. else if (cishort <= wo->mrru)
  1093. try.mrru = cishort;
  1094. );
  1095. }
  1096. /*
  1097. * Nak for short sequence numbers shouldn't be sent, treat it
  1098. * like a reject.
  1099. */
  1100. NAKCIVOID(CI_SSNHF, neg_ssnhf);
  1101. /*
  1102. * Nak of the endpoint discriminator option is not permitted,
  1103. * treat it like a reject.
  1104. */
  1105. NAKCIENDP(CI_EPDISC, neg_endpoint);
  1106. /*
  1107. * There may be remaining CIs, if the peer is requesting negotiation
  1108. * on an option that we didn't include in our request packet.
  1109. * If we see an option that we requested, or one we've already seen
  1110. * in this packet, then this packet is bad.
  1111. * If we wanted to respond by starting to negotiate on the requested
  1112. * option(s), we could, but we don't, because except for the
  1113. * authentication type and quality protocol, if we are not negotiating
  1114. * an option, it is because we were told not to.
  1115. * For the authentication type, the Nak from the peer means
  1116. * `let me authenticate myself with you' which is a bit pointless.
  1117. * For the quality protocol, the Nak means `ask me to send you quality
  1118. * reports', but if we didn't ask for them, we don't want them.
  1119. * An option we don't recognize represents the peer asking to
  1120. * negotiate some option we don't support, so ignore it.
  1121. */
  1122. while (len >= CILEN_VOID) {
  1123. GETCHAR(citype, p);
  1124. GETCHAR(cilen, p);
  1125. if (cilen < CILEN_VOID || (len -= cilen) < 0)
  1126. goto bad;
  1127. next = p + cilen - 2;
  1128. switch (citype) {
  1129. case CI_MRU:
  1130. if ((go->neg_mru && go->mru != DEFMRU)
  1131. || no.neg_mru || cilen != CILEN_SHORT)
  1132. goto bad;
  1133. GETSHORT(cishort, p);
  1134. if (cishort < DEFMRU) {
  1135. try.neg_mru = 1;
  1136. try.mru = cishort;
  1137. }
  1138. break;
  1139. case CI_ASYNCMAP:
  1140. if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
  1141. || no.neg_asyncmap || cilen != CILEN_LONG)
  1142. goto bad;
  1143. break;
  1144. case CI_AUTHTYPE:
  1145. if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
  1146. go->neg_eap || no.neg_eap)
  1147. goto bad;
  1148. break;
  1149. case CI_MAGICNUMBER:
  1150. if (go->neg_magicnumber || no.neg_magicnumber ||
  1151. cilen != CILEN_LONG)
  1152. goto bad;
  1153. break;
  1154. case CI_PCOMPRESSION:
  1155. if (go->neg_pcompression || no.neg_pcompression
  1156. || cilen != CILEN_VOID)
  1157. goto bad;
  1158. break;
  1159. case CI_ACCOMPRESSION:
  1160. if (go->neg_accompression || no.neg_accompression
  1161. || cilen != CILEN_VOID)
  1162. goto bad;
  1163. break;
  1164. case CI_QUALITY:
  1165. if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
  1166. goto bad;
  1167. break;
  1168. case CI_MRRU:
  1169. if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
  1170. goto bad;
  1171. break;
  1172. case CI_SSNHF:
  1173. if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
  1174. goto bad;
  1175. try.neg_ssnhf = 1;
  1176. break;
  1177. case CI_EPDISC:
  1178. if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
  1179. goto bad;
  1180. break;
  1181. }
  1182. p = next;
  1183. }
  1184. /*
  1185. * OK, the Nak is good. Now we can update state.
  1186. * If there are any options left we ignore them.
  1187. */
  1188. if (f->state != OPENED) {
  1189. if (looped_back) {
  1190. if (++try.numloops >= lcp_loopbackfail) {
  1191. notice("Serial line is looped back.");
  1192. status = EXIT_LOOPBACK;
  1193. lcp_close(f->unit, "Loopback detected");
  1194. }
  1195. } else
  1196. try.numloops = 0;
  1197. *go = try;
  1198. }
  1199. return 1;
  1200. bad:
  1201. LCPDEBUG(("lcp_nakci: received bad Nak!"));
  1202. return 0;
  1203. }
  1204. /*
  1205. * lcp_rejci - Peer has Rejected some of our CIs.
  1206. * This should not modify any state if the Reject is bad
  1207. * or if LCP is in the OPENED state.
  1208. *
  1209. * Returns:
  1210. * 0 - Reject was bad.
  1211. * 1 - Reject was good.
  1212. */
  1213. static int
  1214. lcp_rejci(f, p, len)
  1215. fsm *f;
  1216. u_char *p;
  1217. int len;
  1218. {
  1219. lcp_options *go = &lcp_gotoptions[f->unit];
  1220. u_char cichar;
  1221. u_short cishort;
  1222. u_int32_t cilong;
  1223. lcp_options try; /* options to request next time */
  1224. try = *go;
  1225. /*
  1226. * Any Rejected CIs must be in exactly the same order that we sent.
  1227. * Check packet length and CI length at each step.
  1228. * If we find any deviations, then this packet is bad.
  1229. */
  1230. #define REJCIVOID(opt, neg) \
  1231. if (go->neg && \
  1232. len >= CILEN_VOID && \
  1233. p[1] == CILEN_VOID && \
  1234. p[0] == opt) { \
  1235. len -= CILEN_VOID; \
  1236. INCPTR(CILEN_VOID, p); \
  1237. try.neg = 0; \
  1238. }
  1239. #define REJCISHORT(opt, neg, val) \
  1240. if (go->neg && \
  1241. len >= CILEN_SHORT && \
  1242. p[1] == CILEN_SHORT && \
  1243. p[0] == opt) { \
  1244. len -= CILEN_SHORT; \
  1245. INCPTR(2, p); \
  1246. GETSHORT(cishort, p); \
  1247. /* Check rejected value. */ \
  1248. if (cishort != val) \
  1249. goto bad; \
  1250. try.neg = 0; \
  1251. }
  1252. #define REJCICHAP(opt, neg, val) \
  1253. if (go->neg && \
  1254. len >= CILEN_CHAP && \
  1255. p[1] == CILEN_CHAP && \
  1256. p[0] == opt) { \
  1257. len -= CILEN_CHAP; \
  1258. INCPTR(2, p); \
  1259. GETSHORT(cishort, p); \
  1260. GETCHAR(cichar, p); \
  1261. /* Check rejected value. */ \
  1262. if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
  1263. goto bad; \
  1264. try.neg = 0; \
  1265. try.neg_eap = try.neg_upap = 0; \
  1266. }
  1267. #define REJCILONG(opt, neg, val) \
  1268. if (go->neg && \
  1269. len >= CILEN_LONG && \
  1270. p[1] == CILEN_LONG && \
  1271. p[0] == opt) { \
  1272. len -= CILEN_LONG; \
  1273. INCPTR(2, p); \
  1274. GETLONG(cilong, p); \
  1275. /* Check rejected value. */ \
  1276. if (cilong != val) \
  1277. goto bad; \
  1278. try.neg = 0; \
  1279. }
  1280. #define REJCILQR(opt, neg, val) \
  1281. if (go->neg && \
  1282. len >= CILEN_LQR && \
  1283. p[1] == CILEN_LQR && \
  1284. p[0] == opt) { \
  1285. len -= CILEN_LQR; \
  1286. INCPTR(2, p); \
  1287. GETSHORT(cishort, p); \
  1288. GETLONG(cilong, p); \
  1289. /* Check rejected value. */ \
  1290. if (cishort != PPP_LQR || cilong != val) \
  1291. goto bad; \
  1292. try.neg = 0; \
  1293. }
  1294. #define REJCICBCP(opt, neg, val) \
  1295. if (go->neg && \
  1296. len >= CILEN_CBCP && \
  1297. p[1] == CILEN_CBCP && \
  1298. p[0] == opt) { \
  1299. len -= CILEN_CBCP; \
  1300. INCPTR(2, p); \
  1301. GETCHAR(cichar, p); \
  1302. /* Check rejected value. */ \
  1303. if (cichar != val) \
  1304. goto bad; \
  1305. try.neg = 0; \
  1306. }
  1307. #define REJCIENDP(opt, neg, class, val, vlen) \
  1308. if (go->neg && \
  1309. len >= CILEN_CHAR + vlen && \
  1310. p[0] == opt && \
  1311. p[1] == CILEN_CHAR + vlen) { \
  1312. int i; \
  1313. len -= CILEN_CHAR + vlen; \
  1314. INCPTR(2, p); \
  1315. GETCHAR(cichar, p); \
  1316. if (cichar != class) \
  1317. goto bad; \
  1318. for (i = 0; i < vlen; ++i) { \
  1319. GETCHAR(cichar, p); \
  1320. if (cichar != val[i]) \
  1321. goto bad; \
  1322. } \
  1323. try.neg = 0; \
  1324. }
  1325. REJCISHORT(CI_MRU, neg_mru, go->mru);
  1326. REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
  1327. REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
  1328. if (!go->neg_eap) {
  1329. REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
  1330. if (!go->neg_chap) {
  1331. REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
  1332. }
  1333. }
  1334. REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
  1335. REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
  1336. REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
  1337. REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
  1338. REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
  1339. REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
  1340. REJCIVOID(CI_SSNHF, neg_ssnhf);
  1341. REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class,
  1342. go->endpoint.value, go->endpoint.length);
  1343. /*
  1344. * If there are any remaining CIs, then this packet is bad.
  1345. */
  1346. if (len != 0)
  1347. goto bad;
  1348. /*
  1349. * Now we can update state.
  1350. */
  1351. if (f->state != OPENED)
  1352. *go = try;
  1353. return 1;
  1354. bad:
  1355. LCPDEBUG(("lcp_rejci: received bad Reject!"));
  1356. return 0;
  1357. }
  1358. /*
  1359. * lcp_reqci - Check the peer's requested CIs and send appropriate response.
  1360. *
  1361. * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
  1362. * appropriately. If reject_if_disagree is non-zero, doesn't return
  1363. * CONFNAK; returns CONFREJ if it can't return CONFACK.
  1364. */
  1365. static int
  1366. lcp_reqci(f, inp, lenp, reject_if_disagree)
  1367. fsm *f;
  1368. u_char *inp; /* Requested CIs */
  1369. int *lenp; /* Length of requested CIs */
  1370. int reject_if_disagree;
  1371. {
  1372. lcp_options *go = &lcp_gotoptions[f->unit];
  1373. lcp_options *ho = &lcp_hisoptions[f->unit];
  1374. lcp_options *ao = &lcp_allowoptions[f->unit];
  1375. u_char *cip, *next; /* Pointer to current and next CIs */
  1376. int cilen, citype, cichar; /* Parsed len, type, char value */
  1377. u_short cishort; /* Parsed short value */
  1378. u_int32_t cilong; /* Parse long value */
  1379. int rc = CONFACK; /* Final packet return code */
  1380. int orc; /* Individual option return code */
  1381. u_char *p; /* Pointer to next char to parse */
  1382. u_char *rejp; /* Pointer to next char in reject frame */
  1383. u_char *nakp; /* Pointer to next char in Nak frame */
  1384. int l = *lenp; /* Length left */
  1385. /*
  1386. * Reset all his options.
  1387. */
  1388. BZERO(ho, sizeof(*ho));
  1389. /*
  1390. * Process all his options.
  1391. */
  1392. next = inp;
  1393. nakp = nak_buffer;
  1394. rejp = inp;
  1395. while (l) {
  1396. orc = CONFACK; /* Assume success */
  1397. cip = p = next; /* Remember begining of CI */
  1398. if (l < 2 || /* Not enough data for CI header or */
  1399. p[1] < 2 || /* CI length too small or */
  1400. p[1] > l) { /* CI length too big? */
  1401. LCPDEBUG(("lcp_reqci: bad CI length!"));
  1402. orc = CONFREJ; /* Reject bad CI */
  1403. cilen = l; /* Reject till end of packet */
  1404. l = 0; /* Don't loop again */
  1405. citype = 0;
  1406. goto endswitch;
  1407. }
  1408. GETCHAR(citype, p); /* Parse CI type */
  1409. GETCHAR(cilen, p); /* Parse CI length */
  1410. l -= cilen; /* Adjust remaining length */
  1411. next += cilen; /* Step to next CI */
  1412. switch (citype) { /* Check CI type */
  1413. case CI_MRU:
  1414. if (!ao->neg_mru || /* Allow option? */
  1415. cilen != CILEN_SHORT) { /* Check CI length */
  1416. orc = CONFREJ; /* Reject CI */
  1417. break;
  1418. }
  1419. GETSHORT(cishort, p); /* Parse MRU */
  1420. /*
  1421. * He must be able to receive at least our minimum.
  1422. * No need to check a maximum. If he sends a large number,
  1423. * we'll just ignore it.
  1424. */
  1425. if (cishort < MINMRU) {
  1426. orc = CONFNAK; /* Nak CI */
  1427. PUTCHAR(CI_MRU, nakp);
  1428. PUTCHAR(CILEN_SHORT, nakp);
  1429. PUTSHORT(MINMRU, nakp); /* Give him a hint */
  1430. break;
  1431. }
  1432. ho->neg_mru = 1; /* Remember he sent MRU */
  1433. ho->mru = cishort; /* And remember value */
  1434. break;
  1435. case CI_ASYNCMAP:
  1436. if (!ao->neg_asyncmap ||
  1437. cilen != CILEN_LONG) {
  1438. orc = CONFREJ;
  1439. break;
  1440. }
  1441. GETLONG(cilong, p);
  1442. /*
  1443. * Asyncmap must have set at least the bits
  1444. * which are set in lcp_allowoptions[unit].asyncmap.
  1445. */
  1446. if ((ao->asyncmap & ~cilong) != 0) {
  1447. orc = CONFNAK;
  1448. PUTCHAR(CI_ASYNCMAP, nakp);
  1449. PUTCHAR(CILEN_LONG, nakp);
  1450. PUTLONG(ao->asyncmap | cilong, nakp);
  1451. break;
  1452. }
  1453. ho->neg_asyncmap = 1;
  1454. ho->asyncmap = cilong;
  1455. break;
  1456. case CI_AUTHTYPE:
  1457. if (cilen < CILEN_SHORT ||
  1458. !(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
  1459. /*
  1460. * Reject the option if we're not willing to authenticate.
  1461. */
  1462. dbglog("No auth is possible");
  1463. orc = CONFREJ;
  1464. break;
  1465. }
  1466. GETSHORT(cishort, p);
  1467. /*
  1468. * Authtype must be PAP, CHAP, or EAP.
  1469. *
  1470. * Note: if more than one of ao->neg_upap, ao->neg_chap, and
  1471. * ao->neg_eap are set, and the peer sends a Configure-Request
  1472. * with two or more authenticate-protocol requests, then we will
  1473. * reject the second request.
  1474. * Whether we end up doing CHAP, UPAP, or EAP depends then on
  1475. * the ordering of the CIs in the peer's Configure-Request.
  1476. */
  1477. if (cishort == PPP_PAP) {
  1478. /* we've already accepted CHAP or EAP */
  1479. if (ho->neg_chap || ho->neg_eap ||
  1480. cilen != CILEN_SHORT) {
  1481. LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
  1482. orc = CONFREJ;
  1483. break;
  1484. }
  1485. if (!ao->neg_upap) { /* we don't want to do PAP */
  1486. orc = CONFNAK; /* NAK it and suggest CHAP or EAP */
  1487. PUTCHAR(CI_AUTHTYPE, nakp);
  1488. if (ao->neg_eap) {
  1489. PUTCHAR(CILEN_SHORT, nakp);
  1490. PUTSHORT(PPP_EAP, nakp);
  1491. } else {
  1492. PUTCHAR(CILEN_CHAP, nakp);
  1493. PUTSHORT(PPP_CHAP, nakp);
  1494. PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
  1495. }
  1496. break;
  1497. }
  1498. ho->neg_upap = 1;
  1499. break;
  1500. }
  1501. if (cishort == PPP_CHAP) {
  1502. /* we've already accepted PAP or EAP */
  1503. if (ho->neg_upap || ho->neg_eap ||
  1504. cilen != CILEN_CHAP) {
  1505. LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
  1506. orc = CONFREJ;
  1507. break;
  1508. }
  1509. if (!ao->neg_chap) { /* we don't want to do CHAP */
  1510. orc = CONFNAK; /* NAK it and suggest EAP or PAP */
  1511. PUTCHAR(CI_AUTHTYPE, nakp);
  1512. PUTCHAR(CILEN_SHORT, nakp);
  1513. if (ao->neg_eap) {
  1514. PUTSHORT(PPP_EAP, nakp);
  1515. } else {
  1516. PUTSHORT(PPP_PAP, nakp);
  1517. }
  1518. break;
  1519. }
  1520. GETCHAR(cichar, p); /* get digest type */
  1521. if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
  1522. /*
  1523. * We can't/won't do the requested type,
  1524. * suggest something else.
  1525. */
  1526. orc = CONFNAK;
  1527. PUTCHAR(CI_AUTHTYPE, nakp);
  1528. PUTCHAR(CILEN_CHAP, nakp);
  1529. PUTSHORT(PPP_CHAP, nakp);
  1530. PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
  1531. break;
  1532. }
  1533. ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
  1534. ho->neg_chap = 1;
  1535. break;
  1536. }
  1537. if (cishort == PPP_EAP) {
  1538. /* we've already accepted CHAP or PAP */
  1539. if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
  1540. LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
  1541. orc = CONFREJ;
  1542. break;
  1543. }
  1544. if (!ao->neg_eap) { /* we don't want to do EAP */
  1545. orc = CONFNAK; /* NAK it and suggest CHAP or PAP */
  1546. PUTCHAR(CI_AUTHTYPE, nakp);
  1547. if (ao->neg_chap) {
  1548. PUTCHAR(CILEN_CHAP, nakp);
  1549. PUTSHORT(PPP_CHAP, nakp);
  1550. PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
  1551. } else {
  1552. PUTCHAR(CILEN_SHORT, nakp);
  1553. PUTSHORT(PPP_PAP, nakp);
  1554. }
  1555. break;
  1556. }
  1557. ho->neg_eap = 1;
  1558. break;
  1559. }
  1560. /*
  1561. * We don't recognize the protocol they're asking for.
  1562. * Nak it with something we're willing to do.
  1563. * (At this point we know ao->neg_upap || ao->neg_chap ||
  1564. * ao->neg_eap.)
  1565. */
  1566. orc = CONFNAK;
  1567. PUTCHAR(CI_AUTHTYPE, nakp);
  1568. if (ao->neg_eap) {
  1569. PUTCHAR(CILEN_SHORT, nakp);
  1570. PUTSHORT(PPP_EAP, nakp);
  1571. } else if (ao->neg_chap) {
  1572. PUTCHAR(CILEN_CHAP, nakp);
  1573. PUTSHORT(PPP_CHAP, nakp);
  1574. PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
  1575. } else {
  1576. PUTCHAR(CILEN_SHORT, nakp);
  1577. PUTSHORT(PPP_PAP, nakp);
  1578. }
  1579. break;
  1580. case CI_QUALITY:
  1581. if (!ao->neg_lqr ||
  1582. cilen != CILEN_LQR) {
  1583. orc = CONFREJ;
  1584. break;
  1585. }
  1586. GETSHORT(cishort, p);
  1587. GETLONG(cilong, p);
  1588. /*
  1589. * Check the protocol and the reporting period.
  1590. * XXX When should we Nak this, and what with?
  1591. */
  1592. if (cishort != PPP_LQR) {
  1593. orc = CONFNAK;
  1594. PUTCHAR(CI_QUALITY, nakp);
  1595. PUTCHAR(CILEN_LQR, nakp);
  1596. PUTSHORT(PPP_LQR, nakp);
  1597. PUTLONG(ao->lqr_period, nakp);
  1598. break;
  1599. }
  1600. break;
  1601. case CI_MAGICNUMBER:
  1602. if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
  1603. cilen != CILEN_LONG) {
  1604. orc = CONFREJ;
  1605. break;
  1606. }
  1607. GETLONG(cilong, p);
  1608. /*
  1609. * He must have a different magic number.
  1610. */
  1611. if (go->neg_magicnumber &&
  1612. cilong == go->magicnumber) {
  1613. cilong = magic(); /* Don't put magic() inside macro! */
  1614. orc = CONFNAK;
  1615. PUTCHAR(CI_MAGICNUMBER, nakp);
  1616. PUTCHAR(CILEN_LONG, nakp);
  1617. PUTLONG(cilong, nakp);
  1618. break;
  1619. }
  1620. ho->neg_magicnumber = 1;
  1621. ho->magicnumber = cilong;
  1622. break;
  1623. case CI_PCOMPRESSION:
  1624. if (!ao->neg_pcompression ||
  1625. cilen != CILEN_VOID) {
  1626. orc = CONFREJ;
  1627. break;
  1628. }
  1629. ho->neg_pcompression = 1;
  1630. break;
  1631. case CI_ACCOMPRESSION:
  1632. if (!ao->neg_accompression ||
  1633. cilen != CILEN_VOID) {
  1634. orc = CONFREJ;
  1635. break;
  1636. }
  1637. ho->neg_accompression = 1;
  1638. break;
  1639. case CI_MRRU:
  1640. if (!ao->neg_mrru || !multilink ||
  1641. cilen != CILEN_SHORT) {
  1642. orc = CONFREJ;
  1643. break;
  1644. }
  1645. GETSHORT(cishort, p);
  1646. /* possibly should insist on a minimum/maximum MRRU here */
  1647. ho->neg_mrru = 1;
  1648. ho->mrru = cishort;
  1649. break;
  1650. case CI_SSNHF:
  1651. if (!ao->neg_ssnhf || !multilink ||
  1652. cilen != CILEN_VOID) {
  1653. orc = CONFREJ;
  1654. break;
  1655. }
  1656. ho->neg_ssnhf = 1;
  1657. break;
  1658. case CI_EPDISC:
  1659. if (!ao->neg_endpoint ||
  1660. cilen < CILEN_CHAR ||
  1661. cilen > CILEN_CHAR + MAX_ENDP_LEN) {
  1662. orc = CONFREJ;
  1663. break;
  1664. }
  1665. GETCHAR(cichar, p);
  1666. cilen -= CILEN_CHAR;
  1667. ho->neg_endpoint = 1;
  1668. ho->endpoint.class = cichar;
  1669. ho->endpoint.length = cilen;
  1670. BCOPY(p, ho->endpoint.value, cilen);
  1671. INCPTR(cilen, p);
  1672. break;
  1673. default:
  1674. LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
  1675. orc = CONFREJ;
  1676. break;
  1677. }
  1678. endswitch:
  1679. if (orc == CONFACK && /* Good CI */
  1680. rc != CONFACK) /* but prior CI wasnt? */
  1681. continue; /* Don't send this one */
  1682. if (orc == CONFNAK) { /* Nak this CI? */
  1683. if (reject_if_disagree /* Getting fed up with sending NAKs? */
  1684. && citype != CI_MAGICNUMBER) {
  1685. orc = CONFREJ; /* Get tough if so */
  1686. } else {
  1687. if (rc == CONFREJ) /* Rejecting prior CI? */
  1688. continue; /* Don't send this one */
  1689. rc = CONFNAK;
  1690. }
  1691. }
  1692. if (orc == CONFREJ) { /* Reject this CI */
  1693. rc = CONFREJ;
  1694. if (cip != rejp) /* Need to move rejected CI? */
  1695. BCOPY(cip, rejp, cilen); /* Move it */
  1696. INCPTR(cilen, rejp); /* Update output pointer */
  1697. }
  1698. }
  1699. /*
  1700. * If we wanted to send additional NAKs (for unsent CIs), the
  1701. * code would go here. The extra NAKs would go at *nakp.
  1702. * At present there are no cases where we want to ask the
  1703. * peer to negotiate an option.
  1704. */
  1705. switch (rc) {
  1706. case CONFACK:
  1707. *lenp = next - inp;
  1708. break;
  1709. case CONFNAK:
  1710. /*
  1711. * Copy the Nak'd options from the nak_buffer to the caller's buffer.
  1712. */
  1713. *lenp = nakp - nak_buffer;
  1714. BCOPY(nak_buffer, inp, *lenp);
  1715. break;
  1716. case CONFREJ:
  1717. *lenp = rejp - inp;
  1718. break;
  1719. }
  1720. LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
  1721. return (rc); /* Return final code */
  1722. }
  1723. /*
  1724. * lcp_up - LCP has come UP.
  1725. */
  1726. static void
  1727. lcp_up(f)
  1728. fsm *f;
  1729. {
  1730. lcp_options *wo = &lcp_wantoptions[f->unit];
  1731. lcp_options *ho = &lcp_hisoptions[f->unit];
  1732. lcp_options *go = &lcp_gotoptions[f->unit];
  1733. lcp_options *ao = &lcp_allowoptions[f->unit];
  1734. int mtu, mru;
  1735. if (!go->neg_magicnumber)
  1736. go->magicnumber = 0;
  1737. if (!ho->neg_magicnumber)
  1738. ho->magicnumber = 0;
  1739. /*
  1740. * Set our MTU to the smaller of the MTU we wanted and
  1741. * the MRU our peer wanted. If we negotiated an MRU,
  1742. * set our MRU to the larger of value we wanted and
  1743. * the value we got in the negotiation.
  1744. * Note on the MTU: the link MTU can be the MRU the peer wanted,
  1745. * the interface MTU is set to the lowest of that, the
  1746. * MTU we want to use, and our link MRU.
  1747. */
  1748. mtu = ho->neg_mru? ho->mru: PPP_MRU;
  1749. mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
  1750. #ifdef HAVE_MULTILINK
  1751. if (!(multilink && go->neg_mrru && ho->neg_mrru))
  1752. #endif /* HAVE_MULTILINK */
  1753. netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
  1754. ppp_send_config(f->unit, mtu,
  1755. (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
  1756. ho->neg_pcompression, ho->neg_accompression);
  1757. ppp_recv_config(f->unit, mru,
  1758. (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
  1759. go->neg_pcompression, go->neg_accompression);
  1760. if (ho->neg_mru)
  1761. peer_mru[f->unit] = ho->mru;
  1762. lcp_echo_lowerup(f->unit); /* Enable echo messages */
  1763. link_established(f->unit);
  1764. }
  1765. /*
  1766. * lcp_down - LCP has gone DOWN.
  1767. *
  1768. * Alert other protocols.
  1769. */
  1770. static void
  1771. lcp_down(f)
  1772. fsm *f;
  1773. {
  1774. lcp_options *go = &lcp_gotoptions[f->unit];
  1775. lcp_echo_lowerdown(f->unit);
  1776. link_down(f->unit);
  1777. ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
  1778. ppp_recv_config(f->unit, PPP_MRU,
  1779. (go->neg_asyncmap? go->asyncmap: 0xffffffff),
  1780. go->neg_pcompression, go->neg_accompression);
  1781. peer_mru[f->unit] = PPP_MRU;
  1782. }
  1783. /*
  1784. * lcp_starting - LCP needs the lower layer up.
  1785. */
  1786. static void
  1787. lcp_starting(f)
  1788. fsm *f;
  1789. {
  1790. link_required(f->unit);
  1791. }
  1792. /*
  1793. * lcp_finished - LCP has finished with the lower layer.
  1794. */
  1795. static void
  1796. lcp_finished(f)
  1797. fsm *f;
  1798. {
  1799. link_terminated(f->unit);
  1800. }
  1801. /*
  1802. * lcp_printpkt - print the contents of an LCP packet.
  1803. */
  1804. static char *lcp_codenames[] = {
  1805. "ConfReq", "ConfAck", "ConfNak", "ConfRej",
  1806. "TermReq", "TermAck", "CodeRej", "ProtRej",
  1807. "EchoReq", "EchoRep", "DiscReq", "Ident",
  1808. "TimeRem"
  1809. };
  1810. static int
  1811. lcp_printpkt(p, plen, printer, arg)
  1812. u_char *p;
  1813. int plen;
  1814. void (*printer) __P((void *, char *, ...));
  1815. void *arg;
  1816. {
  1817. int code, id, len, olen, i;
  1818. u_char *pstart, *optend;
  1819. u_short cishort;
  1820. u_int32_t cilong;
  1821. if (plen < HEADERLEN)
  1822. return 0;
  1823. pstart = p;
  1824. GETCHAR(code, p);
  1825. GETCHAR(id, p);
  1826. GETSHORT(len, p);
  1827. if (len < HEADERLEN || len > plen)
  1828. return 0;
  1829. if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
  1830. printer(arg, " %s", lcp_codenames[code-1]);
  1831. else
  1832. printer(arg, " code=0x%x", code);
  1833. printer(arg, " id=0x%x", id);
  1834. len -= HEADERLEN;
  1835. switch (code) {
  1836. case CONFREQ:
  1837. case CONFACK:
  1838. case CONFNAK:
  1839. case CONFREJ:
  1840. /* print option list */
  1841. while (len >= 2) {
  1842. GETCHAR(code, p);
  1843. GETCHAR(olen, p);
  1844. p -= 2;
  1845. if (olen < 2 || olen > len) {
  1846. break;
  1847. }
  1848. printer(arg, " <");
  1849. len -= olen;
  1850. optend = p + olen;
  1851. switch (code) {
  1852. case CI_MRU:
  1853. if (olen == CILEN_SHORT) {
  1854. p += 2;
  1855. GETSHORT(cishort, p);
  1856. printer(arg, "mru %d", cishort);
  1857. }
  1858. break;
  1859. case CI_ASYNCMAP:
  1860. if (olen == CILEN_LONG) {
  1861. p += 2;
  1862. GETLONG(cilong, p);
  1863. printer(arg, "asyncmap 0x%x", cilong);
  1864. }
  1865. break;
  1866. case CI_AUTHTYPE:
  1867. if (olen >= CILEN_SHORT) {
  1868. p += 2;
  1869. printer(arg, "auth ");
  1870. GETSHORT(cishort, p);
  1871. switch (cishort) {
  1872. case PPP_PAP:
  1873. printer(arg, "pap");
  1874. break;
  1875. case PPP_CHAP:
  1876. printer(arg, "chap");
  1877. if (p < optend) {
  1878. switch (*p) {
  1879. case CHAP_MD5:
  1880. printer(arg, " MD5");
  1881. ++p;
  1882. break;
  1883. case CHAP_MICROSOFT:
  1884. printer(arg, " MS");
  1885. ++p;
  1886. break;
  1887. case CHAP_MICROSOFT_V2:
  1888. printer(arg, " MS-v2");
  1889. ++p;
  1890. break;
  1891. }
  1892. }
  1893. break;
  1894. case PPP_EAP:
  1895. printer(arg, "eap");
  1896. break;
  1897. default:
  1898. printer(arg, "0x%x", cishort);
  1899. }
  1900. }
  1901. break;
  1902. case CI_QUALITY:
  1903. if (olen >= CILEN_SHORT) {
  1904. p += 2;
  1905. printer(arg, "quality ");
  1906. GETSHORT(cishort, p);
  1907. switch (cishort) {
  1908. case PPP_LQR:
  1909. printer(arg, "lqr");
  1910. break;
  1911. default:
  1912. printer(arg, "0x%x", cishort);
  1913. }
  1914. }
  1915. break;
  1916. case CI_CALLBACK:
  1917. if (olen >= CILEN_CHAR) {
  1918. p += 2;
  1919. printer(arg, "callback ");
  1920. GETCHAR(cishort, p);
  1921. switch (cishort) {
  1922. case CBCP_OPT:
  1923. printer(arg, "CBCP");
  1924. break;
  1925. default:
  1926. printer(arg, "0x%x", cishort);
  1927. }
  1928. }
  1929. break;
  1930. case CI_MAGICNUMBER:
  1931. if (olen == CILEN_LONG) {
  1932. p += 2;
  1933. GETLONG(cilong, p);
  1934. printer(arg, "magic 0x%x", cilong);
  1935. }
  1936. break;
  1937. case CI_PCOMPRESSION:
  1938. if (olen == CILEN_VOID) {
  1939. p += 2;
  1940. printer(arg, "pcomp");
  1941. }
  1942. break;
  1943. case CI_ACCOMPRESSION:
  1944. if (olen == CILEN_VOID) {
  1945. p += 2;
  1946. printer(arg, "accomp");
  1947. }
  1948. break;
  1949. case CI_MRRU:
  1950. if (olen == CILEN_SHORT) {
  1951. p += 2;
  1952. GETSHORT(cishort, p);
  1953. printer(arg, "mrru %d", cishort);
  1954. }
  1955. break;
  1956. case CI_SSNHF:
  1957. if (olen == CILEN_VOID) {
  1958. p += 2;
  1959. printer(arg, "ssnhf");
  1960. }
  1961. break;
  1962. case CI_EPDISC:
  1963. #ifdef HAVE_MULTILINK
  1964. if (olen >= CILEN_CHAR) {
  1965. struct epdisc epd;
  1966. p += 2;
  1967. GETCHAR(epd.class, p);
  1968. epd.length = olen - CILEN_CHAR;
  1969. if (epd.length > MAX_ENDP_LEN)
  1970. epd.length = MAX_ENDP_LEN;
  1971. if (epd.length > 0) {
  1972. BCOPY(p, epd.value, epd.length);
  1973. p += epd.length;
  1974. }
  1975. printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
  1976. }
  1977. #else
  1978. printer(arg, "endpoint");
  1979. #endif
  1980. break;
  1981. }
  1982. while (p < optend) {
  1983. GETCHAR(code, p);
  1984. printer(arg, " %.2x", code);
  1985. }
  1986. printer(arg, ">");
  1987. }
  1988. break;
  1989. case TERMACK:
  1990. case TERMREQ:
  1991. if (len > 0 && *p >= ' ' && *p < 0x7f) {
  1992. printer(arg, " ");
  1993. print_string((char *)p, len, printer, arg);
  1994. p += len;
  1995. len = 0;
  1996. }
  1997. break;
  1998. case ECHOREQ:
  1999. case ECHOREP:
  2000. case DISCREQ:
  2001. if (len >= 4) {
  2002. GETLONG(cilong, p);
  2003. printer(arg, " magic=0x%x", cilong);
  2004. len -= 4;
  2005. }
  2006. break;
  2007. case IDENTIF:
  2008. case TIMEREM:
  2009. if (len >= 4) {
  2010. GETLONG(cilong, p);
  2011. printer(arg, " magic=0x%x", cilong);
  2012. len -= 4;
  2013. }
  2014. if (code == TIMEREM) {
  2015. if (len < 4)
  2016. break;
  2017. GETLONG(cilong, p);
  2018. printer(arg, " seconds=%u", cilong);
  2019. len -= 4;
  2020. }
  2021. if (len > 0) {
  2022. printer(arg, " ");
  2023. print_string((char *)p, len, printer, arg);
  2024. p += len;
  2025. len = 0;
  2026. }
  2027. break;
  2028. }
  2029. /* print the rest of the bytes in the packet */
  2030. for (i = 0; i < len && i < 32; ++i) {
  2031. GETCHAR(code, p);
  2032. printer(arg, " %.2x", code);
  2033. }
  2034. if (i < len) {
  2035. printer(arg, " ...");
  2036. p += len - i;
  2037. }
  2038. return p - pstart;
  2039. }
  2040. /*
  2041. * Time to shut down the link because there is nothing out there.
  2042. */
  2043. static
  2044. void LcpLinkFailure (f)
  2045. fsm *f;
  2046. {
  2047. if (f->state == OPENED) {
  2048. info("No response to %d echo-requests", lcp_echos_pending);
  2049. notice("Serial link appears to be disconnected.");
  2050. status = EXIT_PEER_DEAD;
  2051. lcp_close(f->unit, "Peer not responding");
  2052. }
  2053. }
  2054. /*
  2055. * Timer expired for the LCP echo requests from this process.
  2056. */
  2057. static void
  2058. LcpEchoCheck (f)
  2059. fsm *f;
  2060. {
  2061. LcpSendEchoRequest (f);
  2062. if (f->state != OPENED)
  2063. return;
  2064. /*
  2065. * Start the timer for the next interval.
  2066. */
  2067. if (lcp_echo_timer_running)
  2068. warn("assertion lcp_echo_timer_running==0 failed");
  2069. TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
  2070. lcp_echo_timer_running = 1;
  2071. }
  2072. /*
  2073. * LcpEchoTimeout - Timer expired on the LCP echo
  2074. */
  2075. static void
  2076. LcpEchoTimeout (arg)
  2077. void *arg;
  2078. {
  2079. if (lcp_echo_timer_running != 0) {
  2080. lcp_echo_timer_running = 0;
  2081. LcpEchoCheck ((fsm *) arg);
  2082. }
  2083. }
  2084. /*
  2085. * LcpEchoReply - LCP has received a reply to the echo
  2086. */
  2087. static void
  2088. lcp_received_echo_reply (f, id, inp, len)
  2089. fsm *f;
  2090. int id;
  2091. u_char *inp;
  2092. int len;
  2093. {
  2094. u_int32_t magic;
  2095. /* Check the magic number - don't count replies from ourselves. */
  2096. if (len < 4) {
  2097. dbglog("lcp: received short Echo-Reply, length %d", len);
  2098. return;
  2099. }
  2100. GETLONG(magic, inp);
  2101. if (lcp_gotoptions[f->unit].neg_magicnumber
  2102. && magic == lcp_gotoptions[f->unit].magicnumber) {
  2103. warn("appear to have received our own echo-reply!");
  2104. return;
  2105. }
  2106. /* Reset the number of outstanding echo frames */
  2107. lcp_echos_pending = 0;
  2108. }
  2109. /*
  2110. * LcpSendEchoRequest - Send an echo request frame to the peer
  2111. */
  2112. static void
  2113. LcpSendEchoRequest (f)
  2114. fsm *f;
  2115. {
  2116. u_int32_t lcp_magic;
  2117. u_char pkt[4], *pktp;
  2118. /*
  2119. * Detect the failure of the peer at this point.
  2120. */
  2121. if (lcp_echo_fails != 0) {
  2122. if (lcp_echos_pending >= lcp_echo_fails) {
  2123. LcpLinkFailure(f);
  2124. lcp_echos_pending = 0;
  2125. }
  2126. }
  2127. /*
  2128. * Make and send the echo request frame.
  2129. */
  2130. if (f->state == OPENED) {
  2131. lcp_magic = lcp_gotoptions[f->unit].magicnumber;
  2132. pktp = pkt;
  2133. PUTLONG(lcp_magic, pktp);
  2134. fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
  2135. ++lcp_echos_pending;
  2136. }
  2137. }
  2138. /*
  2139. * lcp_echo_lowerup - Start the timer for the LCP frame
  2140. */
  2141. static void
  2142. lcp_echo_lowerup (unit)
  2143. int unit;
  2144. {
  2145. fsm *f = &lcp_fsm[unit];
  2146. /* Clear the parameters for generating echo frames */
  2147. lcp_echos_pending = 0;
  2148. lcp_echo_number = 0;
  2149. lcp_echo_timer_running = 0;
  2150. /* If a timeout interval is specified then start the timer */
  2151. if (lcp_echo_interval != 0)
  2152. LcpEchoCheck (f);
  2153. }
  2154. /*
  2155. * lcp_echo_lowerdown - Stop the timer for the LCP frame
  2156. */
  2157. static void
  2158. lcp_echo_lowerdown (unit)
  2159. int unit;
  2160. {
  2161. fsm *f = &lcp_fsm[unit];
  2162. if (lcp_echo_timer_running != 0) {
  2163. UNTIMEOUT (LcpEchoTimeout, f);
  2164. lcp_echo_timer_running = 0;
  2165. }
  2166. }