53 #include "netif/ppp/ppp_opts.h" 54 #if PPP_SUPPORT && PPPOS_SUPPORT 69 #include "netif/ppp/ppp_impl.h" 71 #include "netif/ppp/vj.h" 77 static
err_t pppos_write(ppp_pcb *ppp,
void *ctx, struct
pbuf *p);
78 static
err_t pppos_netif_output(ppp_pcb *ppp,
void *ctx, struct
pbuf *pb, u16_t protocol);
79 static
void pppos_connect(ppp_pcb *ppp,
void *ctx);
81 static void pppos_listen(ppp_pcb *ppp,
void *ctx);
83 static void pppos_disconnect(ppp_pcb *ppp,
void *ctx);
84 static err_t pppos_destroy(ppp_pcb *ppp,
void *ctx);
85 static void pppos_send_config(ppp_pcb *ppp,
void *ctx, u32_t accm,
int pcomp,
int accomp);
86 static void pppos_recv_config(ppp_pcb *ppp,
void *ctx, u32_t accm,
int pcomp,
int accomp);
89 #if PPP_INPROC_IRQ_SAFE 90 static void pppos_input_callback(
void *arg);
92 static void pppos_input_free_current_packet(pppos_pcb *pppos);
93 static void pppos_input_drop(pppos_pcb *pppos);
94 static err_t pppos_output_append(pppos_pcb *pppos,
err_t err,
struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs);
95 static err_t pppos_output_last(pppos_pcb *pppos,
err_t err,
struct pbuf *nb, u16_t *fcs);
98 static const struct link_callbacks pppos_callbacks = {
113 #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & 1 << (c & 0x07)) 119 static const u16_t fcstab[256] = {
120 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
121 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
122 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
123 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
124 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
125 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
126 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
127 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
128 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
129 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
130 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
131 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
132 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
133 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
134 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
135 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
136 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
137 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
138 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
139 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
140 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
141 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
142 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
143 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
144 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
145 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
146 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
147 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
148 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
149 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
150 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
151 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
153 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 156 #define PPP_FCS_POLYNOMIAL 0x8408 158 ppp_get_fcs(u8_t byte)
163 for (bit = 8; bit-- > 0; ) {
164 octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1);
166 return octet & 0xffff;
168 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) 174 #define PPP_INITFCS 0xffff 175 #define PPP_GOODFCS 0xf0b8 177 #if PPP_INPROC_IRQ_SAFE 178 #define PPPOS_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) 179 #define PPPOS_PROTECT(lev) SYS_ARCH_PROTECT(lev) 180 #define PPPOS_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) 182 #define PPPOS_DECL_PROTECT(lev) 183 #define PPPOS_PROTECT(lev) 184 #define PPPOS_UNPROTECT(lev) 193 ppp_pcb *pppos_create(
struct netif *pppif, pppos_output_cb_fn output_cb,
194 ppp_link_status_cb_fn link_status_cb,
void *ctx_cb)
204 ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb);
210 memset(pppos, 0,
sizeof(pppos_pcb));
212 pppos->output_cb = output_cb;
218 pppos_write(ppp_pcb *ppp,
void *ctx,
struct pbuf *p)
220 pppos_pcb *pppos = (pppos_pcb *)ctx;
231 PPPDEBUG(LOG_WARNING, (
"pppos_write[%d]: alloc fail\n", ppp->netif->num));
232 LINK_STATS_INC(link.memerr);
233 LINK_STATS_INC(link.drop);
234 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
242 if ((
sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
243 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL);
247 fcs_out = PPP_INITFCS;
251 err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out);
254 err = pppos_output_last(pppos, err, nb, &fcs_out);
256 PPPDEBUG(LOG_INFO, (
"pppos_write[%d]: len=%d\n", ppp->netif->num, p->
len));
258 PPPDEBUG(LOG_WARNING, (
"pppos_write[%d]: output failed len=%d\n", ppp->netif->num, p->
len));
266 pppos_netif_output(ppp_pcb *ppp,
void *ctx,
struct pbuf *pb, u16_t protocol)
268 pppos_pcb *pppos = (pppos_pcb *)ctx;
277 PPPDEBUG(LOG_WARNING, (
"pppos_netif_output[%d]: alloc fail\n", ppp->netif->num));
278 LINK_STATS_INC(link.memerr);
279 LINK_STATS_INC(link.drop);
280 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
287 if ((
sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
288 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL);
291 fcs_out = PPP_INITFCS;
292 if (!pppos->accomp) {
293 err = pppos_output_append(pppos, err, nb, PPP_ALLSTATIONS, 1, &fcs_out);
294 err = pppos_output_append(pppos, err, nb, PPP_UI, 1, &fcs_out);
296 if (!pppos->pcomp || protocol > 0xFF) {
297 err = pppos_output_append(pppos, err, nb, (protocol >> 8) & 0xFF, 1, &fcs_out);
299 err = pppos_output_append(pppos, err, nb, protocol & 0xFF, 1, &fcs_out);
302 for(p = pb; p; p = p->
next) {
307 err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out);
311 err = pppos_output_last(pppos, err, nb, &fcs_out);
313 PPPDEBUG(LOG_INFO, (
"pppos_netif_output[%d]: proto=0x%"X16_F
", len = %d\n", ppp->netif->num, protocol, pb->
tot_len));
315 PPPDEBUG(LOG_WARNING, (
"pppos_netif_output[%d]: output failed proto=0x%"X16_F
", len = %d\n", ppp->netif->num, protocol, pb->
tot_len));
321 pppos_connect(ppp_pcb *ppp,
void *ctx)
323 pppos_pcb *pppos = (pppos_pcb *)ctx;
324 PPPOS_DECL_PROTECT(lev);
326 #if PPP_INPROC_IRQ_SAFE 328 pppos_input_free_current_packet(pppos);
332 memset(&pppos->last_xmit, 0,
sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit));
338 pppos->in_accm[15] = 0x60;
339 pppos->out_accm[15] = 0x60;
342 PPPOS_UNPROTECT(lev);
347 PPPDEBUG(LOG_INFO, (
"pppos_connect: unit %d: connecting\n", ppp->netif->num));
353 pppos_listen(ppp_pcb *ppp,
void *ctx)
355 pppos_pcb *pppos = (pppos_pcb *)ctx;
356 PPPOS_DECL_PROTECT(lev);
358 #if PPP_INPROC_IRQ_SAFE 360 pppos_input_free_current_packet(pppos);
364 memset(&pppos->last_xmit, 0,
sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit));
370 pppos->in_accm[15] = 0x60;
371 pppos->out_accm[15] = 0x60;
374 PPPOS_UNPROTECT(lev);
379 PPPDEBUG(LOG_INFO, (
"pppos_listen: unit %d: listening\n", ppp->netif->num));
385 pppos_disconnect(ppp_pcb *ppp,
void *ctx)
387 pppos_pcb *pppos = (pppos_pcb *)ctx;
388 PPPOS_DECL_PROTECT(lev);
392 PPPOS_UNPROTECT(lev);
398 #if !PPP_INPROC_IRQ_SAFE 400 pppos_input_free_current_packet(pppos);
407 pppos_destroy(ppp_pcb *ppp,
void *ctx)
409 pppos_pcb *pppos = (pppos_pcb *)ctx;
412 #if PPP_INPROC_IRQ_SAFE 414 pppos_input_free_current_packet(pppos);
421 #if !NO_SYS && !PPP_INPROC_IRQ_SAFE 429 pppos_input_tcpip(ppp_pcb *ppp, u8_t *s,
int l)
440 err =
tcpip_inpkt(p, ppp_netif(ppp), pppos_input_sys);
449 ppp_pcb *ppp = (ppp_pcb*)inp->
state;
452 for (n = p; n; n = n->
next) {
453 pppos_input(ppp, (u8_t*)n->payload, n->len);
462 #if PPP_INPROC_IRQ_SAFE 463 #ifdef PACK_STRUCT_USE_INCLUDES 464 # include "arch/bpstruct.h" 467 struct pppos_input_header {
469 } PACK_STRUCT_STRUCT;
471 #ifdef PACK_STRUCT_USE_INCLUDES 472 # include "arch/epstruct.h" 483 pppos_input(ppp_pcb *ppp, u8_t *s,
int l)
485 pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb;
486 struct pbuf *next_pbuf;
489 PPPOS_DECL_PROTECT(lev);
491 PPPDEBUG(LOG_DEBUG, (
"pppos_input[%d]: got %d bytes\n", ppp->netif->num, l));
502 PPPOS_UNPROTECT(lev);
505 escaped = ESCAPE_P(pppos->in_accm, cur_char);
506 PPPOS_UNPROTECT(lev);
514 if (cur_char == PPP_ESCAPE) {
515 pppos->in_escaped = 1;
517 }
else if (cur_char == PPP_FLAG) {
519 if (pppos->in_state <= PDADDRESS) {
522 }
else if (pppos->in_state < PDDATA) {
523 PPPDEBUG(LOG_WARNING,
524 (
"pppos_input[%d]: Dropping incomplete packet %d\n",
525 ppp->netif->num, pppos->in_state));
526 LINK_STATS_INC(link.lenerr);
527 pppos_input_drop(pppos);
529 }
else if (pppos->in_fcs != PPP_GOODFCS) {
531 (
"pppos_input[%d]: Dropping bad fcs 0x%"X16_F
" proto=0x%"X16_F
"\n",
532 ppp->netif->num, pppos->in_fcs, pppos->in_protocol));
534 LINK_STATS_INC(link.chkerr);
535 pppos_input_drop(pppos);
540 if(pppos->in_tail->len > 2) {
541 pppos->in_tail->len -= 2;
543 pppos->in_tail->tot_len = pppos->in_tail->len;
544 if (pppos->in_tail != pppos->in_head) {
545 pbuf_cat(pppos->in_head, pppos->in_tail);
548 pppos->in_tail->tot_len = pppos->in_tail->len;
549 if (pppos->in_tail != pppos->in_head) {
550 pbuf_cat(pppos->in_head, pppos->in_tail);
553 pbuf_realloc(pppos->in_head, pppos->in_head->tot_len - 2);
557 inp = pppos->in_head;
559 pppos->in_head = NULL;
560 pppos->in_tail = NULL;
561 #if IP_FORWARD || LWIP_IPV6_FORWARD 565 #if PPP_INPROC_IRQ_SAFE 567 PPPDEBUG(LOG_ERR, (
"pppos_input[%d]: tcpip_callback() failed, dropping packet\n", ppp->netif->num));
569 LINK_STATS_INC(link.drop);
570 MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards);
578 pppos->in_fcs = PPP_INITFCS;
579 pppos->in_state = PDADDRESS;
580 pppos->in_escaped = 0;
584 PPPDEBUG(LOG_WARNING,
585 (
"pppos_input[%d]: Dropping ACCM char <%d>\n", ppp->netif->num, cur_char));
590 if (pppos->in_escaped) {
591 pppos->in_escaped = 0;
592 cur_char ^= PPP_TRANS;
596 switch(pppos->in_state) {
600 if (cur_char != PPP_ALLSTATIONS) {
608 pppos->in_fcs = PPP_INITFCS;
613 if (cur_char == PPP_ALLSTATIONS) {
614 pppos->in_state = PDCONTROL;
623 if (cur_char == PPP_UI) {
624 pppos->in_state = PDPROTOCOL1;
631 PPPDEBUG(LOG_WARNING,
632 (
"pppos_input[%d]: Invalid control <%d>\n", ppp->netif->num, cur_char));
633 pppos->in_state = PDSTART;
640 pppos->in_protocol = cur_char;
641 pppos->in_state = PDDATA;
643 pppos->in_protocol = (u16_t)cur_char << 8;
644 pppos->in_state = PDPROTOCOL2;
648 pppos->in_protocol |= cur_char;
649 pppos->in_state = PDDATA;
654 u16_t pbuf_alloc_len;
655 if (pppos->in_tail != NULL) {
656 pppos->in_tail->tot_len = pppos->in_tail->len;
657 if (pppos->in_tail != pppos->in_head) {
658 pbuf_cat(pppos->in_head, pppos->in_tail);
660 pppos->in_tail = NULL;
665 #if IP_FORWARD || LWIP_IPV6_FORWARD 670 if (pppos->in_head == NULL) {
675 if (next_pbuf == NULL) {
679 PPPDEBUG(LOG_ERR, (
"pppos_input[%d]: NO FREE PBUFS!\n", ppp->netif->num));
680 LINK_STATS_INC(link.memerr);
681 pppos_input_drop(pppos);
682 pppos->in_state = PDSTART;
685 if (pppos->in_head == NULL) {
686 u8_t *
payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len;
687 #if PPP_INPROC_IRQ_SAFE 688 ((
struct pppos_input_header*)payload)->ppp = ppp;
689 payload +=
sizeof(
struct pppos_input_header);
690 next_pbuf->len +=
sizeof(
struct pppos_input_header);
692 next_pbuf->len +=
sizeof(pppos->in_protocol);
693 *(payload++) = pppos->in_protocol >> 8;
694 *(payload) = pppos->in_protocol & 0xFF;
695 pppos->in_head = next_pbuf;
697 pppos->in_tail = next_pbuf;
700 ((u8_t*)pppos->in_tail->payload)[pppos->in_tail->len++] = cur_char;
707 pppos->in_fcs = PPP_FCS(pppos->in_fcs, cur_char);
712 #if PPP_INPROC_IRQ_SAFE 715 static void pppos_input_callback(
void *arg) {
716 struct pbuf *pb = (
struct pbuf*)arg;
719 ppp = ((
struct pppos_input_header*)pb->
payload)->ppp;
720 if(
pbuf_header(pb, -(s16_t)
sizeof(
struct pppos_input_header))) {
721 LWIP_ASSERT(
"pbuf_header failed\n", 0);
730 LINK_STATS_INC(link.drop);
731 MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards);
737 pppos_send_config(ppp_pcb *ppp,
void *ctx, u32_t accm,
int pcomp,
int accomp)
740 pppos_pcb *pppos = (pppos_pcb *)ctx;
743 pppos->pcomp = pcomp;
744 pppos->accomp = accomp;
747 for (i = 0; i < 32/8; i++) {
748 pppos->out_accm[i] = (u8_t)((accm >> (8 * i)) & 0xFF);
751 PPPDEBUG(LOG_INFO, (
"pppos_send_config[%d]: out_accm=%X %X %X %X\n",
752 pppos->ppp->netif->num,
753 pppos->out_accm[0], pppos->out_accm[1], pppos->out_accm[2], pppos->out_accm[3]));
757 pppos_recv_config(ppp_pcb *ppp,
void *ctx, u32_t accm,
int pcomp,
int accomp)
760 pppos_pcb *pppos = (pppos_pcb *)ctx;
761 PPPOS_DECL_PROTECT(lev);
768 for (i = 0; i < 32 / 8; i++) {
769 pppos->in_accm[i] = (u8_t)(accm >> (i * 8));
771 PPPOS_UNPROTECT(lev);
773 PPPDEBUG(LOG_INFO, (
"pppos_recv_config[%d]: in_accm=%X %X %X %X\n",
774 pppos->ppp->netif->num,
775 pppos->in_accm[0], pppos->in_accm[1], pppos->in_accm[2], pppos->in_accm[3]));
782 pppos_input_free_current_packet(pppos_pcb *pppos)
784 if (pppos->in_head != NULL) {
785 if (pppos->in_tail && (pppos->in_tail != pppos->in_head)) {
789 pppos->in_head = NULL;
791 pppos->in_tail = NULL;
798 pppos_input_drop(pppos_pcb *pppos)
800 if (pppos->in_head != NULL) {
802 PPPDEBUG(LOG_INFO, (
"pppos_input_drop: %d:%.*H\n", pppos->in_head->len, min(60, pppos->in_head->len * 2), pppos->in_head->payload));
804 PPPDEBUG(LOG_INFO, (
"pppos_input_drop: pbuf len=%d, addr %p\n", pppos->in_head->len, (
void*)pppos->in_head));
806 pppos_input_free_current_packet(pppos);
808 vj_uncompress_err(&pppos->ppp->vj_comp);
811 LINK_STATS_INC(link.drop);
812 MIB2_STATS_NETIF_INC(pppos->ppp->netif, ifindiscards);
822 pppos_output_append(pppos_pcb *pppos,
err_t err,
struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs)
832 u32_t l = pppos->output_cb(pppos->ppp, (u8_t*)nb->
payload, nb->
len, pppos->ppp->ctx_cb);
841 *fcs = PPP_FCS(*fcs, c);
845 if (accm && ESCAPE_P(pppos->out_accm, c)) {
846 *((u8_t*)nb->
payload + nb->
len++) = PPP_ESCAPE;
847 *((u8_t*)nb->
payload + nb->
len++) = c ^ PPP_TRANS;
856 pppos_output_last(pppos_pcb *pppos,
err_t err,
struct pbuf *nb, u16_t *fcs)
858 ppp_pcb *ppp = pppos->ppp;
861 err = pppos_output_append(pppos, err, nb, ~(*fcs) & 0xFF, 1, NULL);
862 err = pppos_output_append(pppos, err, nb, (~(*fcs) >> 8) & 0xFF, 1, NULL);
863 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL);
871 u32_t l = pppos->output_cb(ppp, (u8_t*)nb->
payload, nb->
len, ppp->ctx_cb);
879 MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, nb->
tot_len);
880 MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts);
881 LINK_STATS_INC(link.xmit);
886 pppos->last_xmit = 0;
887 LINK_STATS_INC(link.err);
888 LINK_STATS_INC(link.drop);
889 MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards);
void pbuf_realloc(struct pbuf *p, u16_t new_len)
#define LWIP_MEMPOOL_ALLOC(name)
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
#define PACK_STRUCT_BEGIN
#define LWIP_MEMPOOL_FREE(name, x)
#define LWIP_MEMPOOL_DECLARE(name, num, size, desc)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
#define PACK_STRUCT_FIELD(x)
#define PBUF_POOL_BUFSIZE
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
#define LWIP_UNUSED_ARG(x)
u8_t pbuf_free(struct pbuf *p)
#define PBUF_LINK_ENCAPSULATION_HLEN