71#define DELAYED_UP 0x80
73static void lcp_delayed_up(
void *
arg);
79int lcp_echo_interval = 0;
80int lcp_echo_fails = 0;
85static u_int lcp_echo_interval = LCP_ECHOINTERVAL;
86static u_int lcp_echo_fails = LCP_MAXECHOFAILS;
91bool lcp_echo_adaptive = 0;
98static int noopt (
char **);
102static int setendpoint (
char **);
103static void printendpoint (option_t *,
void (*)(
void *,
char *, ...),
108static option_t lcp_option_list[] = {
110 {
"-all", o_special_noarg, (
void *)noopt,
111 "Don't request/allow any LCP options" },
113 {
"noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
114 "Disable address/control compression",
115 OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
116 {
"-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
117 "Disable address/control compression",
118 OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
120 {
"asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
121 "Set asyncmap (for received packets)",
122 OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
123 {
"-as", o_uint32, &lcp_wantoptions[0].asyncmap,
124 "Set asyncmap (for received packets)",
125 OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
126 {
"default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
127 "Disable asyncmap negotiation",
128 OPT_OR | OPT_NOARG | OPT_VAL(~0
U) | OPT_A2CLR,
129 &lcp_allowoptions[0].neg_asyncmap },
130 {
"-am", o_uint32, &lcp_wantoptions[0].asyncmap,
131 "Disable asyncmap negotiation",
132 OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0
U) | OPT_A2CLR,
133 &lcp_allowoptions[0].neg_asyncmap },
135 {
"nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
136 "Disable magic number negotiation (looped-back line detection)",
137 OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
138 {
"-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
139 "Disable magic number negotiation (looped-back line detection)",
140 OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
142 {
"mru", o_int, &lcp_wantoptions[0].mru,
143 "Set MRU (maximum received packet size) for negotiation",
144 OPT_PRIO, &lcp_wantoptions[0].neg_mru },
145 {
"default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
146 "Disable MRU negotiation (use default 1500)",
147 OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
148 {
"-mru", o_bool, &lcp_wantoptions[0].neg_mru,
149 "Disable MRU negotiation (use default 1500)",
150 OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
152 {
"mtu", o_int, &lcp_allowoptions[0].mru,
153 "Set our MTU", OPT_LIMITS,
NULL, MAXMRU, MINMRU },
155 {
"nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
156 "Disable protocol field compression",
157 OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
158 {
"-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
159 "Disable protocol field compression",
160 OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
162 {
"passive", o_bool, &lcp_wantoptions[0].passive,
163 "Set passive mode", 1 },
164 {
"-p", o_bool, &lcp_wantoptions[0].passive,
165 "Set passive mode", OPT_ALIAS | 1 },
167 {
"silent", o_bool, &lcp_wantoptions[0].silent,
168 "Set silent mode", 1 },
170 {
"lcp-echo-failure", o_int, &lcp_echo_fails,
171 "Set number of consecutive echo failures to indicate link failure",
173 {
"lcp-echo-interval", o_int, &lcp_echo_interval,
174 "Set time in seconds between LCP echo requests", OPT_PRIO },
176 {
"lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
177 "Suppress LCP echo requests if traffic was received", 1 },
179 {
"lcp-restart", o_int, &lcp_fsm[0].timeouttime,
180 "Set time in seconds between LCP retransmissions", OPT_PRIO },
181 {
"lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
182 "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
183 {
"lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
184 "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
185 {
"lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
186 "Set limit on number of LCP configure-naks", OPT_PRIO },
188 {
"receive-all", o_bool, &lax_recv,
189 "Accept all received control characters", 1 },
192 {
"mrru", o_int, &lcp_wantoptions[0].mrru,
193 "Maximum received packet size for multilink bundle",
194 OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
196 {
"mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
197 "Use short sequence numbers in multilink headers",
198 OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
199 {
"nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
200 "Don't use short sequence numbers in multilink headers",
201 OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
203 {
"endpoint", o_special, (
void *) setendpoint,
204 "Endpoint discriminator for multilink",
205 OPT_PRIO | OPT_A2PRINTER, (
void *) printendpoint },
208 {
"noendpoint", o_bool, &noendpoint,
209 "Don't send or accept multilink endpoint discriminator", 1 },
218static void lcp_resetci(fsm *
f);
219static int lcp_cilen(fsm *
f);
220static void lcp_addci(fsm *
f,
u_char *ucp,
int *lenp);
222static int lcp_nakci(fsm *
f,
u_char *
p,
int len,
int treat_as_reject);
224static int lcp_reqci(fsm *
f,
u_char *inp,
int *lenp,
int reject_if_disagree);
225static void lcp_up(fsm *
f);
226static void lcp_down(fsm *
f);
227static void lcp_starting (fsm *);
228static void lcp_finished (fsm *);
229static int lcp_extcode(fsm *
f,
int code,
int id,
u_char *inp,
int len);
230static void lcp_rprotrej(fsm *
f,
u_char *inp,
int len);
236static void lcp_echo_lowerup(ppp_pcb *pcb);
237static void lcp_echo_lowerdown(ppp_pcb *pcb);
238static void LcpEchoTimeout(
void *
arg);
239static void lcp_received_echo_reply(fsm *
f,
int id,
u_char *inp,
int len);
240static void LcpSendEchoRequest(fsm *
f);
241static void LcpLinkFailure(fsm *
f);
242static void LcpEchoCheck(fsm *
f);
244static const fsm_callbacks lcp_callbacks = {
267static void lcp_init(ppp_pcb *pcb);
268static void lcp_input(ppp_pcb *pcb,
u_char *
p,
int len);
269static void lcp_protrej(ppp_pcb *pcb);
271static int lcp_printpkt(
const u_char *
p,
int plen,
272 void (*printer) (
void *,
const char *, ...),
void *
arg);
275const struct protent lcp_protent = {
319#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
320 (x) == CONFNAK ? "NAK" : "REJ")
330 BZERO((
char *) &lcp_wantoptions[0],
sizeof (
struct lcp_options));
331 BZERO((
char *) &lcp_allowoptions[0],
sizeof (
struct lcp_options));
342 if (str_to_epdisc(&lcp_wantoptions[0].
endpoint, *
argv)) {
343 lcp_wantoptions[0].neg_endpoint = 1;
346 option_error(
"Can't parse '%s' as an endpoint discriminator", *
argv);
351printendpoint(opt, printer,
arg)
353 void (*printer) (
void *,
char *, ...);
356 printer(
arg,
"%s", epdisc_to_str(&lcp_wantoptions[0].
endpoint));
363static void lcp_init(ppp_pcb *pcb) {
364 fsm *
f = &pcb->lcp_fsm;
365 lcp_options *wo = &pcb->lcp_wantoptions;
366 lcp_options *ao = &pcb->lcp_allowoptions;
369 f->protocol = PPP_LCP;
370 f->callbacks = &lcp_callbacks;
374 BZERO(wo,
sizeof(*wo));
377 wo->neg_asyncmap = 1;
378 wo->neg_magicnumber = 1;
379 wo->neg_pcompression = 1;
380 wo->neg_accompression = 1;
382 BZERO(ao,
sizeof(*ao));
384 ao->mru = PPP_MAXMRU;
385 ao->neg_asyncmap = 1;
388 ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED;
396 ao->neg_magicnumber = 1;
397 ao->neg_pcompression = 1;
398 ao->neg_accompression = 1;
399 ao->neg_endpoint = 1;
406void lcp_open(ppp_pcb *pcb) {
407 fsm *
f = &pcb->lcp_fsm;
408 lcp_options *wo = &pcb->lcp_wantoptions;
410 f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
412 f->flags |= OPT_PASSIVE;
414 f->flags |= OPT_SILENT;
422void lcp_close(ppp_pcb *pcb,
const char *
reason) {
423 fsm *
f = &pcb->lcp_fsm;
426 if (pcb->phase != PPP_PHASE_DEAD
428 && pcb->phase != PPP_PHASE_MASTER
431 new_phase(pcb, PPP_PHASE_TERMINATE);
433 if (
f->flags & DELAYED_UP) {
434 UNTIMEOUT(lcp_delayed_up,
f);
435 f->state = PPP_FSM_STOPPED;
440 if (oldstate == PPP_FSM_STOPPED && (
f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) {
448 f->flags &= ~DELAYED_UP;
457void lcp_lowerup(ppp_pcb *pcb) {
458 lcp_options *wo = &pcb->lcp_wantoptions;
459 fsm *
f = &pcb->lcp_fsm;
465 if (ppp_send_config(pcb, PPP_DEFMRU, 0xffffffff, 0, 0) < 0
466 || ppp_recv_config(pcb, PPP_DEFMRU, (pcb->settings.lax_recv? 0: 0xffffffff),
467 wo->neg_pcompression, wo->neg_accompression) < 0)
469 pcb->peer_mru = PPP_DEFMRU;
471 if (pcb->settings.listen_time != 0) {
472 f->flags |= DELAYED_UP;
473 TIMEOUTMS(lcp_delayed_up,
f, pcb->settings.listen_time);
482void lcp_lowerdown(ppp_pcb *pcb) {
483 fsm *
f = &pcb->lcp_fsm;
485 if (
f->flags & DELAYED_UP) {
486 f->flags &= ~DELAYED_UP;
487 UNTIMEOUT(lcp_delayed_up,
f);
496static void lcp_delayed_up(
void *
arg) {
499 if (
f->flags & DELAYED_UP) {
500 f->flags &= ~DELAYED_UP;
509static void lcp_input(ppp_pcb *pcb,
u_char *
p,
int len) {
510 fsm *
f = &pcb->lcp_fsm;
512 if (
f->flags & DELAYED_UP) {
513 f->flags &= ~DELAYED_UP;
514 UNTIMEOUT(lcp_delayed_up,
f);
517 fsm_input(
f,
p,
len);
523static int lcp_extcode(fsm *
f,
int code,
int id,
u_char *inp,
int len) {
524 ppp_pcb *pcb =
f->pcb;
525 lcp_options *go = &pcb->lcp_gotoptions;
530 lcp_rprotrej(
f, inp,
len);
534 if (
f->state != PPP_FSM_OPENED)
537 PUTLONG(go->magicnumber, magp);
538 fsm_sdata(
f, ECHOREP,
id, inp,
len);
542 lcp_received_echo_reply(
f,
id, inp,
len);
562static void lcp_rprotrej(fsm *
f,
u_char *inp,
int len) {
564 const struct protent *protp;
571 LCPDEBUG((
"lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
581 if(
f->state != PPP_FSM_OPENED ){
582 LCPDEBUG((
"Protocol-Reject discarded: LCP in state %d",
f->state));
587 pname = protocol_name(prot);
594 if (protp->protocol == prot) {
597 ppp_dbglog((
"Protocol-Reject for '%s' (0x%x) received",
pname,
601 ppp_dbglog((
"Protocol-Reject for 0x%x received", prot));
602 (*protp->protrej)(
f->pcb);
608 ppp_warn((
"Protocol-Reject for unsupported protocol '%s' (0x%x)",
pname,
612 ppp_warn((
"Protocol-Reject for unsupported protocol 0x%x", prot));
620static void lcp_protrej(ppp_pcb *pcb) {
624 ppp_error((
"Received Protocol-Reject for LCP!"));
625 fsm_protreject(&pcb->lcp_fsm);
632void lcp_sprotrej(ppp_pcb *pcb,
u_char *
p,
int len) {
633 fsm *
f = &pcb->lcp_fsm;
643 fsm_sdata(
f, PROTREJ, ++
f->id,
651static void lcp_resetci(fsm *
f) {
652 ppp_pcb *pcb =
f->pcb;
653 lcp_options *wo = &pcb->lcp_wantoptions;
654 lcp_options *go = &pcb->lcp_gotoptions;
655 lcp_options *ao = &pcb->lcp_allowoptions;
660 if (pcb->settings.user && pcb->settings.passwd) {
662 if (pcb->settings.refuse_pap) {
667 if (pcb->settings.refuse_chap) {
668 ao->chap_mdtype &= ~MDTYPE_MD5;
671 if (pcb->settings.refuse_mschap) {
672 ao->chap_mdtype &= ~MDTYPE_MICROSOFT;
674 if (pcb->settings.refuse_mschap_v2) {
675 ao->chap_mdtype &= ~MDTYPE_MICROSOFT_V2;
678 ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE);
681 if (pcb->settings.refuse_eap) {
688 if (pcb->settings.auth_required) {
690 if (!pcb->settings.refuse_pap) {
695 if (!pcb->settings.refuse_chap) {
696 wo->chap_mdtype |= MDTYPE_MD5;
699 if (!pcb->settings.refuse_mschap) {
700 wo->chap_mdtype |= MDTYPE_MICROSOFT;
702 if (!pcb->settings.refuse_mschap_v2) {
703 wo->chap_mdtype |= MDTYPE_MICROSOFT_V2;
706 wo->neg_chap = (wo->chap_mdtype != MDTYPE_NONE);
709 if (!pcb->settings.refuse_eap) {
722 ao->chap_mdtype = MDTYPE_NONE;
729 PPPDEBUG(
LOG_DEBUG, (
"ppp: auth protocols:"));
731 PPPDEBUG(
LOG_DEBUG, (
" PAP=%d", ao->neg_upap));
734 PPPDEBUG(
LOG_DEBUG, (
" CHAP=%d CHAP_MD5=%d", ao->neg_chap, !!(ao->chap_mdtype&MDTYPE_MD5)));
736 PPPDEBUG(
LOG_DEBUG, (
" CHAP_MS=%d CHAP_MS2=%d", !!(ao->chap_mdtype&MDTYPE_MICROSOFT), !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2)));
740 PPPDEBUG(
LOG_DEBUG, (
" EAP=%d", ao->neg_eap));
746 wo->magicnumber = magic();
754 go->neg_endpoint = 0;
758 if (pcb->settings.noendpoint)
759 ao->neg_endpoint = 0;
760 pcb->peer_mru = PPP_DEFMRU;
770static int lcp_cilen(fsm *
f) {
771 ppp_pcb *pcb =
f->pcb;
772 lcp_options *go = &pcb->lcp_gotoptions;
774#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
776#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
778#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
779#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
781#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
783#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
789 return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
790 LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
792 LENCISHORT(go->neg_eap) +
796 LENCICHAP(!go->neg_eap && go->neg_chap) +
799 LENCICHAP(go->neg_chap) +
803#
if EAP_SUPPORT && CHAP_SUPPORT
804 LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
806#
if EAP_SUPPORT && !CHAP_SUPPORT
807 LENCISHORT(!go->neg_eap && go->neg_upap) +
809#
if !EAP_SUPPORT && CHAP_SUPPORT
810 LENCISHORT(!go->neg_chap && go->neg_upap) +
812#
if !EAP_SUPPORT && !CHAP_SUPPORT
813 LENCISHORT(go->neg_upap) +
817 LENCILQR(go->neg_lqr) +
819 LENCICBCP(go->neg_cbcp) +
820 LENCILONG(go->neg_magicnumber) +
821 LENCIVOID(go->neg_pcompression) +
822 LENCIVOID(go->neg_accompression) +
824 LENCISHORT(go->neg_mrru) +
826 LENCIVOID(go->neg_ssnhf) +
827 (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
834static void lcp_addci(fsm *
f,
u_char *ucp,
int *lenp) {
835 ppp_pcb *pcb =
f->pcb;
836 lcp_options *go = &pcb->lcp_gotoptions;
839#define ADDCIVOID(opt, neg) \
842 PUTCHAR(CILEN_VOID, ucp); \
844#define ADDCISHORT(opt, neg, val) \
847 PUTCHAR(CILEN_SHORT, ucp); \
848 PUTSHORT(val, ucp); \
851#define ADDCICHAP(opt, neg, val) \
853 PUTCHAR((opt), ucp); \
854 PUTCHAR(CILEN_CHAP, ucp); \
855 PUTSHORT(PPP_CHAP, ucp); \
856 PUTCHAR((CHAP_DIGEST(val)), ucp); \
859#define ADDCILONG(opt, neg, val) \
862 PUTCHAR(CILEN_LONG, ucp); \
866#define ADDCILQR(opt, neg, val) \
869 PUTCHAR(CILEN_LQR, ucp); \
870 PUTSHORT(PPP_LQR, ucp); \
874#define ADDCICHAR(opt, neg, val) \
877 PUTCHAR(CILEN_CHAR, ucp); \
880#define ADDCIENDP(opt, neg, class, val, len) \
884 PUTCHAR(CILEN_CHAR + len, ucp); \
885 PUTCHAR(class, ucp); \
886 for (i = 0; i < len; ++i) \
887 PUTCHAR(val[i], ucp); \
890 ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
891 ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
894 ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
898 ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
901 ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
905#if EAP_SUPPORT && CHAP_SUPPORT
906 ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP);
908#if EAP_SUPPORT && !CHAP_SUPPORT
909 ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP);
911#if !EAP_SUPPORT && CHAP_SUPPORT
912 ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
914#if !EAP_SUPPORT && !CHAP_SUPPORT
915 ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP);
919 ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
921 ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
922 ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
923 ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
924 ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
926 ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
928 ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
929 ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_,
930 go->endpoint.value, go->endpoint.length);
932 if (ucp - start_ucp != *lenp) {
934 ppp_error((
"Bug in lcp_addci: wrong length"));
948 ppp_pcb *pcb =
f->pcb;
949 lcp_options *go = &pcb->lcp_gotoptions;
950 u_char cilen, citype, cichar;
959#define ACKCIVOID(opt, neg) \
961 if ((len -= CILEN_VOID) < 0) \
963 GETCHAR(citype, p); \
965 if (cilen != CILEN_VOID || \
969#define ACKCISHORT(opt, neg, val) \
971 if ((len -= CILEN_SHORT) < 0) \
973 GETCHAR(citype, p); \
975 if (cilen != CILEN_SHORT || \
978 GETSHORT(cishort, p); \
979 if (cishort != val) \
982#define ACKCICHAR(opt, neg, val) \
984 if ((len -= CILEN_CHAR) < 0) \
986 GETCHAR(citype, p); \
988 if (cilen != CILEN_CHAR || \
991 GETCHAR(cichar, p); \
996#define ACKCICHAP(opt, neg, val) \
998 if ((len -= CILEN_CHAP) < 0) \
1000 GETCHAR(citype, p); \
1001 GETCHAR(cilen, p); \
1002 if (cilen != CILEN_CHAP || \
1005 GETSHORT(cishort, p); \
1006 if (cishort != PPP_CHAP) \
1008 GETCHAR(cichar, p); \
1009 if (cichar != (CHAP_DIGEST(val))) \
1013#define ACKCILONG(opt, neg, val) \
1015 if ((len -= CILEN_LONG) < 0) \
1017 GETCHAR(citype, p); \
1018 GETCHAR(cilen, p); \
1019 if (cilen != CILEN_LONG || \
1022 GETLONG(cilong, p); \
1023 if (cilong != val) \
1027#define ACKCILQR(opt, neg, val) \
1029 if ((len -= CILEN_LQR) < 0) \
1031 GETCHAR(citype, p); \
1032 GETCHAR(cilen, p); \
1033 if (cilen != CILEN_LQR || \
1036 GETSHORT(cishort, p); \
1037 if (cishort != PPP_LQR) \
1039 GETLONG(cilong, p); \
1040 if (cilong != val) \
1044#define ACKCIENDP(opt, neg, class, val, vlen) \
1047 if ((len -= CILEN_CHAR + vlen) < 0) \
1049 GETCHAR(citype, p); \
1050 GETCHAR(cilen, p); \
1051 if (cilen != CILEN_CHAR + vlen || \
1054 GETCHAR(cichar, p); \
1055 if (cichar != class) \
1057 for (i = 0; i < vlen; ++i) { \
1058 GETCHAR(cichar, p); \
1059 if (cichar != val[i]) \
1064 ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
1065 ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
1068 ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
1072 ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
1075 ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
1079#if EAP_SUPPORT && CHAP_SUPPORT
1080 ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP);
1082#if EAP_SUPPORT && !CHAP_SUPPORT
1083 ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP);
1085#if !EAP_SUPPORT && CHAP_SUPPORT
1086 ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
1088#if !EAP_SUPPORT && !CHAP_SUPPORT
1089 ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP);
1093 ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
1095 ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
1096 ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
1097 ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
1098 ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
1099#ifdef HAVE_MULTILINK
1100 ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
1102 ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
1103 ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_,
1104 go->endpoint.value, go->endpoint.length);
1113 LCPDEBUG((
"lcp_acki: received bad Ack!"));
1127static int lcp_nakci(fsm *
f,
u_char *
p,
int len,
int treat_as_reject) {
1128 ppp_pcb *pcb =
f->pcb;
1129 lcp_options *go = &pcb->lcp_gotoptions;
1130 lcp_options *wo = &pcb->lcp_wantoptions;
1136 int looped_back = 0;
1139 BZERO(&
no,
sizeof(
no));
1147#define NAKCIVOID(opt, neg) \
1149 len >= CILEN_VOID && \
1150 p[1] == CILEN_VOID && \
1152 len -= CILEN_VOID; \
1153 INCPTR(CILEN_VOID, p); \
1158#define NAKCICHAP(opt, neg, code) \
1160 len >= CILEN_CHAP && \
1161 p[1] == CILEN_CHAP && \
1163 len -= CILEN_CHAP; \
1165 GETSHORT(cishort, p); \
1166 GETCHAR(cichar, p); \
1171#define NAKCICHAR(opt, neg, code) \
1173 len >= CILEN_CHAR && \
1174 p[1] == CILEN_CHAR && \
1176 len -= CILEN_CHAR; \
1178 GETCHAR(cichar, p); \
1182#define NAKCISHORT(opt, neg, code) \
1184 len >= CILEN_SHORT && \
1185 p[1] == CILEN_SHORT && \
1187 len -= CILEN_SHORT; \
1189 GETSHORT(cishort, p); \
1193#define NAKCILONG(opt, neg, code) \
1195 len >= CILEN_LONG && \
1196 p[1] == CILEN_LONG && \
1198 len -= CILEN_LONG; \
1200 GETLONG(cilong, p); \
1205#define NAKCILQR(opt, neg, code) \
1207 len >= CILEN_LQR && \
1208 p[1] == CILEN_LQR && \
1212 GETSHORT(cishort, p); \
1213 GETLONG(cilong, p); \
1218#define NAKCIENDP(opt, neg) \
1220 len >= CILEN_CHAR && \
1222 p[1] >= CILEN_CHAR && \
1241 if (go->neg_mru && go->mru != PPP_DEFMRU) {
1242 NAKCISHORT(CI_MRU, neg_mru,
1243 if (cishort <= wo->mru || cishort <= PPP_DEFMRU)
1251 if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
1252 NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
1253 try_.asyncmap = go->asyncmap | cilong;
1273 &&
len >= CILEN_SHORT
1274 &&
p[0] == CI_AUTHTYPE &&
p[1] >= CILEN_SHORT &&
p[1] <=
len) {
1278 no.neg_chap = go->neg_chap;
1281 no.neg_upap = go->neg_upap;
1284 no.neg_eap = go->neg_eap;
1287 GETSHORT(cishort,
p);
1290 if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
1314 if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
1321 if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
1322 try_.chap_mdtype = CHAP_MDTYPE_D(cichar);
1330 if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
1331 if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
1333 try_.chap_mdtype = CHAP_MDTYPE_D(cichar);
1336 try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype));
1337 if (try_.chap_mdtype == MDTYPE_NONE)
1365 if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
1366 ppp_dbglog((
"Unexpected Conf-Nak for EAP"));
1390 p += cilen - CILEN_SHORT;
1400 NAKCILQR(CI_QUALITY, neg_lqr,
1401 if (cishort != PPP_LQR)
1404 try_.lqr_period = cilong;
1411 NAKCICHAR(CI_CALLBACK, neg_cbcp,
1419 NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
1420 try_.magicnumber = magic();
1429 NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
1430 NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
1432#ifdef HAVE_MULTILINK
1438 NAKCISHORT(CI_MRRU, neg_mrru,
1439 if (treat_as_reject)
1441 else if (cishort <= wo->mrru)
1442 try_.mrru = cishort;
1453 NAKCIVOID(CI_SSNHF, neg_ssnhf);
1459 NAKCIENDP(CI_EPDISC, neg_endpoint);
1477 while (
len >= CILEN_VOID) {
1480 if (cilen < CILEN_VOID || (
len -= cilen) < 0)
1482 next =
p + cilen - 2;
1486 if ((go->neg_mru && go->mru != PPP_DEFMRU)
1487 ||
no.neg_mru || cilen != CILEN_SHORT)
1489 GETSHORT(cishort,
p);
1490 if (cishort < PPP_DEFMRU) {
1496 if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
1497 ||
no.neg_asyncmap || cilen != CILEN_LONG)
1507 || go->neg_chap ||
no.neg_chap
1510 || go->neg_upap ||
no.neg_upap
1513 || go->neg_eap ||
no.neg_eap
1518 case CI_MAGICNUMBER:
1519 if (go->neg_magicnumber ||
no.neg_magicnumber ||
1520 cilen != CILEN_LONG)
1523 case CI_PCOMPRESSION:
1524 if (go->neg_pcompression ||
no.neg_pcompression
1525 || cilen != CILEN_VOID)
1528 case CI_ACCOMPRESSION:
1529 if (go->neg_accompression ||
no.neg_accompression
1530 || cilen != CILEN_VOID)
1535 if (go->neg_lqr ||
no.neg_lqr || cilen != CILEN_LQR)
1539#ifdef HAVE_MULTILINK
1541 if (go->neg_mrru ||
no.neg_mrru || cilen != CILEN_SHORT)
1546 if (go->neg_ssnhf ||
no.neg_ssnhf || cilen != CILEN_VOID)
1551 if (go->neg_endpoint ||
no.neg_endpoint || cilen < CILEN_CHAR)
1564 if (
f->state != PPP_FSM_OPENED) {
1566 if (++try_.numloops >= pcb->settings.lcp_loopbackfail) {
1567 ppp_notice((
"Serial line is looped back."));
1568 pcb->err_code = PPPERR_LOOPBACK;
1569 lcp_close(
f->pcb,
"Loopback detected");
1579 LCPDEBUG((
"lcp_nakci: received bad Nak!"));
1594 ppp_pcb *pcb =
f->pcb;
1595 lcp_options *go = &pcb->lcp_gotoptions;
1608#define REJCIVOID(opt, neg) \
1610 len >= CILEN_VOID && \
1611 p[1] == CILEN_VOID && \
1613 len -= CILEN_VOID; \
1614 INCPTR(CILEN_VOID, p); \
1617#define REJCISHORT(opt, neg, val) \
1619 len >= CILEN_SHORT && \
1620 p[1] == CILEN_SHORT && \
1622 len -= CILEN_SHORT; \
1624 GETSHORT(cishort, p); \
1626 if (cishort != val) \
1631#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT
1632#define REJCICHAP(opt, neg, val) \
1634 len >= CILEN_CHAP && \
1635 p[1] == CILEN_CHAP && \
1637 len -= CILEN_CHAP; \
1639 GETSHORT(cishort, p); \
1640 GETCHAR(cichar, p); \
1642 if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1645 try_.neg_eap = try_.neg_upap = 0; \
1649#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT
1650#define REJCICHAP(opt, neg, val) \
1652 len >= CILEN_CHAP && \
1653 p[1] == CILEN_CHAP && \
1655 len -= CILEN_CHAP; \
1657 GETSHORT(cishort, p); \
1658 GETCHAR(cichar, p); \
1660 if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1663 try_.neg_upap = 0; \
1667#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT
1668#define REJCICHAP(opt, neg, val) \
1670 len >= CILEN_CHAP && \
1671 p[1] == CILEN_CHAP && \
1673 len -= CILEN_CHAP; \
1675 GETSHORT(cishort, p); \
1676 GETCHAR(cichar, p); \
1678 if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1685#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT
1686#define REJCICHAP(opt, neg, val) \
1688 len >= CILEN_CHAP && \
1689 p[1] == CILEN_CHAP && \
1691 len -= CILEN_CHAP; \
1693 GETSHORT(cishort, p); \
1694 GETCHAR(cichar, p); \
1696 if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1702#define REJCILONG(opt, neg, val) \
1704 len >= CILEN_LONG && \
1705 p[1] == CILEN_LONG && \
1707 len -= CILEN_LONG; \
1709 GETLONG(cilong, p); \
1711 if (cilong != val) \
1716#define REJCILQR(opt, neg, val) \
1718 len >= CILEN_LQR && \
1719 p[1] == CILEN_LQR && \
1723 GETSHORT(cishort, p); \
1724 GETLONG(cilong, p); \
1726 if (cishort != PPP_LQR || cilong != val) \
1731#define REJCICBCP(opt, neg, val) \
1733 len >= CILEN_CBCP && \
1734 p[1] == CILEN_CBCP && \
1736 len -= CILEN_CBCP; \
1738 GETCHAR(cichar, p); \
1740 if (cichar != val) \
1744#define REJCIENDP(opt, neg, class, val, vlen) \
1746 len >= CILEN_CHAR + vlen && \
1748 p[1] == CILEN_CHAR + vlen) { \
1750 len -= CILEN_CHAR + vlen; \
1752 GETCHAR(cichar, p); \
1753 if (cichar != class) \
1755 for (i = 0; i < vlen; ++i) { \
1756 GETCHAR(cichar, p); \
1757 if (cichar != val[i]) \
1763 REJCISHORT(CI_MRU, neg_mru, go->mru);
1764 REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
1766 REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
1770 REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
1771 if (!go->neg_chap) {
1774 REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
1783 REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
1785 REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
1786 REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
1787 REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
1788 REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
1789#ifdef HAVE_MULTILINK
1790 REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
1792 REJCIVOID(CI_SSNHF, neg_ssnhf);
1793 REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_,
1794 go->endpoint.value, go->endpoint.length);
1804 if (
f->state != PPP_FSM_OPENED)
1809 LCPDEBUG((
"lcp_rejci: received bad Reject!"));
1824static int lcp_reqci(fsm *
f,
u_char *inp,
int *lenp,
int reject_if_disagree) {
1825 ppp_pcb *pcb =
f->pcb;
1826 lcp_options *go = &pcb->lcp_gotoptions;
1827 lcp_options *ho = &pcb->lcp_hisoptions;
1828 lcp_options *ao = &pcb->lcp_allowoptions;
1830 int cilen, citype, cichar;
1844 BZERO(ho,
sizeof(*ho));
1866 LCPDEBUG((
"lcp_reqci: bad CI length!"));
1881 cilen != CILEN_SHORT) {
1885 GETSHORT(cishort,
p);
1892 if (cishort < PPP_MINMRU) {
1894 PUTCHAR(CI_MRU, nakoutp);
1895 PUTCHAR(CILEN_SHORT, nakoutp);
1896 PUTSHORT(PPP_MINMRU, nakoutp);
1904 if (!ao->neg_asyncmap ||
1905 cilen != CILEN_LONG) {
1915 if ((ao->asyncmap & ~cilong) != 0) {
1917 PUTCHAR(CI_ASYNCMAP, nakoutp);
1918 PUTCHAR(CILEN_LONG, nakoutp);
1919 PUTLONG(ao->asyncmap | cilong, nakoutp);
1922 ho->neg_asyncmap = 1;
1923 ho->asyncmap = cilong;
1927 if (cilen < CILEN_SHORT ||
1942 ppp_dbglog((
"No auth is possible"));
1946 GETSHORT(cishort,
p);
1960 if (cishort == PPP_PAP) {
1969 || cilen != CILEN_SHORT) {
1970 LCPDEBUG((
"lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1974 if (!ao->neg_upap) {
1976 PUTCHAR(CI_AUTHTYPE, nakoutp);
1979 PUTCHAR(CILEN_SHORT, nakoutp);
1980 PUTSHORT(PPP_EAP, nakoutp);
1984 PUTCHAR(CILEN_CHAP, nakoutp);
1985 PUTSHORT(PPP_CHAP, nakoutp);
1986 PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
1998 if (cishort == PPP_CHAP) {
2007 cilen != CILEN_CHAP) {
2008 LCPDEBUG((
"lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
2012 if (!ao->neg_chap) {
2014 PUTCHAR(CI_AUTHTYPE, nakoutp);
2015 PUTCHAR(CILEN_SHORT, nakoutp);
2018 PUTSHORT(PPP_EAP, nakoutp);
2023 PUTSHORT(PPP_PAP, nakoutp);
2031 if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
2037 PUTCHAR(CI_AUTHTYPE, nakoutp);
2038 PUTCHAR(CILEN_CHAP, nakoutp);
2039 PUTSHORT(PPP_CHAP, nakoutp);
2040 PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
2043 ho->chap_mdtype = CHAP_MDTYPE_D(cichar);
2049 if (cishort == PPP_EAP) {
2058 cilen != CILEN_SHORT) {
2059 LCPDEBUG((
"lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
2065 PUTCHAR(CI_AUTHTYPE, nakoutp);
2068 PUTCHAR(CILEN_CHAP, nakoutp);
2069 PUTSHORT(PPP_CHAP, nakoutp);
2070 PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
2075 PUTCHAR(CILEN_SHORT, nakoutp);
2076 PUTSHORT(PPP_PAP, nakoutp);
2094 PUTCHAR(CI_AUTHTYPE, nakoutp);
2098 PUTCHAR(CILEN_SHORT, nakoutp);
2099 PUTSHORT(PPP_EAP, nakoutp);
2104 PUTCHAR(CILEN_CHAP, nakoutp);
2105 PUTSHORT(PPP_CHAP, nakoutp);
2106 PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp);
2111 PUTCHAR(CILEN_SHORT, nakoutp);
2112 PUTSHORT(PPP_PAP, nakoutp);
2121 cilen != CILEN_LQR) {
2126 GETSHORT(cishort,
p);
2133 if (cishort != PPP_LQR) {
2135 PUTCHAR(CI_QUALITY, nakoutp);
2136 PUTCHAR(CILEN_LQR, nakoutp);
2137 PUTSHORT(PPP_LQR, nakoutp);
2138 PUTLONG(ao->lqr_period, nakoutp);
2144 case CI_MAGICNUMBER:
2145 if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
2146 cilen != CILEN_LONG) {
2155 if (go->neg_magicnumber &&
2156 cilong == go->magicnumber) {
2159 PUTCHAR(CI_MAGICNUMBER, nakoutp);
2160 PUTCHAR(CILEN_LONG, nakoutp);
2161 PUTLONG(cilong, nakoutp);
2164 ho->neg_magicnumber = 1;
2165 ho->magicnumber = cilong;
2169 case CI_PCOMPRESSION:
2170 if (!ao->neg_pcompression ||
2171 cilen != CILEN_VOID) {
2175 ho->neg_pcompression = 1;
2178 case CI_ACCOMPRESSION:
2179 if (!ao->neg_accompression ||
2180 cilen != CILEN_VOID) {
2184 ho->neg_accompression = 1;
2187#ifdef HAVE_MULTILINK
2191 || cilen != CILEN_SHORT) {
2196 GETSHORT(cishort,
p);
2205#ifdef HAVE_MULTILINK
2208 || cilen != CILEN_VOID) {
2216 if (!ao->neg_endpoint ||
2217 cilen < CILEN_CHAR ||
2218 cilen > CILEN_CHAR + MAX_ENDP_LEN) {
2223 cilen -= CILEN_CHAR;
2224 ho->neg_endpoint = 1;
2225 ho->endpoint.class_ = cichar;
2226 ho->endpoint.length = cilen;
2227 MEMCPY(ho->endpoint.value,
p, cilen);
2232 LCPDEBUG((
"lcp_reqci: rcvd unknown option %d", citype));
2238 if (orc == CONFACK &&
2242 if (orc == CONFNAK) {
2243 if (reject_if_disagree
2244 && citype != CI_MAGICNUMBER) {
2252 if (orc == CONFREJ) {
2255 MEMCPY(rejp, cip, cilen);
2256 INCPTR(cilen, rejp);
2286 LCPDEBUG((
"lcp_reqci: returning CONF%s.", CODENAME(rc)));
2294static void lcp_up(fsm *
f) {
2295 ppp_pcb *pcb =
f->pcb;
2296 lcp_options *wo = &pcb->lcp_wantoptions;
2297 lcp_options *ho = &pcb->lcp_hisoptions;
2298 lcp_options *go = &pcb->lcp_gotoptions;
2299 lcp_options *ao = &pcb->lcp_allowoptions;
2302 if (!go->neg_magicnumber)
2303 go->magicnumber = 0;
2304 if (!ho->neg_magicnumber)
2305 ho->magicnumber = 0;
2316 mtu = ho->neg_mru? ho->mru: PPP_DEFMRU;
2317 mru = go->neg_mru?
LWIP_MAX(wo->mru, go->mru): PPP_DEFMRU;
2318#ifdef HAVE_MULTILINK
2319 if (!(multilink && go->neg_mrru && ho->neg_mrru))
2322 ppp_send_config(pcb, mtu,
2323 (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
2324 ho->neg_pcompression, ho->neg_accompression);
2325 ppp_recv_config(pcb, mru,
2326 (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
2327 go->neg_pcompression, go->neg_accompression);
2330 pcb->peer_mru = ho->mru;
2332 lcp_echo_lowerup(
f->pcb);
2334 link_established(pcb);
2343static void lcp_down(fsm *
f) {
2344 ppp_pcb *pcb =
f->pcb;
2345 lcp_options *go = &pcb->lcp_gotoptions;
2347 lcp_echo_lowerdown(
f->pcb);
2351 ppp_send_config(pcb, PPP_DEFMRU, 0xffffffff, 0, 0);
2352 ppp_recv_config(pcb, PPP_DEFMRU,
2353 (go->neg_asyncmap? go->asyncmap: 0xffffffff),
2354 go->neg_pcompression, go->neg_accompression);
2355 pcb->peer_mru = PPP_DEFMRU;
2362static void lcp_starting(fsm *
f) {
2363 ppp_pcb *pcb =
f->pcb;
2371static void lcp_finished(fsm *
f) {
2372 ppp_pcb *pcb =
f->pcb;
2373 link_terminated(pcb);
2381static const char*
const lcp_codenames[] = {
2382 "ConfReq",
"ConfAck",
"ConfNak",
"ConfRej",
2383 "TermReq",
"TermAck",
"CodeRej",
"ProtRej",
2384 "EchoReq",
"EchoRep",
"DiscReq",
"Ident",
2388static int lcp_printpkt(
const u_char *
p,
int plen,
2389 void (*printer) (
void *,
const char *, ...),
void *
arg) {
2395 if (plen < HEADERLEN)
2401 if (len < HEADERLEN || len > plen)
2405 printer(
arg,
" %s", lcp_codenames[
code-1]);
2407 printer(
arg,
" code=0x%x",
code);
2408 printer(
arg,
" id=0x%x",
id);
2420 if (olen < 2 || olen >
len) {
2428 if (olen == CILEN_SHORT) {
2430 GETSHORT(cishort,
p);
2431 printer(
arg,
"mru %d", cishort);
2435 if (olen == CILEN_LONG) {
2438 printer(
arg,
"asyncmap 0x%x", cilong);
2442 if (olen >= CILEN_SHORT) {
2444 printer(
arg,
"auth ");
2445 GETSHORT(cishort,
p);
2449 printer(
arg,
"pap");
2454 printer(
arg,
"chap");
2458 printer(
arg,
" MD5");
2462 case CHAP_MICROSOFT:
2463 printer(
arg,
" MS");
2467 case CHAP_MICROSOFT_V2:
2468 printer(
arg,
" MS-v2");
2480 printer(
arg,
"eap");
2484 printer(
arg,
"0x%x", cishort);
2490 if (olen >= CILEN_SHORT) {
2492 printer(
arg,
"quality ");
2493 GETSHORT(cishort,
p);
2496 printer(
arg,
"lqr");
2499 printer(
arg,
"0x%x", cishort);
2505 if (olen >= CILEN_CHAR) {
2507 printer(
arg,
"callback ");
2508 GETCHAR(cishort,
p);
2511 printer(
arg,
"CBCP");
2514 printer(
arg,
"0x%x", cishort);
2518 case CI_MAGICNUMBER:
2519 if (olen == CILEN_LONG) {
2522 printer(
arg,
"magic 0x%x", cilong);
2525 case CI_PCOMPRESSION:
2526 if (olen == CILEN_VOID) {
2528 printer(
arg,
"pcomp");
2531 case CI_ACCOMPRESSION:
2532 if (olen == CILEN_VOID) {
2534 printer(
arg,
"accomp");
2538 if (olen == CILEN_SHORT) {
2540 GETSHORT(cishort,
p);
2541 printer(
arg,
"mrru %d", cishort);
2545 if (olen == CILEN_VOID) {
2547 printer(
arg,
"ssnhf");
2551#ifdef HAVE_MULTILINK
2552 if (olen >= CILEN_CHAR) {
2555 GETCHAR(epd.class,
p);
2556 epd.length = olen - CILEN_CHAR;
2557 if (epd.length > MAX_ENDP_LEN)
2558 epd.length = MAX_ENDP_LEN;
2559 if (epd.length > 0) {
2560 MEMCPY(epd.value,
p, epd.length);
2563 printer(
arg,
"endpoint [%s]", epdisc_to_str(&epd));
2566 printer(
arg,
"endpoint");
2582 if (
len > 0 && *
p >=
' ' && *
p < 0x7f) {
2584 ppp_print_string(
p,
len, printer,
arg);
2595 printer(
arg,
" magic=0x%x", cilong);
2604 printer(
arg,
" magic=0x%x", cilong);
2607 if (
code == TIMEREM) {
2611 printer(
arg,
" seconds=%u", cilong);
2616 ppp_print_string(
p,
len, printer,
arg);
2626 for (
i = 0;
i <
len &&
i < 32; ++
i) {
2631 printer(
arg,
" ...");
2643static void LcpLinkFailure(fsm *
f) {
2644 ppp_pcb *pcb =
f->pcb;
2645 if (
f->state == PPP_FSM_OPENED) {
2646 ppp_info((
"No response to %d echo-requests", pcb->lcp_echos_pending));
2647 ppp_notice((
"Serial link appears to be disconnected."));
2648 pcb->err_code = PPPERR_PEERDEAD;
2649 lcp_close(pcb,
"Peer not responding");
2657static void LcpEchoCheck(fsm *
f) {
2658 ppp_pcb *pcb =
f->pcb;
2660 LcpSendEchoRequest (
f);
2661 if (
f->state != PPP_FSM_OPENED)
2667 if (pcb->lcp_echo_timer_running)
2668 ppp_warn((
"assertion lcp_echo_timer_running==0 failed"));
2669 TIMEOUT (LcpEchoTimeout,
f, pcb->settings.lcp_echo_interval);
2670 pcb->lcp_echo_timer_running = 1;
2677static void LcpEchoTimeout(
void *
arg) {
2679 ppp_pcb *pcb =
f->pcb;
2680 if (pcb->lcp_echo_timer_running != 0) {
2681 pcb->lcp_echo_timer_running = 0;
2682 LcpEchoCheck ((fsm *)
arg);
2690static void lcp_received_echo_reply(fsm *
f,
int id,
u_char *inp,
int len) {
2691 ppp_pcb *pcb =
f->pcb;
2692 lcp_options *go = &pcb->lcp_gotoptions;
2698 ppp_dbglog((
"lcp: received short Echo-Reply, length %d",
len));
2701 GETLONG(magic_val, inp);
2702 if (go->neg_magicnumber
2703 && magic_val == go->magicnumber) {
2704 ppp_warn((
"appear to have received our own echo-reply!"));
2709 pcb->lcp_echos_pending = 0;
2716static void LcpSendEchoRequest(fsm *
f) {
2717 ppp_pcb *pcb =
f->pcb;
2718 lcp_options *go = &pcb->lcp_gotoptions;
2725 if (pcb->settings.lcp_echo_fails != 0) {
2726 if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) {
2728 pcb->lcp_echos_pending = 0;
2737 if (pcb->settings.lcp_echo_adaptive) {
2738 static unsigned int last_pkts_in = 0;
2740#if PPP_STATS_SUPPORT
2741 update_link_stats(
f->unit);
2742 link_stats_valid = 0;
2745 if (link_stats.pkts_in != last_pkts_in) {
2746 last_pkts_in = link_stats.pkts_in;
2755 if (
f->state == PPP_FSM_OPENED) {
2756 lcp_magic = go->magicnumber;
2758 PUTLONG(lcp_magic, pktp);
2759 fsm_sdata(
f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt);
2760 ++pcb->lcp_echos_pending;
2768static void lcp_echo_lowerup(ppp_pcb *pcb) {
2769 fsm *
f = &pcb->lcp_fsm;
2772 pcb->lcp_echos_pending = 0;
2773 pcb->lcp_echo_number = 0;
2774 pcb->lcp_echo_timer_running = 0;
2777 if (pcb->settings.lcp_echo_interval != 0)
2785static void lcp_echo_lowerdown(ppp_pcb *pcb) {
2786 fsm *
f = &pcb->lcp_fsm;
2788 if (pcb->lcp_echo_timer_running != 0) {
2789 UNTIMEOUT (LcpEchoTimeout,
f);
2790 pcb->lcp_echo_timer_running = 0;
struct protocol * protocols
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define LWIP_ARRAYSIZE(x)
static WCHAR no[MAX_STRING_RESOURCE_LEN]
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
#define MEMCPY(DST, SRC, BYTES)
const char * optend(char *fmt) const
static unsigned __int64 next