35 #if PPP_SUPPORT && PPPOS_SUPPORT 54 static err_t pppos_write(ppp_pcb *ppp,
void *ctx,
struct pbuf *p);
55 static err_t pppos_netif_output(ppp_pcb *ppp,
void *ctx,
struct pbuf *pb,
u16_t protocol);
56 static err_t pppos_connect(ppp_pcb *ppp,
void *ctx);
58 static err_t pppos_listen(ppp_pcb *ppp,
void *ctx,
struct ppp_addrs *addrs);
60 static void pppos_disconnect(ppp_pcb *ppp,
void *ctx);
61 static err_t pppos_destroy(ppp_pcb *ppp,
void *ctx);
62 static void pppos_send_config(ppp_pcb *ppp,
void *ctx,
u32_t accm,
int pcomp,
int accomp);
63 static void pppos_recv_config(ppp_pcb *ppp,
void *ctx,
u32_t accm,
int pcomp,
int accomp);
66 #if PPP_INPROC_IRQ_SAFE 67 static void pppos_input_callback(
void *arg);
69 static void pppos_input_free_current_packet(pppos_pcb *pppos);
70 static void pppos_input_drop(pppos_pcb *pppos);
75 static const struct link_callbacks pppos_callbacks = {
90 #define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & 1 << (c & 0x07)) 96 static const u16_t fcstab[256] = {
97 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
98 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
99 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
100 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
101 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
102 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
103 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
104 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
105 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
106 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
107 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
108 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
109 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
110 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
111 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
112 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
113 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
114 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
115 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
116 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
117 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
118 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
119 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
120 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
121 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
122 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
123 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
124 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
125 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
126 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
127 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
128 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
130 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 133 #define PPP_FCS_POLYNOMIAL 0x8408 135 ppp_get_fcs(
u8_t byte)
140 for (bit = 8; bit-- > 0; ) {
141 octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1);
143 return octet & 0xffff;
145 #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) 151 #define PPP_INITFCS 0xffff 152 #define PPP_GOODFCS 0xf0b8 154 #if PPP_INPROC_IRQ_SAFE 155 #define PPPOS_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) 156 #define PPPOS_PROTECT(lev) SYS_ARCH_PROTECT(lev) 157 #define PPPOS_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) 159 #define PPPOS_DECL_PROTECT(lev) 160 #define PPPOS_PROTECT(lev) 161 #define PPPOS_UNPROTECT(lev) 170 ppp_pcb *pppos_create(
struct netif *pppif, pppos_output_cb_fn output_cb,
171 ppp_link_status_cb_fn link_status_cb,
void *ctx_cb)
181 ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb);
187 memset(pppos, 0,
sizeof(pppos_pcb));
189 pppos->output_cb = output_cb;
195 pppos_write(ppp_pcb *ppp,
void *ctx,
struct pbuf *p)
197 pppos_pcb *pppos = (pppos_pcb *)ctx;
208 PPPDEBUG(LOG_WARNING, (
"pppos_write[%d]: alloc fail\n", ppp->netif->num));
219 if ((
sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
220 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0,
NULL);
224 fcs_out = PPP_INITFCS;
228 err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out);
231 err = pppos_output_last(pppos, err, nb, &fcs_out);
233 PPPDEBUG(LOG_INFO, (
"pppos_write[%d]: len=%d\n", ppp->netif->num, p->
len));
235 PPPDEBUG(LOG_WARNING, (
"pppos_write[%d]: output failed len=%d\n", ppp->netif->num, p->
len));
243 pppos_netif_output(ppp_pcb *ppp,
void *ctx,
struct pbuf *pb,
u16_t protocol)
245 pppos_pcb *pppos = (pppos_pcb *)ctx;
254 PPPDEBUG(LOG_WARNING, (
"pppos_netif_output[%d]: alloc fail\n", ppp->netif->num));
264 if ((
sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) {
265 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0,
NULL);
268 fcs_out = PPP_INITFCS;
269 if (!pppos->accomp) {
270 err = pppos_output_append(pppos, err, nb, PPP_ALLSTATIONS, 1, &fcs_out);
271 err = pppos_output_append(pppos, err, nb, PPP_UI, 1, &fcs_out);
273 if (!pppos->pcomp || protocol > 0xFF) {
274 err = pppos_output_append(pppos, err, nb, (protocol >> 8) & 0xFF, 1, &fcs_out);
276 err = pppos_output_append(pppos, err, nb, protocol & 0xFF, 1, &fcs_out);
279 for(p = pb; p; p = p->
next) {
284 err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out);
288 err = pppos_output_last(pppos, err, nb, &fcs_out);
290 PPPDEBUG(LOG_INFO, (
"pppos_netif_output[%d]: proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->
tot_len));
292 PPPDEBUG(LOG_WARNING, (
"pppos_netif_output[%d]: output failed proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->
tot_len));
298 pppos_connect(ppp_pcb *ppp,
void *ctx)
300 pppos_pcb *pppos = (pppos_pcb *)ctx;
301 PPPOS_DECL_PROTECT(lev);
303 #if PPP_INPROC_IRQ_SAFE 305 pppos_input_free_current_packet(pppos);
310 memset(&pppos->last_xmit, 0,
sizeof(pppos_pcb) - ( (
char*)&((pppos_pcb*)0)->last_xmit - (
char*)0 ) );
316 pppos->in_accm[15] = 0x60;
317 pppos->out_accm[15] = 0x60;
320 PPPOS_UNPROTECT(lev);
325 PPPDEBUG(LOG_INFO, (
"pppos_connect: unit %d: connecting\n", ppp->netif->num));
332 pppos_listen(ppp_pcb *ppp,
void *ctx,
struct ppp_addrs *addrs)
334 pppos_pcb *pppos = (pppos_pcb *)ctx;
336 ipcp_options *ipcp_wo;
339 PPPOS_DECL_PROTECT(lev);
341 #if PPP_INPROC_IRQ_SAFE 343 pppos_input_free_current_packet(pppos);
348 memset(&pppos->last_xmit, 0,
sizeof(pppos_pcb) - ( (
char*)&((pppos_pcb*)0)->last_xmit - (
char*)0 ) );
351 lcp_wo = &ppp->lcp_wantoptions;
355 if (ppp->settings.user && ppp->settings.passwd) {
356 ppp->settings.auth_required = 1;
361 ipcp_wo = &ppp->ipcp_wantoptions;
362 ipcp_wo->ouraddr = ip4_addr_get_u32(&addrs->our_ipaddr);
363 ipcp_wo->hisaddr = ip4_addr_get_u32(&addrs->his_ipaddr);
365 ipcp_wo->dnsaddr[0] = ip4_addr_get_u32(&addrs->dns1);
366 ipcp_wo->dnsaddr[1] = ip4_addr_get_u32(&addrs->dns2);
376 pppos->in_accm[15] = 0x60;
377 pppos->out_accm[15] = 0x60;
380 PPPOS_UNPROTECT(lev);
385 PPPDEBUG(LOG_INFO, (
"pppos_listen: unit %d: listening\n", ppp->netif->num));
392 pppos_disconnect(ppp_pcb *ppp,
void *ctx)
394 pppos_pcb *pppos = (pppos_pcb *)ctx;
395 PPPOS_DECL_PROTECT(lev);
399 PPPOS_UNPROTECT(lev);
405 #if !PPP_INPROC_IRQ_SAFE 407 pppos_input_free_current_packet(pppos);
414 pppos_destroy(ppp_pcb *ppp,
void *ctx)
416 pppos_pcb *pppos = (pppos_pcb *)ctx;
419 #if PPP_INPROC_IRQ_SAFE 421 pppos_input_free_current_packet(pppos);
428 #if !NO_SYS && !PPP_INPROC_IRQ_SAFE 436 pppos_input_tcpip(ppp_pcb *ppp,
u8_t *s,
int l)
447 err = tcpip_pppos_input(p, ppp_netif(ppp));
456 ppp_pcb *ppp = (ppp_pcb*)inp->
state;
459 for (n = p; n; n = n->
next) {
460 pppos_input(ppp, (
u8_t*)n->payload, n->len);
469 #if PPP_INPROC_IRQ_SAFE 470 #ifdef PACK_STRUCT_USE_INCLUDES 474 struct pppos_input_header {
478 #ifdef PACK_STRUCT_USE_INCLUDES 490 pppos_input(ppp_pcb *ppp,
u8_t *s,
int l)
492 pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb;
493 struct pbuf *next_pbuf;
496 PPPOS_DECL_PROTECT(lev);
500 PPPOS_UNPROTECT(lev);
503 PPPOS_UNPROTECT(lev);
505 PPPDEBUG(LOG_DEBUG, (
"pppos_input[%d]: got %d bytes\n", ppp->netif->num, l));
510 escaped = ESCAPE_P(pppos->in_accm, cur_char);
511 PPPOS_UNPROTECT(lev);
519 if (cur_char == PPP_ESCAPE) {
520 pppos->in_escaped = 1;
522 }
else if (cur_char == PPP_FLAG) {
524 if (pppos->in_state <= PDADDRESS) {
527 }
else if (pppos->in_state < PDDATA) {
528 PPPDEBUG(LOG_WARNING,
529 (
"pppos_input[%d]: Dropping incomplete packet %d\n",
530 ppp->netif->num, pppos->in_state));
532 pppos_input_drop(pppos);
534 }
else if (pppos->in_fcs != PPP_GOODFCS) {
536 (
"pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n",
537 ppp->netif->num, pppos->in_fcs, pppos->in_protocol));
540 pppos_input_drop(pppos);
545 if(pppos->in_tail->len > 2) {
546 pppos->in_tail->len -= 2;
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 pppos->in_tail->tot_len = pppos->in_tail->len;
554 if (pppos->in_tail != pppos->in_head) {
555 pbuf_cat(pppos->in_head, pppos->in_tail);
558 pbuf_realloc(pppos->in_head, pppos->in_head->tot_len - 2);
562 inp = pppos->in_head;
564 pppos->in_head =
NULL;
565 pppos->in_tail =
NULL;
566 #if IP_FORWARD || LWIP_IPV6_FORWARD 570 #if PPP_INPROC_IRQ_SAFE 572 PPPDEBUG(LOG_ERR, (
"pppos_input[%d]: tcpip_callback() failed, dropping packet\n", ppp->netif->num));
583 pppos->in_fcs = PPP_INITFCS;
584 pppos->in_state = PDADDRESS;
585 pppos->in_escaped = 0;
589 PPPDEBUG(LOG_WARNING,
590 (
"pppos_input[%d]: Dropping ACCM char <%d>\n", ppp->netif->num, cur_char));
595 if (pppos->in_escaped) {
596 pppos->in_escaped = 0;
597 cur_char ^= PPP_TRANS;
601 switch(pppos->in_state) {
605 if (cur_char != PPP_ALLSTATIONS) {
613 pppos->in_fcs = PPP_INITFCS;
618 if (cur_char == PPP_ALLSTATIONS) {
619 pppos->in_state = PDCONTROL;
628 if (cur_char == PPP_UI) {
629 pppos->in_state = PDPROTOCOL1;
636 PPPDEBUG(LOG_WARNING,
637 (
"pppos_input[%d]: Invalid control <%d>\n", ppp->netif->num, cur_char));
638 pppos->in_state = PDSTART;
645 pppos->in_protocol = cur_char;
646 pppos->in_state = PDDATA;
648 pppos->in_protocol = (
u16_t)cur_char << 8;
649 pppos->in_state = PDPROTOCOL2;
653 pppos->in_protocol |= cur_char;
654 pppos->in_state = PDDATA;
659 u16_t pbuf_alloc_len;
660 if (pppos->in_tail !=
NULL) {
661 pppos->in_tail->tot_len = pppos->in_tail->len;
662 if (pppos->in_tail != pppos->in_head) {
663 pbuf_cat(pppos->in_head, pppos->in_tail);
665 pppos->in_tail =
NULL;
670 #if IP_FORWARD || LWIP_IPV6_FORWARD 675 if (pppos->in_head ==
NULL) {
680 if (next_pbuf ==
NULL) {
684 PPPDEBUG(LOG_ERR, (
"pppos_input[%d]: NO FREE PBUFS!\n", ppp->netif->num));
686 pppos_input_drop(pppos);
687 pppos->in_state = PDSTART;
690 if (pppos->in_head ==
NULL) {
692 #if PPP_INPROC_IRQ_SAFE 693 ((
struct pppos_input_header*)payload)->ppp = ppp;
694 payload +=
sizeof(
struct pppos_input_header);
695 next_pbuf->len +=
sizeof(
struct pppos_input_header);
697 next_pbuf->len +=
sizeof(pppos->in_protocol);
698 *(payload++) = pppos->in_protocol >> 8;
699 *(payload) = pppos->in_protocol & 0xFF;
700 pppos->in_head = next_pbuf;
702 pppos->in_tail = next_pbuf;
705 ((
u8_t*)pppos->in_tail->payload)[pppos->in_tail->len++] = cur_char;
712 pppos->in_fcs = PPP_FCS(pppos->in_fcs, cur_char);
717 #if PPP_INPROC_IRQ_SAFE 720 static void pppos_input_callback(
void *arg) {
721 struct pbuf *pb = (
struct pbuf*)arg;
724 ppp = ((
struct pppos_input_header*)pb->
payload)->ppp;
742 pppos_send_config(ppp_pcb *ppp,
void *ctx,
u32_t accm,
int pcomp,
int accomp)
745 pppos_pcb *pppos = (pppos_pcb *)ctx;
748 pppos->pcomp = pcomp;
749 pppos->accomp = accomp;
752 for (i = 0; i < 32/8; i++) {
753 pppos->out_accm[i] = (
u8_t)((accm >> (8 * i)) & 0xFF);
756 PPPDEBUG(LOG_INFO, (
"pppos_send_config[%d]: out_accm=%X %X %X %X\n",
757 pppos->ppp->netif->num,
758 pppos->out_accm[0], pppos->out_accm[1], pppos->out_accm[2], pppos->out_accm[3]));
762 pppos_recv_config(ppp_pcb *ppp,
void *ctx,
u32_t accm,
int pcomp,
int accomp)
765 pppos_pcb *pppos = (pppos_pcb *)ctx;
766 PPPOS_DECL_PROTECT(lev);
773 for (i = 0; i < 32 / 8; i++) {
774 pppos->in_accm[i] = (
u8_t)(accm >> (i * 8));
776 PPPOS_UNPROTECT(lev);
778 PPPDEBUG(LOG_INFO, (
"pppos_recv_config[%d]: in_accm=%X %X %X %X\n",
779 pppos->ppp->netif->num,
780 pppos->in_accm[0], pppos->in_accm[1], pppos->in_accm[2], pppos->in_accm[3]));
787 pppos_input_free_current_packet(pppos_pcb *pppos)
789 if (pppos->in_head !=
NULL) {
790 if (pppos->in_tail && (pppos->in_tail != pppos->in_head)) {
794 pppos->in_head =
NULL;
796 pppos->in_tail =
NULL;
803 pppos_input_drop(pppos_pcb *pppos)
805 if (pppos->in_head !=
NULL) {
807 PPPDEBUG(LOG_INFO, (
"pppos_input_drop: %d:%.*H\n", pppos->in_head->len, min(60, pppos->in_head->len * 2), pppos->in_head->payload));
809 PPPDEBUG(LOG_INFO, (
"pppos_input_drop: pbuf len=%d, addr %p\n", pppos->in_head->len, (
void*)pppos->in_head));
811 pppos_input_free_current_packet(pppos);
812 #if VJ_SUPPORT && LWIP_TCP 813 vj_uncompress_err(&pppos->ppp->vj_comp);
846 *fcs = PPP_FCS(*fcs, c);
850 if (accm && ESCAPE_P(pppos->out_accm, c)) {
861 pppos_output_last(pppos_pcb *pppos,
err_t err,
struct pbuf *nb,
u16_t *fcs)
863 ppp_pcb *ppp = pppos->ppp;
866 err = pppos_output_append(pppos, err, nb, ~(*fcs) & 0xFF, 1,
NULL);
867 err = pppos_output_append(pppos, err, nb, (~(*fcs) >> 8) & 0xFF, 1,
NULL);
868 err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0,
NULL);
891 pppos->last_xmit = 0;
#define PACK_STRUCT_STRUCT
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
void pbuf_realloc(struct pbuf *p, u16_t new_len)
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
#define PACK_STRUCT_FIELD(x)
void memp_free(memp_t type, void *mem)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define MIB2_STATS_NETIF_ADD(n, x, val)
#define PBUF_POOL_BUFSIZE
u8_t pbuf_free(struct pbuf *p)
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
#define PBUF_LINK_ENCAPSULATION_HLEN
#define LINK_STATS_INC(x)
#define LWIP_ASSERT(message, assertion)
#define PACK_STRUCT_BEGIN
void pbuf_cat(struct pbuf *h, struct pbuf *t)
#define MIB2_STATS_NETIF_INC(n, x)
void * memp_malloc(memp_t type)
#define LWIP_UNUSED_ARG(x)