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