1 /*
2 * Copyright (c) 2019 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #ifndef ZEPHYR_INCLUDE_NET_PPP_H_
9 #define ZEPHYR_INCLUDE_NET_PPP_H_
10
11 #include <zephyr/net/net_if.h>
12 #include <zephyr/net/net_pkt.h>
13 #include <zephyr/net/net_stats.h>
14 #include <zephyr/net/net_mgmt.h>
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 /**
21 * @brief Point-to-point (PPP) L2/driver support functions
22 * @defgroup ppp PPP L2/driver Support Functions
23 * @ingroup networking
24 * @{
25 */
26
27 /** PPP maximum receive unit (MRU) */
28 #define PPP_MRU CONFIG_NET_PPP_MTU_MRU
29
30 /** PPP maximum transfer unit (MTU) */
31 #define PPP_MTU PPP_MRU
32
33 /** Max length of terminate description string */
34 #define PPP_MAX_TERMINATE_REASON_LEN 32
35
36 /** Length of network interface identifier */
37 #define PPP_INTERFACE_IDENTIFIER_LEN 8
38
39 /** PPP L2 API */
40 struct ppp_api {
41 /**
42 * The net_if_api must be placed in first position in this
43 * struct so that we are compatible with network interface API.
44 */
45 struct net_if_api iface_api;
46
47 /** Start the device */
48 int (*start)(const struct device *dev);
49
50 /** Stop the device */
51 int (*stop)(const struct device *dev);
52
53 /** Send a network packet */
54 int (*send)(const struct device *dev, struct net_pkt *pkt);
55
56 #if defined(CONFIG_NET_STATISTICS_PPP)
57 /** Collect optional PPP specific statistics. This pointer
58 * should be set by driver if statistics needs to be collected
59 * for that driver.
60 */
61 struct net_stats_ppp *(*get_stats)(const struct device *dev);
62 #endif
63 };
64
65 /* Make sure that the network interface API is properly setup inside
66 * PPP API struct (it is the first one).
67 */
68 BUILD_ASSERT(offsetof(struct ppp_api, iface_api) == 0);
69
70 /**
71 * PPP protocol types.
72 * See https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml
73 * for details.
74 */
75 enum ppp_protocol_type {
76 PPP_IP = 0x0021, /**< RFC 1332 */
77 PPP_IPV6 = 0x0057, /**< RFC 5072 */
78 PPP_IPCP = 0x8021, /**< RFC 1332 */
79 PPP_ECP = 0x8053, /**< RFC 1968 */
80 PPP_IPV6CP = 0x8057, /**< RFC 5072 */
81 PPP_CCP = 0x80FD, /**< RFC 1962 */
82 PPP_LCP = 0xc021, /**< RFC 1661 */
83 PPP_PAP = 0xc023, /**< RFC 1334 */
84 PPP_CHAP = 0xc223, /**< RFC 1334 */
85 PPP_EAP = 0xc227, /**< RFC 2284 */
86 };
87
88 /**
89 * PPP phases
90 */
91 enum ppp_phase {
92 /** Physical-layer not ready */
93 PPP_DEAD,
94 /** Link is being established */
95 PPP_ESTABLISH,
96 /** Link authentication with peer */
97 PPP_AUTH,
98 /** Network connection establishment */
99 PPP_NETWORK,
100 /** Network running */
101 PPP_RUNNING,
102 /** Link termination */
103 PPP_TERMINATE,
104 };
105
106 /**
107 * PPP states, RFC 1661 ch. 4.2
108 */
109 enum ppp_state {
110 PPP_INITIAL,
111 PPP_STARTING,
112 PPP_CLOSED,
113 PPP_STOPPED,
114 PPP_CLOSING,
115 PPP_STOPPING,
116 PPP_REQUEST_SENT,
117 PPP_ACK_RECEIVED,
118 PPP_ACK_SENT,
119 PPP_OPENED
120 };
121
122 /**
123 * PPP protocol operations from RFC 1661
124 */
125 enum ppp_packet_type {
126 PPP_CONFIGURE_REQ = 1,
127 PPP_CONFIGURE_ACK = 2,
128 PPP_CONFIGURE_NACK = 3,
129 PPP_CONFIGURE_REJ = 4,
130 PPP_TERMINATE_REQ = 5,
131 PPP_TERMINATE_ACK = 6,
132 PPP_CODE_REJ = 7,
133 PPP_PROTOCOL_REJ = 8,
134 PPP_ECHO_REQ = 9,
135 PPP_ECHO_REPLY = 10,
136 PPP_DISCARD_REQ = 11
137 };
138
139 /**
140 * LCP option types from RFC 1661 ch. 6
141 */
142 enum lcp_option_type {
143 LCP_OPTION_RESERVED = 0,
144
145 /** Maximum-Receive-Unit */
146 LCP_OPTION_MRU = 1,
147
148 /** Async-Control-Character-Map */
149 LCP_OPTION_ASYNC_CTRL_CHAR_MAP = 2,
150
151 /** Authentication-Protocol */
152 LCP_OPTION_AUTH_PROTO = 3,
153
154 /** Quality-Protocol */
155 LCP_OPTION_QUALITY_PROTO = 4,
156
157 /** Magic-Number */
158 LCP_OPTION_MAGIC_NUMBER = 5,
159
160 /** Protocol-Field-Compression */
161 LCP_OPTION_PROTO_COMPRESS = 7,
162
163 /** Address-and-Control-Field-Compression */
164 LCP_OPTION_ADDR_CTRL_COMPRESS = 8
165 } __packed;
166
167 /**
168 * IPCP option types from RFC 1332
169 */
170 enum ipcp_option_type {
171 IPCP_OPTION_RESERVED = 0,
172
173 /** IP Addresses */
174 IPCP_OPTION_IP_ADDRESSES = 1,
175
176 /** IP Compression Protocol */
177 IPCP_OPTION_IP_COMP_PROTO = 2,
178
179 /** IP Address */
180 IPCP_OPTION_IP_ADDRESS = 3,
181
182 /* RFC 1877 */
183
184 /** Primary DNS Server Address */
185 IPCP_OPTION_DNS1 = 129,
186
187 /** Primary NBNS Server Address */
188 IPCP_OPTION_NBNS1 = 130,
189
190 /** Secondary DNS Server Address */
191 IPCP_OPTION_DNS2 = 131,
192
193 /** Secondary NBNS Server Address */
194 IPCP_OPTION_NBNS2 = 132,
195 } __packed;
196
197 /**
198 * IPV6CP option types from RFC 5072
199 */
200 enum ipv6cp_option_type {
201 IPV6CP_OPTION_RESERVED = 0,
202
203 /** Interface identifier */
204 IPV6CP_OPTION_INTERFACE_IDENTIFIER = 1,
205 } __packed;
206
207 /**
208 * @typedef net_ppp_lcp_echo_reply_cb_t
209 * @brief A callback function that can be called if a Echo-Reply needs to
210 * be received.
211 * @param user_data User settable data that is passed to the callback
212 * function.
213 * @param user_data_len Length of the user data.
214 */
215 typedef void (*net_ppp_lcp_echo_reply_cb_t)(void *user_data,
216 size_t user_data_len);
217
218 struct ppp_my_option_data;
219 struct ppp_my_option_info;
220
221 /**
222 * Generic PPP Finite State Machine
223 */
224 struct ppp_fsm {
225 /** Timeout timer */
226 struct k_work_delayable timer;
227
228 struct {
229 /** Acknowledge Configuration Information */
230 int (*config_info_ack)(struct ppp_fsm *fsm,
231 struct net_pkt *pkt,
232 uint16_t length);
233
234 /** Add Configuration Information */
235 struct net_pkt *(*config_info_add)(struct ppp_fsm *fsm);
236
237 /** Length of Configuration Information */
238 int (*config_info_len)(struct ppp_fsm *fsm);
239
240 /** Negative Acknowledge Configuration Information */
241 int (*config_info_nack)(struct ppp_fsm *fsm,
242 struct net_pkt *pkt,
243 uint16_t length,
244 bool rejected);
245
246 /** Request peer's Configuration Information */
247 int (*config_info_req)(struct ppp_fsm *fsm,
248 struct net_pkt *pkt,
249 uint16_t length,
250 struct net_pkt *ret_pkt);
251
252 /** Reject Configuration Information */
253 int (*config_info_rej)(struct ppp_fsm *fsm,
254 struct net_pkt *pkt,
255 uint16_t length);
256
257 /** Reset Configuration Information */
258 void (*config_info_reset)(struct ppp_fsm *fsm);
259
260 /** FSM goes to OPENED state */
261 void (*up)(struct ppp_fsm *fsm);
262
263 /** FSM leaves OPENED state */
264 void (*down)(struct ppp_fsm *fsm);
265
266 /** Starting this protocol */
267 void (*starting)(struct ppp_fsm *fsm);
268
269 /** Quitting this protocol */
270 void (*finished)(struct ppp_fsm *fsm);
271
272 /** We received Protocol-Reject */
273 void (*proto_reject)(struct ppp_fsm *fsm);
274
275 /** Retransmit */
276 void (*retransmit)(struct ppp_fsm *fsm);
277
278 /** Any code that is not understood by PPP is passed to
279 * this FSM for further processing.
280 */
281 enum net_verdict (*proto_extension)(struct ppp_fsm *fsm,
282 enum ppp_packet_type code,
283 uint8_t id,
284 struct net_pkt *pkt);
285 } cb;
286
287 struct {
288 /** Options information */
289 const struct ppp_my_option_info *info;
290
291 /** Options negotiation data */
292 struct ppp_my_option_data *data;
293
294 /** Number of negotiated options */
295 size_t count;
296 } my_options;
297
298 /** Option bits */
299 uint32_t flags;
300
301 /** Number of re-transmissions left */;
302 uint32_t retransmits;
303
304 /** Number of NACK loops since last ACK */
305 uint32_t nack_loops;
306
307 /** Number of NACKs received */
308 uint32_t recv_nack_loops;
309
310 /** Reason for closing protocol */
311 char terminate_reason[PPP_MAX_TERMINATE_REASON_LEN];
312
313 /** PPP protocol number for this FSM */
314 uint16_t protocol;
315
316 /** Current state of PPP link */
317 enum ppp_state state;
318
319 /** Protocol/layer name of this FSM (for debugging) */
320 const char *name;
321
322 /** Current id */
323 uint8_t id;
324
325 /** Current request id */
326 uint8_t req_id;
327
328 /** Have received valid Ack, Nack or Reject to a Request */
329 uint8_t ack_received : 1;
330 };
331
332 #define PPP_MY_OPTION_ACKED BIT(0)
333 #define PPP_MY_OPTION_REJECTED BIT(1)
334
335 struct ppp_my_option_data {
336 uint32_t flags;
337 };
338
339 struct lcp_options {
340 /** Magic number */
341 uint32_t magic;
342
343 /** Async char map */
344 uint32_t async_map;
345
346 /** Maximum Receive Unit value */
347 uint16_t mru;
348
349 /** Which authentication protocol was negotiated (0 means none) */
350 uint16_t auth_proto;
351 };
352
353 #if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
354 #define LCP_NUM_MY_OPTIONS 1
355 #endif
356
357 struct ipcp_options {
358 /** IPv4 address */
359 struct in_addr address;
360 struct in_addr dns1_address;
361 struct in_addr dns2_address;
362 };
363
364 #define IPCP_NUM_MY_OPTIONS 3
365
366 struct ipv6cp_options {
367 /** Interface identifier */
368 uint8_t iid[PPP_INTERFACE_IDENTIFIER_LEN];
369 };
370
371 #define IPV6CP_NUM_MY_OPTIONS 1
372
373 enum ppp_flags {
374 PPP_CARRIER_UP,
375 };
376
377 /** PPP L2 context specific to certain network interface */
378 struct ppp_context {
379 /** Flags representing PPP state, which are accessed from multiple
380 * threads.
381 */
382 atomic_t flags;
383
384 /** PPP startup worker. */
385 struct k_work_delayable startup;
386
387 struct {
388 /** Finite state machine for LCP */
389 struct ppp_fsm fsm;
390
391 /** Options that we want to request */
392 struct lcp_options my_options;
393
394 /** Options that peer want to request */
395 struct lcp_options peer_options;
396
397 /** Magic-Number value */
398 uint32_t magic;
399 #if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
400 struct ppp_my_option_data my_options_data[LCP_NUM_MY_OPTIONS];
401 #endif
402 } lcp;
403
404 #if defined(CONFIG_NET_IPV4)
405 struct {
406 /** Finite state machine for IPCP */
407 struct ppp_fsm fsm;
408
409 /** Options that we want to request */
410 struct ipcp_options my_options;
411
412 /** Options that peer want to request */
413 struct ipcp_options peer_options;
414
415 /** My options runtime data */
416 struct ppp_my_option_data my_options_data[IPCP_NUM_MY_OPTIONS];
417 } ipcp;
418 #endif
419
420 #if defined(CONFIG_NET_IPV6)
421 struct {
422 /** Finite state machine for IPV6CP */
423 struct ppp_fsm fsm;
424
425 /** Options that we want to request */
426 struct ipv6cp_options my_options;
427
428 /** Options that peer want to request */
429 struct ipv6cp_options peer_options;
430
431 /** My options runtime data */
432 struct ppp_my_option_data my_options_data[IPV6CP_NUM_MY_OPTIONS];
433 } ipv6cp;
434 #endif
435
436 #if defined(CONFIG_NET_L2_PPP_PAP)
437 struct {
438 /** Finite state machine for PAP */
439 struct ppp_fsm fsm;
440 } pap;
441 #endif
442
443 #if defined(CONFIG_NET_SHELL)
444 struct {
445 struct {
446 /** Callback to be called when Echo-Reply is received.
447 */
448 net_ppp_lcp_echo_reply_cb_t cb;
449
450 /** User specific data for the callback */
451 void *user_data;
452
453 /** User data length */
454 size_t user_data_len;
455 } echo_reply;
456
457 /** Used when waiting Echo-Reply */
458 struct k_sem wait_echo_reply;
459
460 /** Echo-Req data value */
461 uint32_t echo_req_data;
462
463 /** Echo-Reply data value */
464 uint32_t echo_reply_data;
465 } shell;
466 #endif
467
468 /** Network interface related to this PPP connection */
469 struct net_if *iface;
470
471 /** Network management callback structure */
472 struct net_mgmt_event_callback mgmt_evt_cb;
473
474 /** Current phase of PPP link */
475 enum ppp_phase phase;
476
477 /** This tells what features the PPP supports. */
478 enum net_l2_flags ppp_l2_flags;
479
480 /** This tells how many network protocols are open */
481 int network_protos_open;
482
483 /** This tells how many network protocols are up */
484 int network_protos_up;
485
486 /** Is PPP ready to receive packets */
487 uint16_t is_ready_to_serve : 1;
488
489 /** Is PPP L2 enabled or not */
490 uint16_t is_enabled : 1;
491
492 /** PPP enable pending */
493 uint16_t is_enable_done : 1;
494
495 /** IPCP status (up / down) */
496 uint16_t is_ipcp_up : 1;
497
498 /** IPCP open status (open / closed) */
499 uint16_t is_ipcp_open : 1;
500
501 /** IPV6CP status (up / down) */
502 uint16_t is_ipv6cp_up : 1;
503
504 /** IPV6CP open status (open / closed) */
505 uint16_t is_ipv6cp_open : 1;
506
507 /** PAP status (up / down) */
508 uint16_t is_pap_up : 1;
509
510 /** PAP open status (open / closed) */
511 uint16_t is_pap_open : 1;
512 };
513
514 /**
515 * @brief Initialize PPP L2 stack for a given interface
516 *
517 * @param iface A valid pointer to a network interface
518 */
519 void net_ppp_init(struct net_if *iface);
520
521 /* Management API for PPP */
522
523 /** @cond INTERNAL_HIDDEN */
524
525 #define PPP_L2_CTX_TYPE struct ppp_context
526
527 #define _NET_PPP_LAYER NET_MGMT_LAYER_L2
528 #define _NET_PPP_CODE 0x209
529 #define _NET_PPP_BASE (NET_MGMT_IFACE_BIT | \
530 NET_MGMT_LAYER(_NET_PPP_LAYER) | \
531 NET_MGMT_LAYER_CODE(_NET_PPP_CODE))
532 #define _NET_PPP_EVENT (_NET_PPP_BASE | NET_MGMT_EVENT_BIT)
533
534 enum net_event_ppp_cmd {
535 NET_EVENT_PPP_CMD_CARRIER_ON = 1,
536 NET_EVENT_PPP_CMD_CARRIER_OFF,
537 NET_EVENT_PPP_CMD_PHASE_RUNNING,
538 NET_EVENT_PPP_CMD_PHASE_DEAD,
539 };
540
541 #define NET_EVENT_PPP_CARRIER_ON \
542 (_NET_PPP_EVENT | NET_EVENT_PPP_CMD_CARRIER_ON)
543
544 #define NET_EVENT_PPP_CARRIER_OFF \
545 (_NET_PPP_EVENT | NET_EVENT_PPP_CMD_CARRIER_OFF)
546
547 #define NET_EVENT_PPP_PHASE_RUNNING \
548 (_NET_PPP_EVENT | NET_EVENT_PPP_CMD_PHASE_RUNNING)
549
550 #define NET_EVENT_PPP_PHASE_DEAD \
551 (_NET_PPP_EVENT | NET_EVENT_PPP_CMD_PHASE_DEAD)
552
553 struct net_if;
554
555 /** @endcond */
556
557 /**
558 * @brief Raise CARRIER_ON event when PPP is connected.
559 *
560 * @param iface PPP network interface.
561 */
562 #if defined(CONFIG_NET_L2_PPP_MGMT)
563 void ppp_mgmt_raise_carrier_on_event(struct net_if *iface);
564 #else
ppp_mgmt_raise_carrier_on_event(struct net_if * iface)565 static inline void ppp_mgmt_raise_carrier_on_event(struct net_if *iface)
566 {
567 ARG_UNUSED(iface);
568 }
569 #endif
570
571 /**
572 * @brief Raise CARRIER_OFF event when PPP is disconnected.
573 *
574 * @param iface PPP network interface.
575 */
576 #if defined(CONFIG_NET_L2_PPP_MGMT)
577 void ppp_mgmt_raise_carrier_off_event(struct net_if *iface);
578 #else
ppp_mgmt_raise_carrier_off_event(struct net_if * iface)579 static inline void ppp_mgmt_raise_carrier_off_event(struct net_if *iface)
580 {
581 ARG_UNUSED(iface);
582 }
583 #endif
584
585 /**
586 * @brief Raise PHASE_RUNNING event when PPP reaching RUNNING phase
587 *
588 * @param iface PPP network interface.
589 */
590 #if defined(CONFIG_NET_L2_PPP_MGMT)
591 void ppp_mgmt_raise_phase_running_event(struct net_if *iface);
592 #else
ppp_mgmt_raise_phase_running_event(struct net_if * iface)593 static inline void ppp_mgmt_raise_phase_running_event(struct net_if *iface)
594 {
595 ARG_UNUSED(iface);
596 }
597 #endif
598
599 /**
600 * @brief Raise PHASE_DEAD event when PPP reaching DEAD phase
601 *
602 * @param iface PPP network interface.
603 */
604 #if defined(CONFIG_NET_L2_PPP_MGMT)
605 void ppp_mgmt_raise_phase_dead_event(struct net_if *iface);
606 #else
ppp_mgmt_raise_phase_dead_event(struct net_if * iface)607 static inline void ppp_mgmt_raise_phase_dead_event(struct net_if *iface)
608 {
609 ARG_UNUSED(iface);
610 }
611 #endif
612
613 /**
614 * @brief Send PPP Echo-Request to peer. We expect to receive Echo-Reply back.
615 *
616 * @param idx PPP network interface index
617 * @param timeout Amount of time to wait Echo-Reply. The value is in
618 * milliseconds.
619 *
620 * @return 0 if Echo-Reply was received, < 0 if there is a timeout or network
621 * index is not a valid PPP network index.
622 */
623 #if defined(CONFIG_NET_L2_PPP)
624 int net_ppp_ping(int idx, int32_t timeout);
625 #else
net_ppp_ping(int idx,int32_t timeout)626 static inline int net_ppp_ping(int idx, int32_t timeout)
627 {
628 ARG_UNUSED(idx);
629 ARG_UNUSED(timeout);
630
631 return -ENOTSUP;
632 }
633 #endif
634
635 /**
636 * @brief Get PPP context information. This is only used by net-shell to
637 * print information about PPP.
638 *
639 * @param idx PPP network interface index
640 *
641 * @return PPP context or NULL if idx is invalid.
642 */
643 #if defined(CONFIG_NET_L2_PPP) && defined(CONFIG_NET_SHELL)
644 struct ppp_context *net_ppp_context_get(int idx);
645 #else
net_ppp_context_get(int idx)646 static inline struct ppp_context *net_ppp_context_get(int idx)
647 {
648 ARG_UNUSED(idx);
649
650 return NULL;
651 }
652 #endif
653
654 #ifdef __cplusplus
655 }
656 #endif
657
658 /**
659 * @}
660 */
661
662 #endif /* ZEPHYR_INCLUDE_NET_PPP_H_ */
663