1/********************************************************************* 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 3 See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage. 4 5 Authors: Serge Gadeyne, Daniele Lacamera, Maxime Vincent 6 7 *********************************************************************/ 8 9 10#include <stdint.h> 11#include <stdlib.h> 12#include <string.h> 13#include <stdio.h> 14 15#include "pico_device.h" 16#include "pico_dev_ppp.h" 17#include "pico_stack.h" 18#include "pico_ipv4.h" 19#include "pico_md5.h" 20#include "pico_dns_client.h" 21 22#ifdef DEBUG_PPP 23 #define ppp_dbg dbg 24#else 25 #define ppp_dbg(...) do {} while(0) 26#endif 27 28/* We should define this in a global header. */ 29#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 30 31#define PICO_PPP_MRU 1514 /* RFC default MRU */ 32#define PICO_PPP_MTU 1500 33#define PPP_MAXPKT 2048 34#define PPP_MAX_APN 134 35#define PPP_MAX_USERNAME 134 36#define PPP_MAX_PASSWORD 134 37#define PPP_HDR_SIZE 3u 38#define PPP_PROTO_SLOT_SIZE 2u 39#define PPP_FCS_SIZE 2u 40#define PPP_PROTO_LCP short_be(0xc021) 41#define PPP_PROTO_IP short_be(0x0021) 42#define PPP_PROTO_PAP short_be(0xc023) 43#define PPP_PROTO_CHAP short_be(0xc223) 44#define PPP_PROTO_IPCP short_be(0x8021) 45 46#define PICO_CONF_REQ 1 47#define PICO_CONF_ACK 2 48#define PICO_CONF_NAK 3 49#define PICO_CONF_REJ 4 50#define PICO_CONF_TERM 5 51#define PICO_CONF_TERM_ACK 6 52#define PICO_CONF_CODE_REJ 7 53#define PICO_CONF_PROTO_REJ 8 54#define PICO_CONF_ECHO_REQ 9 55#define PICO_CONF_ECHO_REP 10 56#define PICO_CONF_DISCARD_REQ 11 57 58#define LCPOPT_MRU 1u /* param size: 4, fixed: MRU */ 59#define LCPOPT_AUTH 3u /* param size: 4-5: AUTH proto */ 60#define LCPOPT_QUALITY 4u /* unused for now */ 61#define LCPOPT_MAGIC 5u /* param size: 6, fixed: Magic */ 62#define LCPOPT_PROTO_COMP 7u /* param size: 0, flag */ 63#define LCPOPT_ADDRCTL_COMP 8u /* param size: 0, flag */ 64 65#define CHAP_MD5_SIZE 16u 66#define CHAP_CHALLENGE 1 67#define CHAP_RESPONSE 2 68#define CHAP_SUCCESS 3 69#define CHAP_FAILURE 4 70#define CHALLENGE_SIZE(ppp, ch) ((size_t)((1 + strlen(ppp->password) + short_be((ch)->len)))) 71 72#define PAP_AUTH_REQ 1 73#define PAP_AUTH_ACK 2 74#define PAP_AUTH_NAK 3 75 76 77#define PICO_PPP_DEFAULT_TIMER (3) /* seconds */ 78#define PICO_PPP_DEFAULT_MAX_TERMINATE (2) 79#define PICO_PPP_DEFAULT_MAX_CONFIGURE (10) 80#define PICO_PPP_DEFAULT_MAX_FAILURE (5) 81#define PICO_PPP_DEFAULT_MAX_DIALTIME (20) 82 83#define IPCP_ADDR_LEN 6u 84#define IPCP_VJ_LEN 6u 85#define IPCP_OPT_IP 0x03 86#define IPCP_OPT_VJ 0x02 87#define IPCP_OPT_DNS1 0x81 88#define IPCP_OPT_NBNS1 0x82 89#define IPCP_OPT_DNS2 0x83 90#define IPCP_OPT_NBNS2 0x84 91 92static uint8_t LCPOPT_LEN[9] = { 93 0, 4, 0, 4, 4, 6, 2, 2, 2 94}; 95 96 97/* Protocol defines */ 98static const unsigned char AT_S3 = 0x0du; 99static const unsigned char AT_S4 = 0x0au; 100static const unsigned char PPPF_FLAG_SEQ = 0x7eu; 101static const unsigned char PPPF_CTRL_ESC = 0x7du; 102static const unsigned char PPPF_ADDR = 0xffu; 103static const unsigned char PPPF_CTRL = 0x03u; 104 105static int ppp_devnum = 0; 106static uint8_t ppp_recv_buf[PPP_MAXPKT]; 107 108PACKED_STRUCT_DEF pico_lcp_hdr { 109 uint8_t code; 110 uint8_t id; 111 uint16_t len; 112}; 113 114PACKED_STRUCT_DEF pico_chap_hdr { 115 uint8_t code; 116 uint8_t id; 117 uint16_t len; 118}; 119 120PACKED_STRUCT_DEF pico_pap_hdr { 121 uint8_t code; 122 uint8_t id; 123 uint16_t len; 124}; 125 126PACKED_STRUCT_DEF pico_ipcp_hdr { 127 uint8_t code; 128 uint8_t id; 129 uint16_t len; 130}; 131 132enum ppp_modem_state { 133 PPP_MODEM_STATE_INITIAL = 0, 134 PPP_MODEM_STATE_RESET, 135 PPP_MODEM_STATE_ECHO, 136 PPP_MODEM_STATE_CREG, 137 PPP_MODEM_STATE_CGREG, 138 PPP_MODEM_STATE_CGDCONT, 139 PPP_MODEM_STATE_CGATT, 140 PPP_MODEM_STATE_DIAL, 141 PPP_MODEM_STATE_CONNECTED, 142 PPP_MODEM_STATE_MAX 143}; 144 145enum ppp_modem_event { 146 PPP_MODEM_EVENT_START = 0, 147 PPP_MODEM_EVENT_STOP, 148 PPP_MODEM_EVENT_OK, 149 PPP_MODEM_EVENT_CONNECT, 150 PPP_MODEM_EVENT_TIMEOUT, 151 PPP_MODEM_EVENT_MAX 152}; 153 154enum ppp_lcp_state { 155 PPP_LCP_STATE_INITIAL = 0, 156 PPP_LCP_STATE_STARTING, 157 PPP_LCP_STATE_CLOSED, 158 PPP_LCP_STATE_STOPPED, 159 PPP_LCP_STATE_CLOSING, 160 PPP_LCP_STATE_STOPPING, 161 PPP_LCP_STATE_REQ_SENT, 162 PPP_LCP_STATE_ACK_RCVD, 163 PPP_LCP_STATE_ACK_SENT, 164 PPP_LCP_STATE_OPENED, 165 PPP_LCP_STATE_MAX 166}; 167 168enum ppp_lcp_event { 169 PPP_LCP_EVENT_UP = 0, 170 PPP_LCP_EVENT_DOWN, 171 PPP_LCP_EVENT_OPEN, 172 PPP_LCP_EVENT_CLOSE, 173 PPP_LCP_EVENT_TO_POS, 174 PPP_LCP_EVENT_TO_NEG, 175 PPP_LCP_EVENT_RCR_POS, 176 PPP_LCP_EVENT_RCR_NEG, 177 PPP_LCP_EVENT_RCA, 178 PPP_LCP_EVENT_RCN, 179 PPP_LCP_EVENT_RTR, 180 PPP_LCP_EVENT_RTA, 181 PPP_LCP_EVENT_RUC, 182 PPP_LCP_EVENT_RXJ_POS, 183 PPP_LCP_EVENT_RXJ_NEG, 184 PPP_LCP_EVENT_RXR, 185 PPP_LCP_EVENT_MAX 186}; 187 188enum ppp_auth_state { 189 PPP_AUTH_STATE_INITIAL = 0, 190 PPP_AUTH_STATE_STARTING, 191 PPP_AUTH_STATE_RSP_SENT, 192 PPP_AUTH_STATE_REQ_SENT, 193 PPP_AUTH_STATE_AUTHENTICATED, 194 PPP_AUTH_STATE_MAX 195}; 196 197enum ppp_auth_event { 198 PPP_AUTH_EVENT_UP_NONE = 0, 199 PPP_AUTH_EVENT_UP_PAP, 200 PPP_AUTH_EVENT_UP_CHAP, 201 PPP_AUTH_EVENT_DOWN, 202 PPP_AUTH_EVENT_RAC, 203 PPP_AUTH_EVENT_RAA, 204 PPP_AUTH_EVENT_RAN, 205 PPP_AUTH_EVENT_TO, 206 PPP_AUTH_EVENT_MAX 207}; 208 209enum ppp_ipcp_state { 210 PPP_IPCP_STATE_INITIAL = 0, 211 PPP_IPCP_STATE_REQ_SENT, 212 PPP_IPCP_STATE_ACK_RCVD, 213 PPP_IPCP_STATE_ACK_SENT, 214 PPP_IPCP_STATE_OPENED, 215 PPP_IPCP_STATE_MAX 216}; 217 218enum ppp_ipcp_event { 219 PPP_IPCP_EVENT_UP = 0, 220 PPP_IPCP_EVENT_DOWN, 221 PPP_IPCP_EVENT_RCR_POS, 222 PPP_IPCP_EVENT_RCR_NEG, 223 PPP_IPCP_EVENT_RCA, 224 PPP_IPCP_EVENT_RCN, 225 PPP_IPCP_EVENT_TO, 226 PPP_IPCP_EVENT_MAX 227}; 228 229enum pico_ppp_state { 230 PPP_MODEM_RST = 0, 231 PPP_MODEM_CREG, 232 PPP_MODEM_CGREG, 233 PPP_MODEM_CGDCONT, 234 PPP_MODEM_CGATT, 235 PPP_MODEM_CONNECT, 236 /* From here on, PPP states */ 237 PPP_ESTABLISH, 238 PPP_AUTH, 239 PPP_NETCONFIG, 240 PPP_NETWORK, 241 PPP_TERMINATE, 242 /* MAXSTATE is the last one */ 243 PPP_MODEM_MAXSTATE 244}; 245 246 247#define IPCP_ALLOW_IP 0x01u 248#define IPCP_ALLOW_DNS1 0x02u 249#define IPCP_ALLOW_DNS2 0x04u 250#define IPCP_ALLOW_NBNS1 0x08u 251#define IPCP_ALLOW_NBNS2 0x10u 252 253struct pico_device_ppp { 254 struct pico_device dev; 255 int autoreconnect; 256 enum ppp_modem_state modem_state; 257 enum ppp_lcp_state lcp_state; 258 enum ppp_auth_state auth_state; 259 enum ppp_ipcp_state ipcp_state; 260 enum pico_ppp_state state; 261 char apn[PPP_MAX_APN]; 262 char password[PPP_MAX_PASSWORD]; 263 char username[PPP_MAX_USERNAME]; 264 uint16_t lcpopt_local; 265 uint16_t lcpopt_peer; 266 uint8_t *pkt; 267 uint32_t len; 268 uint16_t rej; 269 uint16_t auth; 270 int (*serial_recv)(struct pico_device *dev, void *buf, int len); 271 int (*serial_send)(struct pico_device *dev, const void *buf, int len); 272 int (*serial_set_speed)(struct pico_device *dev, uint32_t speed); 273 uint32_t ipcp_allowed_fields; 274 uint32_t ipcp_ip; 275 uint32_t ipcp_dns1; 276 uint32_t ipcp_nbns1; 277 uint32_t ipcp_dns2; 278 uint32_t ipcp_nbns2; 279 uint32_t timer; 280 uint8_t timer_val; 281 uint8_t timer_count; 282 uint8_t frame_id; 283 uint8_t timer_on; 284 uint16_t mru; 285}; 286 287 288/* Unit test interceptor */ 289static void (*mock_modem_state)(struct pico_device_ppp *ppp, enum ppp_modem_event event) = NULL; 290static void (*mock_lcp_state)(struct pico_device_ppp *ppp, enum ppp_lcp_event event) = NULL; 291static void (*mock_auth_state)(struct pico_device_ppp *ppp, enum ppp_auth_event event) = NULL; 292static void (*mock_ipcp_state)(struct pico_device_ppp *ppp, enum ppp_ipcp_event event) = NULL; 293 294/* Debug prints */ 295#ifdef PPP_DEBUG 296static void lcp_optflags_print(struct pico_device_ppp *ppp, uint8_t *opts, uint32_t opts_len); 297#endif 298 299#define PPP_TIMER_ON_MODEM 0x01u 300#define PPP_TIMER_ON_LCPREQ 0x04u 301#define PPP_TIMER_ON_LCPTERM 0x08u 302#define PPP_TIMER_ON_AUTH 0x10u 303#define PPP_TIMER_ON_IPCP 0x20u 304 305/* Escape and send */ 306static int ppp_serial_send_escape(struct pico_device_ppp *ppp, void *buf, int len) 307{ 308 uint8_t *in_buf = (uint8_t *)buf; 309 uint8_t *out_buf = NULL; 310 int esc_char_count = 0; 311 int newlen = 0, ret = -1; 312 int i, j; 313 314#ifdef PPP_DEBUG 315 { 316 uint32_t idx; 317 if (len > 0) { 318 ppp_dbg("PPP >>>> "); 319 for(idx = 0; idx < (uint32_t)len; idx++) { 320 ppp_dbg(" %02x", ((uint8_t *)buf)[idx]); 321 } 322 ppp_dbg("\n"); 323 } 324 } 325#endif 326 327 for (i = 1; i < (len - 1); i++) /* from 1 to len -1, as start/stop are not escaped */ 328 { 329 if (((in_buf[i] + 1u) >> 1) == 0x3Fu) 330 esc_char_count++; 331 } 332 if (!esc_char_count) { 333 return ppp->serial_send(&ppp->dev, buf, len); 334 } 335 336 newlen = len + esc_char_count; 337 out_buf = PICO_ZALLOC((uint32_t)newlen); 338 if(!out_buf) 339 return -1; 340 341 /* Start byte. */ 342 out_buf[0] = in_buf[0]; 343 for(i = 1, j = 1; i < (len - 1); i++) { 344 if (((in_buf[i] + 1u) >> 1) == 0x3Fu) { 345 out_buf[j++] = PPPF_CTRL_ESC; 346 out_buf[j++] = in_buf[i] ^ 0x20; 347 } else { 348 out_buf[j++] = in_buf[i]; 349 } 350 } 351 /* Stop byte. */ 352 out_buf[newlen - 1] = in_buf[len - 1]; 353 354 ret = ppp->serial_send(&ppp->dev, out_buf, newlen); 355 356 PICO_FREE(out_buf); 357 358 if (ret == newlen) 359 return len; 360 361 return ret; 362 363} 364 365static void lcp_timer_start(struct pico_device_ppp *ppp, uint8_t timer_type) 366{ 367 uint8_t count = 0; 368 ppp->timer_on |= timer_type; 369 370 if (ppp->timer_val == 0) { 371 ppp->timer_val = PICO_PPP_DEFAULT_TIMER; 372 } 373 374 if (timer_type == PPP_TIMER_ON_LCPTERM) { 375 count = PICO_PPP_DEFAULT_MAX_TERMINATE; 376 } 377 378 if (timer_type == PPP_TIMER_ON_LCPREQ) { 379 count = PICO_PPP_DEFAULT_MAX_CONFIGURE; 380 } 381 382 if (timer_type == 0) { 383 ppp->timer_on |= PPP_TIMER_ON_LCPREQ; 384 ppp->timer_count = 0; 385 } 386 387 if (ppp->timer_count == 0) 388 ppp->timer_count = count; 389} 390 391static void lcp_zero_restart_count(struct pico_device_ppp *ppp) 392{ 393 lcp_timer_start(ppp, 0); 394} 395 396static void lcp_timer_stop(struct pico_device_ppp *ppp, uint8_t timer_type) 397{ 398 ppp->timer_on = (uint8_t)ppp->timer_on & (uint8_t)(~timer_type); 399} 400 401 402#define PPP_FSM_MAX_ACTIONS 3 403 404struct pico_ppp_fsm { 405 int next_state; 406 void (*event_handler[PPP_FSM_MAX_ACTIONS]) (struct pico_device_ppp *); 407}; 408 409#define LCPOPT_SET_LOCAL(ppp, opt) ppp->lcpopt_local |= (uint16_t)(1u << opt) 410#define LCPOPT_SET_PEER(ppp, opt) ppp->lcpopt_peer |= (uint16_t)(1u << opt) 411#define LCPOPT_UNSET_LOCAL(ppp, opt) ppp->lcpopt_local &= (uint16_t) ~(1u << opt) 412#define LCPOPT_UNSET_LOCAL_MASK(ppp, opt) ppp->lcpopt_local &= (uint16_t) ~(opt) 413#define LCPOPT_UNSET_PEER(ppp, opt) ppp->lcpopt_peer &= (uint16_t) ~(1u << opt) 414#define LCPOPT_ISSET_LOCAL(ppp, opt) ((ppp->lcpopt_local & (uint16_t)(1u << opt)) != 0) 415#define LCPOPT_ISSET_PEER(ppp, opt) ((ppp->lcpopt_peer & (uint16_t)(1u << opt)) != 0) 416 417static void evaluate_modem_state(struct pico_device_ppp *ppp, enum ppp_modem_event event); 418static void evaluate_lcp_state(struct pico_device_ppp *ppp, enum ppp_lcp_event event); 419static void evaluate_auth_state(struct pico_device_ppp *ppp, enum ppp_auth_event event); 420static void evaluate_ipcp_state(struct pico_device_ppp *ppp, enum ppp_ipcp_event event); 421 422 423static uint32_t ppp_ctl_packet_size(struct pico_device_ppp *ppp, uint16_t proto, uint32_t *size) 424{ 425 uint32_t prefix = 0; 426 427 IGNORE_PARAMETER(ppp); 428 IGNORE_PARAMETER(proto); 429 430 prefix += PPP_HDR_SIZE; /* 7e ff 03 ... */ 431 prefix += PPP_PROTO_SLOT_SIZE; 432 *size += prefix; 433 *size += PPP_FCS_SIZE; 434 (*size)++; /* STOP byte 0x7e */ 435 return prefix; 436} 437 438/* CRC16 / FCS Calculation */ 439static uint16_t ppp_fcs_char(uint16_t old_crc, uint8_t data) 440{ 441 uint16_t word = (old_crc ^ data) & (uint16_t)0x00FFu; 442 word = (uint16_t)(word ^ (uint16_t)((word << 4u) & (uint16_t)0x00FFu)); 443 word = (uint16_t)((word << 8u) ^ (word << 3u) ^ (word >> 4u)); 444 return ((old_crc >> 8u) ^ word); 445} 446 447static uint16_t ppp_fcs_continue(uint16_t fcs, uint8_t *buf, uint32_t len) 448{ 449 uint8_t *pos = buf; 450 for (pos = buf; pos < buf + len; pos++) 451 { 452 fcs = ppp_fcs_char(fcs, *pos); 453 } 454 return fcs; 455} 456 457static uint16_t ppp_fcs_finish(uint16_t fcs) 458{ 459 return fcs ^ 0xFFFF; 460} 461 462static uint16_t ppp_fcs_start(uint8_t *buf, uint32_t len) 463{ 464 uint16_t fcs = 0xFFFF; 465 return ppp_fcs_continue(fcs, buf, len); 466} 467 468static int ppp_fcs_verify(uint8_t *buf, uint32_t len) 469{ 470 uint16_t fcs = ppp_fcs_start(buf, len - 2); 471 fcs = ppp_fcs_finish(fcs); 472 if ((((fcs & 0xFF00u) >> 8) != buf[len - 1]) || ((fcs & 0xFFu) != buf[len - 2])) { 473 return -1; 474 } 475 476 return 0; 477} 478 479/* Serial send (DTE->DCE) functions */ 480static int pico_ppp_ctl_send(struct pico_device *dev, uint16_t code, uint8_t *pkt, uint32_t len) 481{ 482 struct pico_device_ppp *ppp = (struct pico_device_ppp *) dev; 483 uint16_t fcs; 484 uint8_t *ptr = pkt; 485 int i = 0; 486 487 if (!ppp->serial_send) 488 return (int)len; 489 490 /* PPP Header */ 491 ptr[i++] = PPPF_FLAG_SEQ; 492 ptr[i++] = PPPF_ADDR; 493 ptr[i++] = PPPF_CTRL; 494 /* protocol */ 495 ptr[i++] = (uint8_t)(code & 0xFFu); 496 ptr[i++] = (uint8_t)((code & 0xFF00u) >> 8); 497 498 /* payload is already in place. Calculate FCS. */ 499 fcs = ppp_fcs_start(pkt + 1, len - 4); /* FCS excludes: start (1), FCS(2), stop(1), total 4 bytes */ 500 fcs = ppp_fcs_finish(fcs); 501 pkt[len - 3] = (uint8_t)(fcs & 0xFFu); 502 pkt[len - 2] = (uint8_t)((fcs & 0xFF00u) >> 8); 503 pkt[len - 1] = PPPF_FLAG_SEQ; 504 ppp_serial_send_escape(ppp, pkt, (int)len); 505 return (int)len; 506} 507 508static uint8_t pico_ppp_data_buffer[PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + PICO_PPP_MTU + PPP_FCS_SIZE + 1]; 509static int pico_ppp_send(struct pico_device *dev, void *buf, int len) 510{ 511 struct pico_device_ppp *ppp = (struct pico_device_ppp *) dev; 512 uint16_t fcs = 0; 513 int fcs_start; 514 int i = 0; 515 516 ppp_dbg(" >>>>>>>>> PPP OUT\n"); 517 518 if (ppp->ipcp_state != PPP_IPCP_STATE_OPENED) 519 return len; 520 521 if (!ppp->serial_send) 522 return len; 523 524 pico_ppp_data_buffer[i++] = PPPF_FLAG_SEQ; 525 if (!LCPOPT_ISSET_PEER(ppp, LCPOPT_ADDRCTL_COMP)) 526 { 527 pico_ppp_data_buffer[i++] = PPPF_ADDR; 528 pico_ppp_data_buffer[i++] = PPPF_CTRL; 529 } 530 531 fcs_start = i; 532 533 if (!LCPOPT_ISSET_PEER(ppp, LCPOPT_PROTO_COMP)) 534 { 535 pico_ppp_data_buffer[i++] = 0x00; 536 } 537 538 pico_ppp_data_buffer[i++] = 0x21; 539 memcpy(pico_ppp_data_buffer + i, buf, (uint32_t)len); 540 i += len; 541 fcs = ppp_fcs_start(pico_ppp_data_buffer + fcs_start, (uint32_t)(i - fcs_start)); 542 fcs = ppp_fcs_finish(fcs); 543 pico_ppp_data_buffer[i++] = (uint8_t)(fcs & 0xFFu); 544 pico_ppp_data_buffer[i++] = (uint8_t)((fcs & 0xFF00u) >> 8); 545 pico_ppp_data_buffer[i++] = PPPF_FLAG_SEQ; 546 547 ppp_serial_send_escape(ppp, pico_ppp_data_buffer, i); 548 return len; 549} 550 551 552/* FSM functions */ 553 554static void ppp_modem_start_timer(struct pico_device_ppp *ppp) 555{ 556 ppp->timer_on = ppp->timer_on | PPP_TIMER_ON_MODEM; 557 ppp->timer_val = PICO_PPP_DEFAULT_TIMER; 558} 559 560#define PPP_AT_CREG0 "ATZ\r\n" 561static void ppp_modem_send_reset(struct pico_device_ppp *ppp) 562{ 563 if (ppp->serial_send) 564 ppp->serial_send(&ppp->dev, PPP_AT_CREG0, strlen(PPP_AT_CREG0)); 565 566 ppp_modem_start_timer(ppp); 567} 568 569#define PPP_AT_CREG1 "ATE0\r\n" 570static void ppp_modem_send_echo(struct pico_device_ppp *ppp) 571{ 572 if (ppp->serial_send) 573 ppp->serial_send(&ppp->dev, PPP_AT_CREG1, strlen(PPP_AT_CREG1)); 574 575 ppp_modem_start_timer(ppp); 576} 577 578#define PPP_AT_CREG2 "AT+CREG=1\r\n" 579static void ppp_modem_send_creg(struct pico_device_ppp *ppp) 580{ 581 if (ppp->serial_send) 582 ppp->serial_send(&ppp->dev, PPP_AT_CREG2, strlen(PPP_AT_CREG2)); 583 584 ppp_modem_start_timer(ppp); 585} 586 587#define PPP_AT_CGREG "AT+CGREG=1\r\n" 588static void ppp_modem_send_cgreg(struct pico_device_ppp *ppp) 589{ 590 if (ppp->serial_send) 591 ppp->serial_send(&ppp->dev, PPP_AT_CGREG, strlen(PPP_AT_CGREG)); 592 593 ppp_modem_start_timer(ppp); 594} 595 596 597#define PPP_AT_CGDCONT "AT+CGDCONT=1,\"IP\",\"%s\",,,\r\n" 598static void ppp_modem_send_cgdcont(struct pico_device_ppp *ppp) 599{ 600 char at_cgdcont[200]; 601 602 if (ppp->serial_send) { 603 snprintf(at_cgdcont, 200, PPP_AT_CGDCONT, ppp->apn); 604 ppp->serial_send(&ppp->dev, at_cgdcont, (int)strlen(at_cgdcont)); 605 } 606 607 ppp_modem_start_timer(ppp); 608} 609 610 611#define PPP_AT_CGATT "AT+CGATT=1\r\n" 612static void ppp_modem_send_cgatt(struct pico_device_ppp *ppp) 613{ 614 if (ppp->serial_send) 615 ppp->serial_send(&ppp->dev, PPP_AT_CGATT, strlen(PPP_AT_CGATT)); 616 617 ppp_modem_start_timer(ppp); 618} 619 620#ifdef PICOTCP_PPP_SUPPORT_QUERIES 621#define PPP_AT_CGATT_Q "AT+CGATT?\r\n" 622static void ppp_modem_send_cgatt_q(struct pico_device_ppp *ppp) 623{ 624 if (ppp->serial_send) 625 ppp->serial_send(&ppp->dev, PPP_AT_CGATT_Q, strlen(PPP_AT_CGATT_Q)); 626 627 ppp_modem_start_timer(ppp); 628} 629#define PPP_AT_CGDCONT_Q "AT+CGDCONT?\r\n" 630static void ppp_modem_send_cgdcont_q(struct pico_device_ppp *ppp) 631{ 632 if (ppp->serial_send) 633 ppp->serial_send(&ppp->dev, PPP_AT_CGDCONT_Q, strlen(PPP_AT_CGDCONT_Q)); 634 635 ppp_modem_start_timer(ppp); 636} 637 638#define PPP_AT_CGREG_Q "AT+CGREG?\r\n" 639static void ppp_modem_send_cgreg_q(struct pico_device_ppp *ppp) 640{ 641 if (ppp->serial_send) 642 ppp->serial_send(&ppp->dev, PPP_AT_CGREG_Q, strlen(PPP_AT_CGREG_Q)); 643 644 ppp_modem_start_timer(ppp); 645} 646 647#define PPP_AT_CREG3 "AT+CREG?\r\n" 648static void ppp_modem_send_creg_q(struct pico_device_ppp *ppp) 649{ 650 if (ppp->serial_send) 651 ppp->serial_send(&ppp->dev, PPP_AT_CREG3, strlen(PPP_AT_CREG3)); 652 653 ppp_modem_start_timer(ppp); 654} 655#endif /* PICOTCP_PPP_SUPPORT_QUERIES */ 656 657#define PPP_AT_DIALIN "ATD*99***1#\r\n" 658static void ppp_modem_send_dial(struct pico_device_ppp *ppp) 659{ 660 if (ppp->serial_send) 661 ppp->serial_send(&ppp->dev, PPP_AT_DIALIN, strlen(PPP_AT_DIALIN)); 662 663 ppp_modem_start_timer(ppp); 664 ppp->timer_val = PICO_PPP_DEFAULT_MAX_DIALTIME; 665} 666 667static void ppp_modem_connected(struct pico_device_ppp *ppp) 668{ 669 ppp_dbg("PPP: Modem connected to peer.\n"); 670 evaluate_lcp_state(ppp, PPP_LCP_EVENT_UP); 671} 672 673#define PPP_ATH "+++ATH\r\n" 674static void ppp_modem_disconnected(struct pico_device_ppp *ppp) 675{ 676 ppp_dbg("PPP: Modem disconnected.\n"); 677 if (ppp->serial_send) 678 ppp->serial_send(&ppp->dev, PPP_ATH, strlen(PPP_ATH)); 679 680 evaluate_lcp_state(ppp, PPP_LCP_EVENT_DOWN); 681} 682 683static const struct pico_ppp_fsm ppp_modem_fsm[PPP_MODEM_STATE_MAX][PPP_MODEM_EVENT_MAX] = { 684 [PPP_MODEM_STATE_INITIAL] = { 685 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} }, 686 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 687 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_INITIAL, {} }, 688 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_INITIAL, {} }, 689 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_INITIAL, {ppp_modem_send_reset} } 690 }, 691 [PPP_MODEM_STATE_RESET] = { 692 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_RESET, {} }, 693 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 694 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_ECHO, { ppp_modem_send_echo } }, 695 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_RESET, {} }, 696 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 697 }, 698 [PPP_MODEM_STATE_ECHO] = { 699 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_ECHO, {} }, 700 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 701 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_CREG, { ppp_modem_send_creg } }, 702 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_ECHO, {} }, 703 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 704 }, 705 [PPP_MODEM_STATE_CREG] = { 706 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_CREG, {} }, 707 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 708 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_CGREG, { ppp_modem_send_cgreg } }, 709 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CREG, {} }, 710 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 711 }, 712 [PPP_MODEM_STATE_CGREG] = { 713 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_CGREG, {} }, 714 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 715 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_CGDCONT, { ppp_modem_send_cgdcont } }, 716 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CGREG, {} }, 717 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 718 }, 719 [PPP_MODEM_STATE_CGDCONT] = { 720 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_CGDCONT, {} }, 721 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 722 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_CGATT, { ppp_modem_send_cgatt } }, 723 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CGDCONT, {} }, 724 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 725 }, 726 [PPP_MODEM_STATE_CGATT] = { 727 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_CGATT, {} }, 728 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 729 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_DIAL, { ppp_modem_send_dial } }, 730 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CGATT, {} }, 731 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 732 }, 733 [PPP_MODEM_STATE_DIAL] = { 734 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_DIAL, {} }, 735 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, {} }, 736 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_DIAL, {} }, 737 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CONNECTED, { ppp_modem_connected } }, 738 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_RESET, {ppp_modem_send_reset} } 739 }, 740 [PPP_MODEM_STATE_CONNECTED] = { 741 [PPP_MODEM_EVENT_START] = { PPP_MODEM_STATE_CONNECTED, {} }, 742 [PPP_MODEM_EVENT_STOP] = { PPP_MODEM_STATE_INITIAL, { ppp_modem_disconnected } }, 743 [PPP_MODEM_EVENT_OK] = { PPP_MODEM_STATE_CONNECTED, {} }, 744 [PPP_MODEM_EVENT_CONNECT] = { PPP_MODEM_STATE_CONNECTED, {} }, 745 [PPP_MODEM_EVENT_TIMEOUT] = { PPP_MODEM_STATE_CONNECTED, {} } 746 } 747}; 748static void evaluate_modem_state(struct pico_device_ppp *ppp, enum ppp_modem_event event) 749{ 750 const struct pico_ppp_fsm *fsm; 751 int i; 752 if (mock_modem_state) { 753 mock_modem_state(ppp, event); 754 return; 755 } 756 757 fsm = &ppp_modem_fsm[ppp->modem_state][event]; 758 759 ppp->modem_state = (enum ppp_modem_state)fsm->next_state; 760 761 for (i = 0; i < PPP_FSM_MAX_ACTIONS; i++) { 762 if (fsm->event_handler[i]) 763 fsm->event_handler[i](ppp); 764 } 765} 766 767static void ppp_modem_recv(struct pico_device_ppp *ppp, void *data, uint32_t len) 768{ 769 IGNORE_PARAMETER(len); 770 771 ppp_dbg("PPP: Recv: '%s'\n", (char *)data); 772 773 if (strcmp(data, "OK") == 0) { 774 evaluate_modem_state(ppp, PPP_MODEM_EVENT_OK); 775 } 776 777 if (strcmp(data, "ERROR") == 0) { 778 evaluate_modem_state(ppp, PPP_MODEM_EVENT_STOP); 779 } 780 781 if (strncmp(data, "CONNECT", 7) == 0) { 782 evaluate_modem_state(ppp, PPP_MODEM_EVENT_CONNECT); 783 } 784} 785 786static void lcp_send_configure_request(struct pico_device_ppp *ppp) 787{ 788# define MY_LCP_REQ_SIZE 12 /* Max value. */ 789 struct pico_lcp_hdr *req; 790 uint8_t *lcpbuf, *opts; 791 uint32_t size = MY_LCP_REQ_SIZE; 792 uint32_t prefix; 793 uint32_t optsize = 0; 794 795 prefix = ppp_ctl_packet_size(ppp, PPP_PROTO_LCP, &size); 796 lcpbuf = PICO_ZALLOC(size); 797 if (!lcpbuf) 798 return; 799 800 req = (struct pico_lcp_hdr *)(lcpbuf + prefix); 801 802 opts = lcpbuf + prefix + (sizeof(struct pico_lcp_hdr)); 803 /* uint8_t my_pkt[] = { 0x7e, 0xff, 0x03, 0xc0, 0x21, 0x01, 0x00, 0x00, 0x06, 0x07, 0x02, 0x64, 0x7b, 0x7e }; */ 804 805 ppp_dbg("Sending LCP CONF REQ\n"); 806 req->code = PICO_CONF_REQ; 807 req->id = ppp->frame_id++; 808 809 if (LCPOPT_ISSET_LOCAL(ppp, LCPOPT_PROTO_COMP)) { 810 opts[optsize++] = LCPOPT_PROTO_COMP; 811 opts[optsize++] = LCPOPT_LEN[LCPOPT_PROTO_COMP]; 812 } 813 814 if (LCPOPT_ISSET_LOCAL(ppp, LCPOPT_MRU)) { 815 opts[optsize++] = LCPOPT_MRU; 816 opts[optsize++] = LCPOPT_LEN[LCPOPT_MRU]; 817 opts[optsize++] = (uint8_t)((ppp->mru >> 8) & 0xFF); 818 opts[optsize++] = (uint8_t)(ppp->mru & 0xFF); 819 } else { 820 ppp->mru = PICO_PPP_MRU; 821 } 822 823 if (LCPOPT_ISSET_LOCAL(ppp, LCPOPT_ADDRCTL_COMP)) { 824 opts[optsize++] = LCPOPT_ADDRCTL_COMP; 825 opts[optsize++] = LCPOPT_LEN[LCPOPT_ADDRCTL_COMP]; 826 } 827 828 req->len = short_be((uint16_t)((unsigned long)optsize + sizeof(struct pico_lcp_hdr))); 829 830#ifdef PPP_DEBUG 831 lcp_optflags_print(ppp, opts, optsize); 832#endif 833 834 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, 835 lcpbuf, /* Start of PPP packet */ 836 (uint32_t)(prefix + /* PPP Header, etc. */ 837 sizeof(struct pico_lcp_hdr) + /* LCP HDR */ 838 optsize + /* Actual options size */ 839 PPP_FCS_SIZE + /* FCS at the end of the frame */ 840 1u) /* STOP Byte */ 841 ); 842 PICO_FREE(lcpbuf); 843 ppp->timer_val = PICO_PPP_DEFAULT_TIMER; 844 lcp_timer_start(ppp, PPP_TIMER_ON_LCPREQ); 845} 846 847#ifdef PPP_DEBUG 848static void lcp_optflags_print(struct pico_device_ppp *ppp, uint8_t *opts, uint32_t opts_len) 849{ 850 uint8_t *p = opts; 851 int off; 852 IGNORE_PARAMETER(ppp); 853 ppp_dbg("Parsing options:\n"); 854 while(p < (opts + opts_len)) { 855 int i; 856 857 ppp_dbg("-- LCP opt: %d - len: %d - data:", p[0], p[1]); 858 for (i = 0; i < p[1] - 2; i++) 859 { 860 ppp_dbg(" %02X", p[2 + i]); 861 } 862 ppp_dbg("\n"); 863 864 off = p[1]; 865 if (!off) 866 break; 867 868 p += off; 869 } 870} 871#endif 872 873/* setting adjust_opts will adjust our options to the ones supplied */ 874static uint16_t lcp_optflags(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len, int adjust_opts) 875{ 876 uint16_t flags = 0; 877 uint8_t *p = pkt + sizeof(struct pico_lcp_hdr); 878 int off; 879 while(p < (pkt + len)) { 880 flags = (uint16_t)((uint16_t)(1u << (uint16_t)p[0]) | flags); 881 882 if (adjust_opts && ppp) 883 { 884 switch (p[0]) 885 { 886 case LCPOPT_MRU: 887 /* XXX: Can we accept any MRU ? */ 888 ppp_dbg("Adjusting MRU to %02x%02x\n", p[2], p[3]); 889 ppp->mru = (uint16_t)((p[2] << 8) + p[3]); 890 break; 891 case LCPOPT_AUTH: 892 ppp_dbg("Setting AUTH to %02x%02x\n", p[2], p[3]); 893 ppp->auth = (uint16_t)((p[2] << 8) + p[3]); 894 break; 895 default: 896 break; 897 } 898 } 899 900 off = p[1]; /* opt length field */ 901 if (!off) 902 break; 903 904 p += off; 905 } 906#ifdef PPP_DEBUG 907 lcp_optflags_print(ppp, pkt + sizeof(struct pico_lcp_hdr), (uint32_t)(len - sizeof(struct pico_lcp_hdr))); 908#endif 909 return flags; 910} 911 912 913static void lcp_send_configure_ack(struct pico_device_ppp *ppp) 914{ 915 uint8_t ack[ppp->len + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr) + PPP_FCS_SIZE + 1]; 916 struct pico_lcp_hdr *ack_hdr = (struct pico_lcp_hdr *) (ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 917 struct pico_lcp_hdr *lcpreq = (struct pico_lcp_hdr *)ppp->pkt; 918 memcpy(ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE, ppp->pkt, ppp->len); 919 ack_hdr->code = PICO_CONF_ACK; 920 ack_hdr->id = lcpreq->id; 921 ack_hdr->len = lcpreq->len; 922 ppp_dbg("Sending LCP CONF ACK\n"); 923 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, ack, 924 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 925 short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ 926 PPP_FCS_SIZE + /* FCS at the end of the frame */ 927 1 /* STOP Byte */ 928 ); 929} 930 931static void lcp_send_terminate_request(struct pico_device_ppp *ppp) 932{ 933 uint8_t term[PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr) + PPP_FCS_SIZE + 1]; 934 struct pico_lcp_hdr *term_hdr = (struct pico_lcp_hdr *) (term + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 935 term_hdr->code = PICO_CONF_TERM; 936 term_hdr->id = ppp->frame_id++; 937 term_hdr->len = short_be((uint16_t)sizeof(struct pico_lcp_hdr)); 938 ppp_dbg("Sending LCP TERMINATE REQUEST\n"); 939 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, term, 940 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 941 sizeof(struct pico_lcp_hdr) + /* Actual options size + hdr (whole lcp packet) */ 942 PPP_FCS_SIZE + /* FCS at the end of the frame */ 943 1 /* STOP Byte */ 944 ); 945 lcp_timer_start(ppp, PPP_TIMER_ON_LCPTERM); 946} 947 948static void lcp_send_terminate_ack(struct pico_device_ppp *ppp) 949{ 950 uint8_t ack[ppp->len + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr) + PPP_FCS_SIZE + 1]; 951 struct pico_lcp_hdr *ack_hdr = (struct pico_lcp_hdr *) (ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 952 struct pico_lcp_hdr *lcpreq = (struct pico_lcp_hdr *)ppp->pkt; 953 memcpy(ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE, ppp->pkt, ppp->len); 954 ack_hdr->code = PICO_CONF_TERM_ACK; 955 ack_hdr->id = lcpreq->id; 956 ack_hdr->len = lcpreq->len; 957 ppp_dbg("Sending LCP TERM ACK\n"); 958 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, ack, 959 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 960 short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ 961 PPP_FCS_SIZE + /* FCS at the end of the frame */ 962 1 /* STOP Byte */ 963 ); 964} 965 966static void lcp_send_configure_nack(struct pico_device_ppp *ppp) 967{ 968 uint8_t reject[64]; 969 uint8_t *p = ppp->pkt + sizeof(struct pico_lcp_hdr); 970 struct pico_lcp_hdr *lcpreq = (struct pico_lcp_hdr *)ppp->pkt; 971 struct pico_lcp_hdr *lcprej = (struct pico_lcp_hdr *)(reject + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 972 uint8_t *dst_opts = reject + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr); 973 uint32_t dstopts_len = 0; 974 ppp_dbg("CONF_NACK: rej = %04X\n", ppp->rej); 975 while (p < (ppp->pkt + ppp->len)) { 976 uint8_t i = 0; 977 if ((1u << p[0]) & ppp->rej || (p[0] > 8u)) { /* Reject anything we dont support or with option id >8 */ 978 ppp_dbg("rejecting option %d -- ", p[0]); 979 dst_opts[dstopts_len++] = p[0]; 980 981 ppp_dbg("len: %d -- ", p[1]); 982 dst_opts[dstopts_len++] = p[1]; 983 984 ppp_dbg("data: "); 985 for(i = 0; i < p[1] - 2u; i++) { /* length includes type, length and data fields */ 986 dst_opts[dstopts_len++] = p[2 + i]; 987 ppp_dbg("%02X ", p[2 + i]); 988 } 989 ppp_dbg("\n"); 990 } 991 992 p += p[1]; 993 } 994 lcprej->code = PICO_CONF_REJ; 995 lcprej->id = lcpreq->id; 996 lcprej->len = short_be((uint16_t)(dstopts_len + sizeof(struct pico_lcp_hdr))); 997 998 ppp_dbg("Sending LCP CONF REJ\n"); 999#ifdef PPP_DEBUG 1000 lcp_optflags_print(ppp, dst_opts, dstopts_len); 1001#endif 1002 1003 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, reject, 1004 (uint32_t)(PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 1005 sizeof(struct pico_lcp_hdr) + /* LCP HDR */ 1006 dstopts_len + /* Actual options size */ 1007 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1008 1u) /* STOP Byte */ 1009 ); 1010} 1011 1012static void lcp_process_in(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1013{ 1014 uint16_t optflags; 1015 if (!ppp) 1016 return; 1017 1018 if (pkt[0] == PICO_CONF_REQ) { 1019 uint16_t rejected = 0; 1020 ppp_dbg("Received LCP CONF REQ\n"); 1021 optflags = lcp_optflags(ppp, pkt, len, 1u); 1022 rejected = (uint16_t)(optflags & (~ppp->lcpopt_local)); 1023 ppp->pkt = pkt; 1024 ppp->len = len; 1025 ppp->rej = rejected; 1026 if (rejected) { 1027 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RCR_NEG); 1028 } else { 1029 ppp->lcpopt_peer = optflags; 1030 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RCR_POS); 1031 } 1032 1033 return; 1034 } 1035 1036 if (pkt[0] == PICO_CONF_ACK) { 1037 ppp_dbg("Received LCP CONF ACK\nOptflags: %04x\n", lcp_optflags(NULL, pkt, len, 0u)); 1038 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RCA); 1039 return; 1040 } 1041 1042 if (pkt[0] == PICO_CONF_NAK) { 1043 /* Every instance of the received Configuration Options is recognizable, but some values are not acceptable */ 1044 optflags = lcp_optflags(ppp, pkt, len, 1u); /* We want our options adjusted */ 1045 ppp_dbg("Received LCP CONF NAK - changed optflags: %04X\n", optflags); 1046 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RCN); 1047 return; 1048 } 1049 1050 if (pkt[0] == PICO_CONF_REJ) { 1051 /* Some Configuration Options received in a Configure-Request are not recognizable or are not acceptable for negotiation */ 1052 optflags = lcp_optflags(ppp, pkt, len, 0u); 1053 ppp_dbg("Received LCP CONF REJ - will disable optflags: %04X\n", optflags); 1054 /* Disable the options that are not supported by the peer */ 1055 LCPOPT_UNSET_LOCAL_MASK(ppp, optflags); 1056 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RCN); 1057 return; 1058 } 1059 1060 if (pkt[0] == PICO_CONF_ECHO_REQ) { 1061 ppp_dbg("Received LCP ECHO REQ\n"); 1062 evaluate_lcp_state(ppp, PPP_LCP_EVENT_RXR); 1063 return; 1064 } 1065} 1066 1067static void pap_process_in(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1068{ 1069 struct pico_pap_hdr *p = (struct pico_pap_hdr *)pkt; 1070 (void)len; 1071 if (!p) 1072 return; 1073 1074 if (ppp->auth != 0xc023) 1075 return; 1076 1077 switch(p->code) { 1078 case PAP_AUTH_ACK: 1079 ppp_dbg("PAP: Received Authentication OK!\n"); 1080 evaluate_auth_state(ppp, PPP_AUTH_EVENT_RAA); 1081 break; 1082 case PAP_AUTH_NAK: 1083 ppp_dbg("PAP: Received Authentication Reject!\n"); 1084 evaluate_auth_state(ppp, PPP_AUTH_EVENT_RAN); 1085 break; 1086 1087 default: 1088 ppp_dbg("PAP: Received invalid packet with code %d\n", p->code); 1089 } 1090} 1091 1092 1093static void chap_process_in(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1094{ 1095 struct pico_chap_hdr *ch = (struct pico_chap_hdr *)pkt; 1096 1097 if (!pkt) 1098 return; 1099 1100 if (ppp->auth != 0xc223) 1101 return; 1102 1103 switch(ch->code) { 1104 case CHAP_CHALLENGE: 1105 ppp_dbg("Received CHAP CHALLENGE\n"); 1106 ppp->pkt = pkt; 1107 ppp->len = len; 1108 evaluate_auth_state(ppp, PPP_AUTH_EVENT_RAC); 1109 break; 1110 case CHAP_SUCCESS: 1111 ppp_dbg("Received CHAP SUCCESS\n"); 1112 evaluate_auth_state(ppp, PPP_AUTH_EVENT_RAA); 1113 break; 1114 case CHAP_FAILURE: 1115 ppp_dbg("Received CHAP FAILURE\n"); 1116 evaluate_auth_state(ppp, PPP_AUTH_EVENT_RAN); 1117 break; 1118 } 1119} 1120 1121 1122static void ipcp_send_ack(struct pico_device_ppp *ppp) 1123{ 1124 uint8_t ack[ppp->len + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr) + PPP_FCS_SIZE + 1]; 1125 struct pico_ipcp_hdr *ack_hdr = (struct pico_ipcp_hdr *) (ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 1126 struct pico_ipcp_hdr *ipcpreq = (struct pico_ipcp_hdr *)ppp->pkt; 1127 memcpy(ack + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE, ppp->pkt, ppp->len); 1128 ack_hdr->code = PICO_CONF_ACK; 1129 ack_hdr->id = ipcpreq->id; 1130 ack_hdr->len = ipcpreq->len; 1131 ppp_dbg("Sending IPCP CONF ACK\n"); 1132 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_IPCP, ack, 1133 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 1134 short_be(ipcpreq->len) + /* Actual options size + hdr (whole ipcp packet) */ 1135 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1136 1 /* STOP Byte */ 1137 ); 1138} 1139 1140static inline uint32_t ipcp_request_options_size(struct pico_device_ppp *ppp) 1141{ 1142 uint32_t size = 0; 1143 1144/* if (ppp->ipcp_ip) */ 1145 size += IPCP_ADDR_LEN; 1146/* if (ppp->ipcp_dns1) */ 1147 size += IPCP_ADDR_LEN; 1148/* if (ppp->ipcp_dns2) */ 1149 size += IPCP_ADDR_LEN; 1150 if (ppp->ipcp_nbns1) 1151 size += IPCP_ADDR_LEN; 1152 1153 if (ppp->ipcp_nbns2) 1154 size += IPCP_ADDR_LEN; 1155 1156 return size; 1157} 1158 1159static int ipcp_request_add_address(uint8_t *dst, uint8_t tag, uint32_t arg) 1160{ 1161 uint32_t addr = long_be(arg); 1162 dst[0] = tag; 1163 dst[1] = IPCP_ADDR_LEN; 1164 dst[2] = (uint8_t)((addr & 0xFF000000u) >> 24); 1165 dst[3] = (uint8_t)((addr & 0x00FF0000u) >> 16); 1166 dst[4] = (uint8_t)((addr & 0x0000FF00u) >> 8); 1167 dst[5] = (addr & 0x000000FFu); 1168 return IPCP_ADDR_LEN; 1169} 1170 1171static void ipcp_request_fill(struct pico_device_ppp *ppp, uint8_t *opts) 1172{ 1173 if (ppp->ipcp_allowed_fields & IPCP_ALLOW_IP) 1174 opts += ipcp_request_add_address(opts, IPCP_OPT_IP, ppp->ipcp_ip); 1175 1176 if (ppp->ipcp_allowed_fields & IPCP_ALLOW_DNS1) 1177 opts += ipcp_request_add_address(opts, IPCP_OPT_DNS1, ppp->ipcp_dns1); 1178 1179 if (ppp->ipcp_allowed_fields & IPCP_ALLOW_DNS2) 1180 opts += ipcp_request_add_address(opts, IPCP_OPT_DNS2, ppp->ipcp_dns2); 1181 1182 if ((ppp->ipcp_allowed_fields & IPCP_ALLOW_NBNS1) && (ppp->ipcp_nbns1)) 1183 opts += ipcp_request_add_address(opts, IPCP_OPT_NBNS1, ppp->ipcp_nbns1); 1184 1185 if ((ppp->ipcp_allowed_fields & IPCP_ALLOW_NBNS2) && (ppp->ipcp_nbns2)) 1186 opts += ipcp_request_add_address(opts, IPCP_OPT_NBNS2, ppp->ipcp_nbns2); 1187} 1188 1189static void ipcp_send_req(struct pico_device_ppp *ppp) 1190{ 1191 uint8_t ipcp_req[PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_ipcp_hdr) + ipcp_request_options_size(ppp) + PPP_FCS_SIZE + 1]; 1192 uint32_t prefix = PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE; 1193 struct pico_ipcp_hdr *ih = (struct pico_ipcp_hdr *) (ipcp_req + prefix); 1194 uint8_t *p = ipcp_req + prefix + sizeof(struct pico_ipcp_hdr); 1195 uint16_t len = (uint16_t)(ipcp_request_options_size(ppp) + sizeof(struct pico_ipcp_hdr)); 1196 1197 ih->id = ppp->frame_id++; 1198 ih->code = PICO_CONF_REQ; 1199 ih->len = short_be(len); 1200 ipcp_request_fill(ppp, p); 1201 1202 ppp_dbg("Sending IPCP CONF REQ, ipcp size = %d\n", len); 1203 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_IPCP, 1204 ipcp_req, /* Start of PPP packet */ 1205 (uint32_t)(prefix + /* PPP Header, etc. */ 1206 (uint32_t)len + /* IPCP Header + options */ 1207 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1208 1u) /* STOP Byte */ 1209 ); 1210} 1211 1212static void ipcp_reject_vj(struct pico_device_ppp *ppp, uint8_t *comp_req) 1213{ 1214 uint8_t ipcp_req[PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_ipcp_hdr) + IPCP_VJ_LEN + PPP_FCS_SIZE + 1]; 1215 uint32_t prefix = PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE; 1216 struct pico_ipcp_hdr *ih = (struct pico_ipcp_hdr *) (ipcp_req + prefix); 1217 uint8_t *p = ipcp_req + prefix + sizeof(struct pico_ipcp_hdr); 1218 uint32_t i; 1219 1220 ih->id = ppp->frame_id++; 1221 ih->code = PICO_CONF_REQ; 1222 ih->len = short_be(IPCP_VJ_LEN + sizeof(struct pico_ipcp_hdr)); 1223 for(i = 0; i < IPCP_OPT_VJ; i++) 1224 p[i] = comp_req[i + sizeof(struct pico_ipcp_hdr)]; 1225 ppp_dbg("Sending IPCP CONF REJ VJ\n"); 1226 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_IPCP, 1227 ipcp_req, /* Start of PPP packet */ 1228 (uint32_t)(prefix + /* PPP Header, etc. */ 1229 sizeof(struct pico_ipcp_hdr) + /* LCP HDR */ 1230 IPCP_VJ_LEN + /* Actual options size */ 1231 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1232 1u) /* STOP Byte */ 1233 ); 1234} 1235 1236static void ppp_ipv4_conf(struct pico_device_ppp *ppp) 1237{ 1238 struct pico_ip4 ip; 1239 struct pico_ip4 nm; 1240 struct pico_ip4 dns1; 1241 struct pico_ip4 dns2; 1242 struct pico_ip4 any = { 1243 0 1244 }; 1245 ip.addr = ppp->ipcp_ip; 1246 nm.addr = 0xFFFFFF00; 1247 pico_ipv4_link_add(&ppp->dev, ip, nm); 1248 pico_ipv4_route_add(any, any, any, 1, pico_ipv4_link_by_dev(&ppp->dev)); 1249 1250 dns1.addr = ppp->ipcp_dns1; 1251 dns2.addr = ppp->ipcp_dns2; 1252 pico_dns_client_nameserver(&dns1, PICO_DNS_NS_ADD); 1253 pico_dns_client_nameserver(&dns2, PICO_DNS_NS_ADD); 1254} 1255 1256 1257static void ipcp_process_in(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1258{ 1259 struct pico_ipcp_hdr *ih = (struct pico_ipcp_hdr *)pkt; 1260 uint8_t *p = pkt + sizeof(struct pico_ipcp_hdr); 1261 int reject = 0; 1262 while (p < pkt + len) { 1263 if (p[0] == IPCP_OPT_VJ) { 1264 reject++; 1265 } 1266 1267 if (p[0] == IPCP_OPT_IP) { 1268 if (ih->code != PICO_CONF_REJ) 1269 ppp->ipcp_ip = long_be((uint32_t)((p[2] << 24) + (p[3] << 16) + (p[4] << 8) + p[5])); 1270 else { 1271 ppp->ipcp_allowed_fields &= (~IPCP_ALLOW_IP); 1272 ppp->ipcp_ip = 0; 1273 } 1274 } 1275 1276 if (p[0] == IPCP_OPT_DNS1) { 1277 if (ih->code != PICO_CONF_REJ) 1278 ppp->ipcp_dns1 = long_be((uint32_t)((p[2] << 24) + (p[3] << 16) + (p[4] << 8) + p[5])); 1279 else { 1280 ppp->ipcp_allowed_fields &= (~IPCP_ALLOW_DNS1); 1281 ppp->ipcp_dns1 = 0; 1282 } 1283 } 1284 1285 if (p[0] == IPCP_OPT_NBNS1) { 1286 if (ih->code != PICO_CONF_REJ) 1287 ppp->ipcp_nbns1 = long_be((uint32_t)((p[2] << 24) + (p[3] << 16) + (p[4] << 8) + p[5])); 1288 else { 1289 ppp->ipcp_allowed_fields &= (~IPCP_ALLOW_NBNS1); 1290 ppp->ipcp_nbns1 = 0; 1291 } 1292 } 1293 1294 if (p[0] == IPCP_OPT_DNS2) { 1295 if (ih->code != PICO_CONF_REJ) 1296 ppp->ipcp_dns2 = long_be((uint32_t)((p[2] << 24) + (p[3] << 16) + (p[4] << 8) + p[5])); 1297 else { 1298 ppp->ipcp_allowed_fields &= (~IPCP_ALLOW_DNS2); 1299 ppp->ipcp_dns2 = 0; 1300 } 1301 } 1302 1303 if (p[0] == IPCP_OPT_NBNS2) { 1304 if (ih->code != PICO_CONF_REJ) 1305 ppp->ipcp_nbns2 = long_be((uint32_t)((p[2] << 24) + (p[3] << 16) + (p[4] << 8) + p[5])); 1306 else { 1307 ppp->ipcp_allowed_fields &= (~IPCP_ALLOW_NBNS2); 1308 ppp->ipcp_nbns2 = 0; 1309 } 1310 } 1311 1312 p += p[1]; 1313 } 1314 if (reject) { 1315 ipcp_reject_vj(ppp, p); 1316 return; 1317 } 1318 1319 ppp->pkt = pkt; 1320 ppp->len = len; 1321 1322 switch(ih->code) { 1323 case PICO_CONF_ACK: 1324 ppp_dbg("Received IPCP CONF ACK\n"); 1325 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_RCA); 1326 break; 1327 case PICO_CONF_REQ: 1328 ppp_dbg("Received IPCP CONF REQ\n"); 1329 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_RCR_POS); 1330 break; 1331 case PICO_CONF_NAK: 1332 ppp_dbg("Received IPCP CONF NAK\n"); 1333 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_RCN); 1334 break; 1335 case PICO_CONF_REJ: 1336 ppp_dbg("Received IPCP CONF REJ\n"); 1337 1338 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_RCN); 1339 break; 1340 } 1341} 1342 1343static void ipcp6_process_in(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1344{ 1345 IGNORE_PARAMETER(ppp); 1346 IGNORE_PARAMETER(pkt); 1347 IGNORE_PARAMETER(len); 1348} 1349 1350static void ppp_process_packet_payload(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1351{ 1352 if (pkt[0] == 0xc0) { 1353 /* Link control packet */ 1354 if (pkt[1] == 0x21) { 1355 /* LCP */ 1356 lcp_process_in(ppp, pkt + 2, len - 2); 1357 } 1358 1359 if (pkt[1] == 0x23) { 1360 /* PAP */ 1361 pap_process_in(ppp, pkt + 2, len - 2); 1362 } 1363 1364 return; 1365 } 1366 1367 if ((pkt[0] == 0xc2) && (pkt[1] == 0x23)) { 1368 /* CHAP */ 1369 chap_process_in(ppp, pkt + 2, len - 2); 1370 return; 1371 } 1372 1373 if (pkt[0] == 0x80) { 1374 /* IP assignment (IPCP/IPCP6) */ 1375 if (pkt[1] == 0x21) { 1376 /* IPCP */ 1377 ipcp_process_in(ppp, pkt + 2, len - 2); 1378 } 1379 1380 if (pkt[1] == 0x57) { 1381 /* IPCP6 */ 1382 ipcp6_process_in(ppp, pkt + 2, len - 2); 1383 } 1384 1385 return; 1386 } 1387 1388 if (pkt[0] == 0x00) { 1389 /* Uncompressed protocol: leading zero. */ 1390 pkt++; 1391 len--; 1392 } 1393 1394 if ((pkt[0] == 0x21) || (pkt[0] == 0x57)) { 1395 /* IPv4 /v6 Data */ 1396 pico_stack_recv(&ppp->dev, pkt + 1, len - 1); 1397 return; 1398 } 1399 1400 ppp_dbg("PPP: Unrecognized protocol %02x%02x\n", pkt[0], pkt[1]); 1401} 1402 1403static void ppp_process_packet(struct pico_device_ppp *ppp, uint8_t *pkt, uint32_t len) 1404{ 1405 /* Verify incoming FCS */ 1406 if (ppp_fcs_verify(pkt, len) != 0) 1407 return; 1408 1409 /* Remove trailing FCS */ 1410 len -= 2; 1411 1412 /* Remove ADDR/CTRL, then process */ 1413 if ((pkt[0] == PPPF_ADDR) && (pkt[1] == PPPF_CTRL)) { 1414 pkt += 2; 1415 len -= 2; 1416 } 1417 1418 ppp_process_packet_payload(ppp, pkt, len); 1419 1420} 1421 1422static void ppp_recv_data(struct pico_device_ppp *ppp, void *data, uint32_t len) 1423{ 1424 uint8_t *pkt = (uint8_t *)data; 1425 1426#ifdef PPP_DEBUG 1427 uint32_t idx; 1428 if (len > 0) { 1429 ppp_dbg("PPP <<<<< "); 1430 for(idx = 0; idx < len; idx++) { 1431 ppp_dbg(" %02x", ((uint8_t *)data)[idx]); 1432 } 1433 ppp_dbg("\n"); 1434 } 1435 1436#endif 1437 1438 ppp_process_packet(ppp, pkt, len); 1439} 1440 1441static void lcp_this_layer_up(struct pico_device_ppp *ppp) 1442{ 1443 ppp_dbg("PPP: LCP up.\n"); 1444 1445 switch (ppp->auth) { 1446 case 0x0000: 1447 evaluate_auth_state(ppp, PPP_AUTH_EVENT_UP_NONE); 1448 break; 1449 case 0xc023: 1450 evaluate_auth_state(ppp, PPP_AUTH_EVENT_UP_PAP); 1451 break; 1452 case 0xc223: 1453 evaluate_auth_state(ppp, PPP_AUTH_EVENT_UP_CHAP); 1454 break; 1455 default: 1456 ppp_dbg("PPP: Unknown authentication protocol.\n"); 1457 break; 1458 } 1459} 1460 1461static void lcp_this_layer_down(struct pico_device_ppp *ppp) 1462{ 1463 ppp_dbg("PPP: LCP down.\n"); 1464 evaluate_auth_state(ppp, PPP_AUTH_EVENT_DOWN); 1465} 1466 1467static void lcp_this_layer_started(struct pico_device_ppp *ppp) 1468{ 1469 ppp_dbg("PPP: LCP started.\n"); 1470 evaluate_modem_state(ppp, PPP_MODEM_EVENT_START); 1471} 1472 1473static void lcp_this_layer_finished(struct pico_device_ppp *ppp) 1474{ 1475 ppp_dbg("PPP: LCP finished.\n"); 1476 evaluate_modem_state(ppp, PPP_MODEM_EVENT_STOP); 1477} 1478 1479static void lcp_initialize_restart_count(struct pico_device_ppp *ppp) 1480{ 1481 lcp_timer_start(ppp, PPP_TIMER_ON_LCPREQ); 1482} 1483 1484static void lcp_send_code_reject(struct pico_device_ppp *ppp) 1485{ 1486 IGNORE_PARAMETER(ppp); 1487} 1488 1489static void lcp_send_echo_reply(struct pico_device_ppp *ppp) 1490{ 1491 uint8_t reply[ppp->len + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_lcp_hdr) + PPP_FCS_SIZE + 1]; 1492 struct pico_lcp_hdr *reply_hdr = (struct pico_lcp_hdr *) (reply + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 1493 struct pico_lcp_hdr *lcpreq = (struct pico_lcp_hdr *)ppp->pkt; 1494 memcpy(reply + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE, ppp->pkt, ppp->len); 1495 reply_hdr->code = PICO_CONF_ECHO_REP; 1496 reply_hdr->id = lcpreq->id; 1497 reply_hdr->len = lcpreq->len; 1498 ppp_dbg("Sending LCP ECHO REPLY\n"); 1499 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_LCP, reply, 1500 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 1501 short_be(lcpreq->len) + /* Actual options size + hdr (whole lcp packet) */ 1502 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1503 1 /* STOP Byte */ 1504 ); 1505} 1506 1507static const struct pico_ppp_fsm ppp_lcp_fsm[PPP_LCP_STATE_MAX][PPP_LCP_EVENT_MAX] = { 1508 [PPP_LCP_STATE_INITIAL] = { 1509 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_CLOSED, {} }, 1510 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_INITIAL, {} }, 1511 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_STARTING, { lcp_this_layer_started } }, 1512 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_INITIAL, {} }, 1513 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_INITIAL, {} }, 1514 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_INITIAL, {} }, 1515 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_INITIAL, {} }, 1516 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_INITIAL, {} }, 1517 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_INITIAL, {} }, 1518 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_INITIAL, {} }, 1519 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_INITIAL, {} }, 1520 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_INITIAL, {} }, 1521 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_INITIAL, {} }, 1522 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_INITIAL, {} }, 1523 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_INITIAL, {} }, 1524 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_INITIAL, {} } 1525 }, 1526 [PPP_LCP_STATE_STARTING] = { 1527 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, 1528 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {} }, 1529 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_STARTING, {} }, 1530 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_INITIAL, { lcp_this_layer_finished } }, 1531 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_STARTING, {} }, 1532 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STARTING, {} }, 1533 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_STARTING, {} }, 1534 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_STARTING, {} }, 1535 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_STARTING, {} }, 1536 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_STARTING, {} }, 1537 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_STARTING, {} }, 1538 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_STARTING, {} }, 1539 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_STARTING, {} }, 1540 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_STARTING, {} }, 1541 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STARTING, {} }, 1542 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_STARTING, {} } 1543 }, 1544 [PPP_LCP_STATE_CLOSED] = { 1545 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_CLOSED, {} }, 1546 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_INITIAL, {} }, 1547 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request} }, 1548 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSED, {} }, 1549 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_CLOSED, {} }, 1550 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_CLOSED, {} }, 1551 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_CLOSED, { lcp_send_terminate_ack } }, 1552 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_CLOSED, { lcp_send_terminate_ack } }, 1553 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_CLOSED, { lcp_send_terminate_ack } }, 1554 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_CLOSED, { lcp_send_terminate_ack } }, 1555 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_CLOSED, { lcp_send_terminate_ack } }, 1556 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_CLOSED, {} }, 1557 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_CLOSED, { lcp_send_code_reject } }, 1558 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_CLOSED, {} }, 1559 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_CLOSED, { lcp_this_layer_finished } }, 1560 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_CLOSED, {} } 1561 }, 1562 [PPP_LCP_STATE_STOPPED] = { 1563 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_STOPPED, {} }, 1564 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, { lcp_this_layer_started } }, 1565 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_STOPPED, {}}, 1566 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSED, {}}, 1567 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_STOPPED, {} }, 1568 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STOPPED, {} }, 1569 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_ACK_SENT, 1570 { lcp_send_configure_request, lcp_send_configure_ack}}, 1571 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_REQ_SENT, 1572 { lcp_send_configure_request, lcp_send_configure_nack}}, 1573 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_STOPPED, { lcp_send_terminate_ack } }, 1574 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_STOPPED, { lcp_send_terminate_ack } }, 1575 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_STOPPED, { lcp_send_terminate_ack } }, 1576 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_STOPPED, {} }, 1577 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_STOPPED, { lcp_send_code_reject } }, 1578 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_STOPPED, {} }, 1579 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1580 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_STOPPED, {} } 1581 }, 1582 [PPP_LCP_STATE_CLOSING] = { 1583 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_CLOSING, {} }, 1584 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_INITIAL, {} }, 1585 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_STOPPING, {} }, 1586 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, {} }, 1587 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_CLOSING, { lcp_send_terminate_request } }, 1588 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_CLOSED, { lcp_this_layer_finished } }, 1589 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_CLOSING, {} }, 1590 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_CLOSING, {} }, 1591 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_CLOSING, {} }, 1592 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_CLOSING, {} }, 1593 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_CLOSING, { lcp_send_terminate_ack } }, 1594 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_CLOSED, { lcp_this_layer_finished } }, 1595 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_CLOSING, { lcp_send_code_reject } }, 1596 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_CLOSING, {} }, 1597 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_CLOSED, { lcp_this_layer_finished } }, 1598 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_CLOSING, {} } 1599 }, 1600 [PPP_LCP_STATE_STOPPING] = { 1601 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_STOPPING, {} }, 1602 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {} }, 1603 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_STOPPING, {} }, 1604 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, {} }, 1605 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_STOPPING, { lcp_send_terminate_request } }, 1606 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1607 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_STOPPING, {} }, 1608 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_STOPPING, {} }, 1609 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_STOPPING, {} }, 1610 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_STOPPING, {} }, 1611 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_STOPPING, { lcp_send_terminate_ack } }, 1612 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1613 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_STOPPING, { lcp_send_code_reject } }, 1614 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_STOPPING, {} }, 1615 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1616 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_STOPPING, {} } 1617 }, 1618 [PPP_LCP_STATE_REQ_SENT] = { 1619 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_REQ_SENT, {} }, 1620 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {} }, 1621 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_REQ_SENT, {} }, 1622 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, { lcp_send_terminate_request } }, 1623 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, 1624 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1625 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_ACK_SENT, { lcp_send_configure_ack } }, 1626 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_nack } }, 1627 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_ACK_RCVD, { lcp_initialize_restart_count } }, 1628 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request} }, 1629 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_terminate_ack } }, 1630 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_REQ_SENT, {} }, 1631 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_code_reject } }, 1632 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_REQ_SENT, {} }, 1633 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1634 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_REQ_SENT, {} } 1635 }, 1636 [PPP_LCP_STATE_ACK_RCVD] = { 1637 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_ACK_RCVD, {} }, 1638 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {} }, 1639 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_ACK_RCVD, {} }, 1640 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, { lcp_send_terminate_request} }, 1641 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, 1642 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1643 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_OPENED, { lcp_send_configure_ack, lcp_this_layer_up} }, 1644 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_ACK_RCVD, { lcp_send_configure_nack } }, 1645 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, 1646 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_request } }, 1647 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_terminate_ack } }, 1648 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_REQ_SENT, {} }, 1649 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_ACK_RCVD, { lcp_send_code_reject } }, 1650 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_REQ_SENT, {} }, 1651 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1652 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_ACK_RCVD, {} } 1653 }, 1654 [PPP_LCP_STATE_ACK_SENT] = { 1655 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_ACK_SENT, {} }, 1656 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {} }, 1657 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_ACK_SENT, {} }, 1658 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, { lcp_send_terminate_request} }, 1659 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_ACK_SENT, { lcp_send_configure_request } }, 1660 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1661 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_ACK_SENT, { lcp_send_configure_ack } }, 1662 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_configure_nack } }, 1663 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_OPENED, { lcp_this_layer_up} }, 1664 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_ACK_SENT, { lcp_send_configure_request} }, 1665 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_REQ_SENT, { lcp_send_terminate_ack } }, 1666 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_ACK_SENT, {} }, 1667 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_ACK_SENT, { lcp_send_code_reject } }, 1668 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_ACK_SENT, {} }, 1669 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPED, { lcp_this_layer_finished } }, 1670 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_ACK_SENT, {} } 1671 }, 1672 [PPP_LCP_STATE_OPENED] = { 1673 [PPP_LCP_EVENT_UP] = { PPP_LCP_STATE_OPENED, {} }, 1674 [PPP_LCP_EVENT_DOWN] = { PPP_LCP_STATE_STARTING, {lcp_this_layer_down } }, 1675 [PPP_LCP_EVENT_OPEN] = { PPP_LCP_STATE_OPENED, {} }, 1676 [PPP_LCP_EVENT_CLOSE] = { PPP_LCP_STATE_CLOSING, 1677 { lcp_this_layer_down, lcp_send_terminate_request }}, 1678 [PPP_LCP_EVENT_TO_POS] = { PPP_LCP_STATE_OPENED, {} }, 1679 [PPP_LCP_EVENT_TO_NEG] = { PPP_LCP_STATE_OPENED, {} }, 1680 [PPP_LCP_EVENT_RCR_POS] = { PPP_LCP_STATE_ACK_SENT, 1681 { lcp_this_layer_down, lcp_send_terminate_request, lcp_send_configure_ack }}, 1682 [PPP_LCP_EVENT_RCR_NEG] = { PPP_LCP_STATE_REQ_SENT, 1683 { lcp_this_layer_down, lcp_send_configure_request, lcp_send_configure_nack }}, 1684 [PPP_LCP_EVENT_RCA] = { PPP_LCP_STATE_REQ_SENT, { lcp_this_layer_down, lcp_send_terminate_request } }, 1685 [PPP_LCP_EVENT_RCN] = { PPP_LCP_STATE_REQ_SENT, { lcp_this_layer_down, lcp_send_terminate_request } }, 1686 [PPP_LCP_EVENT_RTR] = { PPP_LCP_STATE_STOPPING, { lcp_this_layer_down, lcp_zero_restart_count, lcp_send_terminate_ack} }, 1687 [PPP_LCP_EVENT_RTA] = { PPP_LCP_STATE_REQ_SENT, { lcp_this_layer_down, lcp_send_terminate_request} }, 1688 [PPP_LCP_EVENT_RUC] = { PPP_LCP_STATE_OPENED, { lcp_send_code_reject } }, 1689 [PPP_LCP_EVENT_RXJ_POS] = { PPP_LCP_STATE_OPENED, { } }, 1690 [PPP_LCP_EVENT_RXJ_NEG] = { PPP_LCP_STATE_STOPPING, 1691 {lcp_this_layer_down, lcp_send_terminate_request}}, 1692 [PPP_LCP_EVENT_RXR] = { PPP_LCP_STATE_OPENED, { lcp_send_echo_reply} } 1693 } 1694}; 1695 1696static void evaluate_lcp_state(struct pico_device_ppp *ppp, enum ppp_lcp_event event) 1697{ 1698 const struct pico_ppp_fsm *fsm, *next_fsm_to; 1699 int i; 1700 if (!ppp) 1701 return; 1702 1703 if (mock_lcp_state) { 1704 mock_lcp_state(ppp, event); 1705 return; 1706 } 1707 1708 fsm = &ppp_lcp_fsm[ppp->lcp_state][event]; 1709 ppp->lcp_state = (enum ppp_lcp_state)fsm->next_state; 1710 /* RFC1661: The states in which the Restart timer is running are identifiable by 1711 * the presence of TO events. 1712 */ 1713 next_fsm_to = &ppp_lcp_fsm[ppp->lcp_state][PPP_LCP_EVENT_TO_POS]; 1714 if (!next_fsm_to->event_handler[0]) { 1715 /* The Restart timer is stopped when transitioning 1716 * from any state where the timer is running to a state where the timer 1717 * is not running. 1718 */ 1719 lcp_timer_stop(ppp, PPP_TIMER_ON_LCPREQ); 1720 lcp_timer_stop(ppp, PPP_TIMER_ON_LCPTERM); 1721 } 1722 1723 for (i = 0; i < PPP_FSM_MAX_ACTIONS; i++) { 1724 if (fsm->event_handler[i]) 1725 fsm->event_handler[i](ppp); 1726 } 1727} 1728 1729static void auth(struct pico_device_ppp *ppp) 1730{ 1731 ppp_dbg("PPP: Authenticated.\n"); 1732 ppp->ipcp_allowed_fields = 0xFFFF; 1733 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_UP); 1734} 1735 1736static void deauth(struct pico_device_ppp *ppp) 1737{ 1738 ppp_dbg("PPP: De-authenticated.\n"); 1739 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_DOWN); 1740} 1741 1742static void auth_abort(struct pico_device_ppp *ppp) 1743{ 1744 ppp_dbg("PPP: Authentication failed!\n"); 1745 ppp->timer_on = (uint8_t) (ppp->timer_on & (~PPP_TIMER_ON_AUTH)); 1746 evaluate_lcp_state(ppp, PPP_LCP_EVENT_CLOSE); 1747 1748} 1749 1750static void auth_req(struct pico_device_ppp *ppp) 1751{ 1752 uint16_t ppp_usr_len = 0; 1753 uint16_t ppp_pwd_len = 0; 1754 uint8_t *req = NULL, *p; 1755 struct pico_pap_hdr *hdr; 1756 uint16_t pap_len = 0; 1757 uint8_t field_len = 0; 1758 ppp_usr_len = (uint16_t)strlen(ppp->username); 1759 ppp_pwd_len = (uint16_t)strlen(ppp->password); 1760 1761 pap_len = (uint16_t)(sizeof(struct pico_pap_hdr) + 1u + 1u + ppp_usr_len + ppp_pwd_len); 1762 1763 req = PICO_ZALLOC(PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + pap_len + PPP_FCS_SIZE + 1); 1764 if (!req) 1765 return; 1766 1767 hdr = (struct pico_pap_hdr *) (req + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 1768 1769 hdr->code = PAP_AUTH_REQ; 1770 hdr->id = ppp->frame_id++; 1771 hdr->len = short_be(pap_len); 1772 1773 p = req + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_pap_hdr); 1774 1775 /* Populate authentication domain */ 1776 field_len = (uint8_t)(ppp_usr_len & 0xFF); 1777 *p = field_len; 1778 ++p; 1779 if (ppp_usr_len > 0) { 1780 memcpy(p, ppp->username, ppp_usr_len); 1781 p += ppp_usr_len; 1782 } 1783 1784 /* Populate authentication password */ 1785 field_len = (uint8_t)(ppp_pwd_len & 0xFF); 1786 *p = field_len; 1787 ++p; 1788 if (ppp_pwd_len > 0) { 1789 memcpy(p, ppp->password, ppp_pwd_len); 1790 p += ppp_pwd_len; 1791 } 1792 1793 ppp_dbg("PAP: Sending authentication request.\n"); 1794 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_PAP, 1795 req, /* Start of PPP packet */ 1796 (uint32_t)( 1797 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 1798 pap_len + /* Authentication packet len */ 1799 PPP_FCS_SIZE + /* FCS */ 1800 1) /* STOP Byte */ 1801 ); 1802 PICO_FREE(req); 1803} 1804 1805static void auth_rsp(struct pico_device_ppp *ppp) 1806{ 1807 struct pico_chap_hdr *ch = (struct pico_chap_hdr *)ppp->pkt; 1808 uint8_t resp[PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_chap_hdr) + CHAP_MD5_SIZE + PPP_FCS_SIZE + 2]; 1809 struct pico_chap_hdr *rh = (struct pico_chap_hdr *) (resp + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE); 1810 uint8_t *md5resp = resp + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_chap_hdr) + 1; 1811 uint8_t *md5resp_len = resp + PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + sizeof(struct pico_chap_hdr); 1812 uint8_t *challenge; 1813 uint32_t i = 0, pwdlen; 1814 uint8_t *recvd_challenge_len = ppp->pkt + sizeof(struct pico_chap_hdr); 1815 uint8_t *recvd_challenge = recvd_challenge_len + 1; 1816 size_t challenge_size = CHALLENGE_SIZE(ppp, ch); 1817 1818 challenge = PICO_ZALLOC(challenge_size); 1819 1820 if (!challenge) 1821 return; 1822 1823 1824 pwdlen = (uint32_t)strlen(ppp->password); 1825 challenge[i++] = ch->id; 1826 memcpy(challenge + i, ppp->password, pwdlen); 1827 i += pwdlen; 1828 memcpy(challenge + i, recvd_challenge, *recvd_challenge_len); 1829 i += *recvd_challenge_len; 1830 pico_md5sum(md5resp, challenge, i); 1831 PICO_FREE(challenge); 1832 rh->id = ch->id; 1833 rh->code = CHAP_RESPONSE; 1834 rh->len = short_be(CHAP_MD5_SIZE + sizeof(struct pico_chap_hdr) + 1); 1835 *md5resp_len = CHAP_MD5_SIZE; 1836 ppp_dbg("Sending CHAP RESPONSE, \n"); 1837 pico_ppp_ctl_send(&ppp->dev, PPP_PROTO_CHAP, 1838 resp, /* Start of PPP packet */ 1839 (uint32_t)( 1840 PPP_HDR_SIZE + PPP_PROTO_SLOT_SIZE + /* PPP Header, etc. */ 1841 sizeof(struct pico_chap_hdr) + /* CHAP HDR */ 1842 1 + /* Value length */ 1843 CHAP_MD5_SIZE + /* Actual payload size */ 1844 PPP_FCS_SIZE + /* FCS at the end of the frame */ 1845 1) /* STOP Byte */ 1846 ); 1847} 1848 1849static void auth_start_timer(struct pico_device_ppp *ppp) 1850{ 1851 ppp->timer_on = ppp->timer_on | PPP_TIMER_ON_AUTH; 1852 ppp->timer_val = PICO_PPP_DEFAULT_TIMER; 1853} 1854 1855static const struct pico_ppp_fsm ppp_auth_fsm[PPP_AUTH_STATE_MAX][PPP_AUTH_EVENT_MAX] = { 1856 [PPP_AUTH_STATE_INITIAL] = { 1857 [PPP_AUTH_EVENT_UP_NONE] = { PPP_AUTH_STATE_AUTHENTICATED, {auth} }, 1858 [PPP_AUTH_EVENT_UP_PAP] = { PPP_AUTH_STATE_REQ_SENT, {auth_req, auth_start_timer} }, 1859 [PPP_AUTH_EVENT_UP_CHAP] = { PPP_AUTH_STATE_STARTING, {} }, 1860 [PPP_AUTH_EVENT_DOWN] = { PPP_AUTH_STATE_INITIAL, {} }, 1861 [PPP_AUTH_EVENT_RAC] = { PPP_AUTH_STATE_INITIAL, {} }, 1862 [PPP_AUTH_EVENT_RAA] = { PPP_AUTH_STATE_INITIAL, {} }, 1863 [PPP_AUTH_EVENT_RAN] = { PPP_AUTH_STATE_INITIAL, {auth_abort} }, 1864 [PPP_AUTH_EVENT_TO] = { PPP_AUTH_STATE_INITIAL, {} } 1865 }, 1866 [PPP_AUTH_STATE_STARTING] = { 1867 [PPP_AUTH_EVENT_UP_NONE] = { PPP_AUTH_STATE_STARTING, {} }, 1868 [PPP_AUTH_EVENT_UP_PAP] = { PPP_AUTH_STATE_STARTING, {} }, 1869 [PPP_AUTH_EVENT_UP_CHAP] = { PPP_AUTH_STATE_STARTING, {} }, 1870 [PPP_AUTH_EVENT_DOWN] = { PPP_AUTH_STATE_INITIAL, {deauth} }, 1871 [PPP_AUTH_EVENT_RAC] = { PPP_AUTH_STATE_RSP_SENT, {auth_rsp, auth_start_timer} }, 1872 [PPP_AUTH_EVENT_RAA] = { PPP_AUTH_STATE_STARTING, {auth_start_timer} }, 1873 [PPP_AUTH_EVENT_RAN] = { PPP_AUTH_STATE_STARTING, {auth_abort} }, 1874 [PPP_AUTH_EVENT_TO] = { PPP_AUTH_STATE_INITIAL, {auth_req, auth_start_timer} } 1875 }, 1876 [PPP_AUTH_STATE_RSP_SENT] = { 1877 [PPP_AUTH_EVENT_UP_NONE] = { PPP_AUTH_STATE_RSP_SENT, {} }, 1878 [PPP_AUTH_EVENT_UP_PAP] = { PPP_AUTH_STATE_RSP_SENT, {} }, 1879 [PPP_AUTH_EVENT_UP_CHAP] = { PPP_AUTH_STATE_RSP_SENT, {} }, 1880 [PPP_AUTH_EVENT_DOWN] = { PPP_AUTH_STATE_INITIAL, {deauth} }, 1881 [PPP_AUTH_EVENT_RAC] = { PPP_AUTH_STATE_RSP_SENT, {auth_rsp, auth_start_timer} }, 1882 [PPP_AUTH_EVENT_RAA] = { PPP_AUTH_STATE_AUTHENTICATED, {auth} }, 1883 [PPP_AUTH_EVENT_RAN] = { PPP_AUTH_STATE_STARTING, {auth_abort} }, 1884 [PPP_AUTH_EVENT_TO] = { PPP_AUTH_STATE_STARTING, {auth_start_timer} } 1885 }, 1886 [PPP_AUTH_STATE_REQ_SENT] = { 1887 [PPP_AUTH_EVENT_UP_NONE] = { PPP_AUTH_STATE_REQ_SENT, {} }, 1888 [PPP_AUTH_EVENT_UP_PAP] = { PPP_AUTH_STATE_REQ_SENT, {} }, 1889 [PPP_AUTH_EVENT_UP_CHAP] = { PPP_AUTH_STATE_REQ_SENT, {} }, 1890 [PPP_AUTH_EVENT_DOWN] = { PPP_AUTH_STATE_INITIAL, {deauth} }, 1891 [PPP_AUTH_EVENT_RAC] = { PPP_AUTH_STATE_REQ_SENT, {} }, 1892 [PPP_AUTH_EVENT_RAA] = { PPP_AUTH_STATE_AUTHENTICATED, {auth} }, 1893 [PPP_AUTH_EVENT_RAN] = { PPP_AUTH_STATE_REQ_SENT, {auth_abort} }, 1894 [PPP_AUTH_EVENT_TO] = { PPP_AUTH_STATE_REQ_SENT, {auth_req, auth_start_timer} } 1895 }, 1896 [PPP_AUTH_STATE_AUTHENTICATED] = { 1897 [PPP_AUTH_EVENT_UP_NONE] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1898 [PPP_AUTH_EVENT_UP_PAP] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1899 [PPP_AUTH_EVENT_UP_CHAP] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1900 [PPP_AUTH_EVENT_DOWN] = { PPP_AUTH_STATE_INITIAL, {deauth} }, 1901 [PPP_AUTH_EVENT_RAC] = { PPP_AUTH_STATE_RSP_SENT, {auth_rsp} }, 1902 [PPP_AUTH_EVENT_RAA] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1903 [PPP_AUTH_EVENT_RAN] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1904 [PPP_AUTH_EVENT_TO] = { PPP_AUTH_STATE_AUTHENTICATED, {} }, 1905 } 1906}; 1907 1908static void evaluate_auth_state(struct pico_device_ppp *ppp, enum ppp_auth_event event) 1909{ 1910 const struct pico_ppp_fsm *fsm; 1911 int i; 1912 if (mock_auth_state) { 1913 mock_auth_state(ppp, event); 1914 return; 1915 } 1916 1917 fsm = &ppp_auth_fsm[ppp->auth_state][event]; 1918 1919 ppp->auth_state = (enum ppp_auth_state)fsm->next_state; 1920 for (i = 0; i < PPP_FSM_MAX_ACTIONS; i++) { 1921 if (fsm->event_handler[i]) 1922 fsm->event_handler[i](ppp); 1923 } 1924} 1925 1926static void ipcp_send_nack(struct pico_device_ppp *ppp) 1927{ 1928 IGNORE_PARAMETER(ppp); 1929} 1930 1931static void ipcp_bring_up(struct pico_device_ppp *ppp) 1932{ 1933 ppp_dbg("PPP: IPCP up.\n"); 1934 1935 if (ppp->ipcp_ip) { 1936 char my_ip[16], my_dns[16]; 1937 pico_ipv4_to_string(my_ip, ppp->ipcp_ip); 1938 ppp_dbg("Received IP config %s\n", my_ip); 1939 pico_ipv4_to_string(my_dns, ppp->ipcp_dns1); 1940 ppp_dbg("Received DNS: %s\n", my_dns); 1941 ppp_ipv4_conf(ppp); 1942 } 1943} 1944 1945static void ipcp_bring_down(struct pico_device_ppp *ppp) 1946{ 1947 IGNORE_PARAMETER(ppp); 1948 1949 ppp_dbg("PPP: IPCP down.\n"); 1950} 1951 1952static void ipcp_start_timer(struct pico_device_ppp *ppp) 1953{ 1954 ppp->timer_on = ppp->timer_on | PPP_TIMER_ON_IPCP; 1955 ppp->timer_val = PICO_PPP_DEFAULT_TIMER * PICO_PPP_DEFAULT_MAX_FAILURE; 1956} 1957 1958static const struct pico_ppp_fsm ppp_ipcp_fsm[PPP_IPCP_STATE_MAX][PPP_IPCP_EVENT_MAX] = { 1959 [PPP_IPCP_STATE_INITIAL] = { 1960 [PPP_IPCP_EVENT_UP] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req, ipcp_start_timer} }, 1961 [PPP_IPCP_EVENT_DOWN] = { PPP_IPCP_STATE_INITIAL, {} }, 1962 [PPP_IPCP_EVENT_RCR_POS] = { PPP_IPCP_STATE_INITIAL, {} }, 1963 [PPP_IPCP_EVENT_RCR_NEG] = { PPP_IPCP_STATE_INITIAL, {} }, 1964 [PPP_IPCP_EVENT_RCA] = { PPP_IPCP_STATE_INITIAL, {} }, 1965 [PPP_IPCP_EVENT_RCN] = { PPP_IPCP_STATE_INITIAL, {} }, 1966 [PPP_IPCP_EVENT_TO] = { PPP_IPCP_STATE_INITIAL, {} } 1967 }, 1968 [PPP_IPCP_STATE_REQ_SENT] = { 1969 [PPP_IPCP_EVENT_UP] = { PPP_IPCP_STATE_REQ_SENT, {} }, 1970 [PPP_IPCP_EVENT_DOWN] = { PPP_IPCP_STATE_INITIAL, {} }, 1971 [PPP_IPCP_EVENT_RCR_POS] = { PPP_IPCP_STATE_ACK_SENT, {ipcp_send_ack} }, 1972 [PPP_IPCP_EVENT_RCR_NEG] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_nack} }, 1973 [PPP_IPCP_EVENT_RCA] = { PPP_IPCP_STATE_ACK_RCVD, {} }, 1974 [PPP_IPCP_EVENT_RCN] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req, ipcp_start_timer} }, 1975 [PPP_IPCP_EVENT_TO] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req, ipcp_start_timer} } 1976 }, 1977 [PPP_IPCP_STATE_ACK_RCVD] = { 1978 [PPP_IPCP_EVENT_UP] = { PPP_IPCP_STATE_ACK_RCVD, {} }, 1979 [PPP_IPCP_EVENT_DOWN] = { PPP_IPCP_STATE_INITIAL, {} }, 1980 [PPP_IPCP_EVENT_RCR_POS] = { PPP_IPCP_STATE_OPENED, {ipcp_send_ack, ipcp_bring_up} }, 1981 [PPP_IPCP_EVENT_RCR_NEG] = { PPP_IPCP_STATE_ACK_RCVD, {ipcp_send_nack} }, 1982 [PPP_IPCP_EVENT_RCA] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req, ipcp_start_timer} }, 1983 [PPP_IPCP_EVENT_RCN] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req, ipcp_start_timer} }, 1984 [PPP_IPCP_EVENT_TO] = { PPP_IPCP_STATE_ACK_RCVD, {ipcp_send_req, ipcp_start_timer} } 1985 }, 1986 [PPP_IPCP_STATE_ACK_SENT] = { 1987 [PPP_IPCP_EVENT_UP] = { PPP_IPCP_STATE_ACK_SENT, {} }, 1988 [PPP_IPCP_EVENT_DOWN] = { PPP_IPCP_STATE_INITIAL, {} }, 1989 [PPP_IPCP_EVENT_RCR_POS] = { PPP_IPCP_STATE_ACK_SENT, {ipcp_send_ack} }, 1990 [PPP_IPCP_EVENT_RCR_NEG] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_nack} }, 1991 [PPP_IPCP_EVENT_RCA] = { PPP_IPCP_STATE_OPENED, {ipcp_bring_up} }, 1992 [PPP_IPCP_EVENT_RCN] = { PPP_IPCP_STATE_ACK_SENT, {ipcp_send_req, ipcp_start_timer} }, 1993 [PPP_IPCP_EVENT_TO] = { PPP_IPCP_STATE_ACK_SENT, {ipcp_send_req, ipcp_start_timer} } 1994 }, 1995 [PPP_IPCP_STATE_OPENED] = { 1996 [PPP_IPCP_EVENT_UP] = { PPP_IPCP_STATE_OPENED, {} }, 1997 [PPP_IPCP_EVENT_DOWN] = { PPP_IPCP_STATE_INITIAL, {ipcp_bring_down} }, 1998 [PPP_IPCP_EVENT_RCR_POS] = { PPP_IPCP_STATE_ACK_SENT, {ipcp_bring_down, ipcp_send_req, ipcp_send_ack} }, 1999 [PPP_IPCP_EVENT_RCR_NEG] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_bring_down, ipcp_send_req, ipcp_send_nack} }, 2000 [PPP_IPCP_EVENT_RCA] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req} }, 2001 [PPP_IPCP_EVENT_RCN] = { PPP_IPCP_STATE_REQ_SENT, {ipcp_send_req} }, 2002 [PPP_IPCP_EVENT_TO] = { PPP_IPCP_STATE_OPENED, {} } 2003 } 2004}; 2005 2006static void evaluate_ipcp_state(struct pico_device_ppp *ppp, enum ppp_ipcp_event event) 2007{ 2008 const struct pico_ppp_fsm *fsm; 2009 int i; 2010 if (mock_ipcp_state) { 2011 mock_ipcp_state(ppp, event); 2012 return; 2013 } 2014 2015 fsm = &ppp_ipcp_fsm[ppp->ipcp_state][event]; 2016 2017 ppp->ipcp_state = (enum ppp_ipcp_state)fsm->next_state; 2018 for (i = 0; i < PPP_FSM_MAX_ACTIONS; i++) { 2019 if (fsm->event_handler[i]) 2020 fsm->event_handler[i](ppp); 2021 } 2022} 2023 2024static int pico_ppp_poll(struct pico_device *dev, int loop_score) 2025{ 2026 struct pico_device_ppp *ppp = (struct pico_device_ppp *) dev; 2027 static uint32_t len = 0; 2028 int r; 2029 if (ppp->serial_recv) { 2030 do { 2031 r = ppp->serial_recv(&ppp->dev, &ppp_recv_buf[len], 1); 2032 if (r <= 0) 2033 break; 2034 2035 if (ppp->modem_state == PPP_MODEM_STATE_CONNECTED) { 2036 static int control_escape = 0; 2037 2038 if (ppp_recv_buf[len] == PPPF_FLAG_SEQ) { 2039 if (control_escape) { 2040 /* Illegal sequence, discard frame */ 2041 ppp_dbg("Illegal sequence, ppp_recv_buf[%d] = %d\n", len, ppp_recv_buf[len]); 2042 control_escape = 0; 2043 len = 0; 2044 } 2045 2046 if (len > 1) { 2047 ppp_recv_data(ppp, ppp_recv_buf, len); 2048 loop_score--; 2049 len = 0; 2050 } 2051 } else if (control_escape) { 2052 ppp_recv_buf[len] ^= 0x20; 2053 control_escape = 0; 2054 len++; 2055 } else if (ppp_recv_buf[len] == PPPF_CTRL_ESC) { 2056 control_escape = 1; 2057 } else { 2058 len++; 2059 } 2060 } else { 2061 static int s3 = 0; 2062 2063 if (ppp_recv_buf[len] == AT_S3) { 2064 s3 = 1; 2065 if (len > 0) { 2066 ppp_recv_buf[len] = '\0'; 2067 ppp_modem_recv(ppp, ppp_recv_buf, len); 2068 len = 0; 2069 } 2070 } else if (ppp_recv_buf[len] == AT_S4) { 2071 if (!s3) { 2072 len++; 2073 } 2074 2075 s3 = 0; 2076 } else { 2077 s3 = 0; 2078 len++; 2079 } 2080 } 2081 } while ((r > 0) && (len < ARRAY_SIZE(ppp_recv_buf)) && (loop_score > 0)); 2082 } 2083 2084 return loop_score; 2085} 2086 2087/* Public interface: create/destroy. */ 2088 2089static int pico_ppp_link_state(struct pico_device *dev) 2090{ 2091 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2092 if (ppp->ipcp_state == PPP_IPCP_STATE_OPENED) 2093 return 1; 2094 2095 return 0; 2096} 2097 2098void pico_ppp_destroy(struct pico_device *ppp) 2099{ 2100 if (!ppp) 2101 return; 2102 2103 /* Perform custom cleanup here before calling 'pico_device_destroy' 2104 * or register a custom cleanup function during initialization 2105 * by setting 'ppp->dev.destroy'. */ 2106 2107 pico_device_destroy(ppp); 2108} 2109 2110static void check_to_modem(struct pico_device_ppp *ppp) 2111{ 2112 if (ppp->timer_on & PPP_TIMER_ON_MODEM) { 2113 if (ppp->timer_val == 0) { 2114 ppp->timer_on = (uint8_t) (ppp->timer_on & (~PPP_TIMER_ON_MODEM)); 2115 evaluate_modem_state(ppp, PPP_MODEM_EVENT_TIMEOUT); 2116 } 2117 } 2118} 2119 2120static void check_to_lcp(struct pico_device_ppp *ppp) 2121{ 2122 if (ppp->timer_on & (PPP_TIMER_ON_LCPREQ | PPP_TIMER_ON_LCPTERM)) { 2123 if (ppp->timer_val == 0) { 2124 if (ppp->timer_count == 0) 2125 evaluate_lcp_state(ppp, PPP_LCP_EVENT_TO_NEG); 2126 else{ 2127 evaluate_lcp_state(ppp, PPP_LCP_EVENT_TO_POS); 2128 ppp->timer_count--; 2129 } 2130 } 2131 } 2132} 2133 2134static void check_to_auth(struct pico_device_ppp *ppp) 2135{ 2136 if (ppp->timer_on & PPP_TIMER_ON_AUTH) { 2137 if (ppp->timer_val == 0) { 2138 ppp->timer_on = (uint8_t) (ppp->timer_on & (~PPP_TIMER_ON_AUTH)); 2139 evaluate_auth_state(ppp, PPP_AUTH_EVENT_TO); 2140 } 2141 } 2142} 2143 2144static void check_to_ipcp(struct pico_device_ppp *ppp) 2145{ 2146 if (ppp->timer_on & PPP_TIMER_ON_IPCP) { 2147 if (ppp->timer_val == 0) { 2148 ppp->timer_on = (uint8_t) (ppp->timer_on & (~PPP_TIMER_ON_IPCP)); 2149 evaluate_ipcp_state(ppp, PPP_IPCP_EVENT_TO); 2150 } 2151 } 2152} 2153 2154static void pico_ppp_tick(pico_time t, void *arg) 2155{ 2156 struct pico_device_ppp *ppp = (struct pico_device_ppp *) arg; 2157 (void)t; 2158 if (ppp->timer_val > 0) 2159 ppp->timer_val--; 2160 2161 check_to_modem(ppp); 2162 check_to_lcp(ppp); 2163 check_to_auth(ppp); 2164 check_to_ipcp(ppp); 2165 2166 if (ppp->autoreconnect && ppp->lcp_state == PPP_LCP_STATE_INITIAL) { 2167 ppp_dbg("(Re)connecting...\n"); 2168 evaluate_lcp_state(ppp, PPP_LCP_EVENT_OPEN); 2169 } 2170 2171 if (!pico_timer_add(1000, pico_ppp_tick, arg)) { 2172 ppp_dbg("PPP: Failed to start tick timer\n"); 2173 /* TODO No more PPP ticks now */ 2174 } 2175} 2176 2177struct pico_device *pico_ppp_create(void) 2178{ 2179 struct pico_device_ppp *ppp = PICO_ZALLOC(sizeof(struct pico_device_ppp)); 2180 char devname[MAX_DEVICE_NAME]; 2181 2182 if (!ppp) 2183 return NULL; 2184 2185 snprintf(devname, MAX_DEVICE_NAME, "ppp%d", ppp_devnum++); 2186 2187 if( 0 != pico_device_init((struct pico_device *)ppp, devname, NULL)) { 2188 return NULL; 2189 } 2190 2191 ppp->dev.overhead = PPP_HDR_SIZE; 2192 ppp->dev.mtu = PICO_PPP_MTU; 2193 ppp->dev.send = pico_ppp_send; 2194 ppp->dev.poll = pico_ppp_poll; 2195 ppp->dev.link_state = pico_ppp_link_state; 2196 ppp->frame_id = (uint8_t)(pico_rand() % 0xFF); 2197 2198 ppp->modem_state = PPP_MODEM_STATE_INITIAL; 2199 ppp->lcp_state = PPP_LCP_STATE_INITIAL; 2200 ppp->auth_state = PPP_AUTH_STATE_INITIAL; 2201 ppp->ipcp_state = PPP_IPCP_STATE_INITIAL; 2202 2203 ppp->timer = pico_timer_add(1000, pico_ppp_tick, ppp); 2204 if (!ppp->timer) { 2205 ppp_dbg("PPP: Failed to start tick timer\n"); 2206 pico_device_destroy((struct pico_device*) ppp); 2207 return NULL; 2208 } 2209 ppp->mru = PICO_PPP_MRU; 2210 2211 LCPOPT_SET_LOCAL(ppp, LCPOPT_MRU); 2212 LCPOPT_SET_LOCAL(ppp, LCPOPT_AUTH); /* We support authentication, even if it's not part of the req */ 2213 LCPOPT_SET_LOCAL(ppp, LCPOPT_PROTO_COMP); 2214 LCPOPT_SET_LOCAL(ppp, LCPOPT_ADDRCTL_COMP); 2215 2216 2217 ppp_dbg("Device %s created.\n", ppp->dev.name); 2218 return (struct pico_device *)ppp; 2219} 2220 2221int pico_ppp_connect(struct pico_device *dev) 2222{ 2223 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2224 ppp->autoreconnect = 1; 2225 return 0; 2226} 2227 2228int pico_ppp_disconnect(struct pico_device *dev) 2229{ 2230 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2231 ppp->autoreconnect = 0; 2232 evaluate_lcp_state(ppp, PPP_LCP_EVENT_CLOSE); 2233 2234 pico_ipv4_cleanup_links(dev); 2235 2236 return 0; 2237} 2238 2239int pico_ppp_set_serial_read(struct pico_device *dev, int (*sread)(struct pico_device *, void *, int)) 2240{ 2241 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2242 2243 if (!dev) 2244 return -1; 2245 2246 ppp->serial_recv = sread; 2247 return 0; 2248} 2249 2250int pico_ppp_set_serial_write(struct pico_device *dev, int (*swrite)(struct pico_device *, const void *, int)) 2251{ 2252 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2253 2254 if (!dev) 2255 return -1; 2256 2257 ppp->serial_send = swrite; 2258 return 0; 2259} 2260 2261int pico_ppp_set_serial_set_speed(struct pico_device *dev, int (*sspeed)(struct pico_device *, uint32_t)) 2262{ 2263 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2264 2265 if (!dev) 2266 return -1; 2267 2268 ppp->serial_set_speed = sspeed; 2269 return 0; 2270} 2271 2272int pico_ppp_set_apn(struct pico_device *dev, const char *apn) 2273{ 2274 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2275 2276 if (!dev) 2277 return -1; 2278 2279 if (!apn) 2280 return -1; 2281 2282 strncpy(ppp->apn, apn, sizeof(ppp->apn) - 1); 2283 return 0; 2284} 2285 2286int pico_ppp_set_username(struct pico_device *dev, const char *username) 2287{ 2288 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2289 2290 if (!dev) 2291 return -1; 2292 2293 if (!username) 2294 return -1; 2295 2296 strncpy(ppp->username, username, sizeof(ppp->username) - 1); 2297 return 0; 2298} 2299 2300int pico_ppp_set_password(struct pico_device *dev, const char *password) 2301{ 2302 struct pico_device_ppp *ppp = (struct pico_device_ppp *)dev; 2303 2304 if (!dev) 2305 return -1; 2306 2307 if (!password) 2308 return -1; 2309 2310 strncpy(ppp->password, password, sizeof(ppp->password) - 1); 2311 return 0; 2312} 2313