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 	/** Carrier ON/OFF handler worker. This is used to create
388 	 * network interface UP/DOWN event when PPP L2 driver
389 	 * notices carrier ON/OFF situation. We must not create another
390 	 * network management event from inside management handler thus
391 	 * we use worker thread to trigger the UP/DOWN event.
392 	 */
393 	struct k_work carrier_work;
394 
395 	struct {
396 		/** Finite state machine for LCP */
397 		struct ppp_fsm fsm;
398 
399 		/** Options that we want to request */
400 		struct lcp_options my_options;
401 
402 		/** Options that peer want to request */
403 		struct lcp_options peer_options;
404 
405 		/** Magic-Number value */
406 		uint32_t magic;
407 #if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
408 		struct ppp_my_option_data my_options_data[LCP_NUM_MY_OPTIONS];
409 #endif
410 	} lcp;
411 
412 #if defined(CONFIG_NET_IPV4)
413 	struct {
414 		/** Finite state machine for IPCP */
415 		struct ppp_fsm fsm;
416 
417 		/** Options that we want to request */
418 		struct ipcp_options my_options;
419 
420 		/** Options that peer want to request */
421 		struct ipcp_options peer_options;
422 
423 		/** My options runtime data */
424 		struct ppp_my_option_data my_options_data[IPCP_NUM_MY_OPTIONS];
425 	} ipcp;
426 #endif
427 
428 #if defined(CONFIG_NET_IPV6)
429 	struct {
430 		/** Finite state machine for IPV6CP */
431 		struct ppp_fsm fsm;
432 
433 		/** Options that we want to request */
434 		struct ipv6cp_options my_options;
435 
436 		/** Options that peer want to request */
437 		struct ipv6cp_options peer_options;
438 
439 		/** My options runtime data */
440 		struct ppp_my_option_data my_options_data[IPV6CP_NUM_MY_OPTIONS];
441 	} ipv6cp;
442 #endif
443 
444 #if defined(CONFIG_NET_L2_PPP_PAP)
445 	struct {
446 		/** Finite state machine for PAP */
447 		struct ppp_fsm fsm;
448 	} pap;
449 #endif
450 
451 #if defined(CONFIG_NET_SHELL)
452 	struct {
453 		struct {
454 			/** Callback to be called when Echo-Reply is received.
455 			 */
456 			net_ppp_lcp_echo_reply_cb_t cb;
457 
458 			/** User specific data for the callback */
459 			void *user_data;
460 
461 			/** User data length */
462 			size_t user_data_len;
463 		} echo_reply;
464 
465 		/** Used when waiting Echo-Reply */
466 		struct k_sem wait_echo_reply;
467 
468 		/** Echo-Req data value */
469 		uint32_t echo_req_data;
470 
471 		/** Echo-Reply data value */
472 		uint32_t echo_reply_data;
473 	} shell;
474 #endif
475 
476 	/** Network interface related to this PPP connection */
477 	struct net_if *iface;
478 
479 	/** Current phase of PPP link */
480 	enum ppp_phase phase;
481 
482 	/** This tells what features the PPP supports. */
483 	enum net_l2_flags ppp_l2_flags;
484 
485 	/** This tells how many network protocols are open */
486 	int network_protos_open;
487 
488 	/** This tells how many network protocols are up */
489 	int network_protos_up;
490 
491 	/** Is network carrier up */
492 	uint16_t is_net_carrier_up : 1;
493 
494 	/** Is PPP ready to receive packets */
495 	uint16_t is_ready_to_serve : 1;
496 
497 	/** Is PPP L2 enabled or not */
498 	uint16_t is_enabled : 1;
499 
500 	/** PPP startup pending */
501 	uint16_t is_startup_pending : 1;
502 
503 	/** PPP enable pending */
504 	uint16_t is_enable_done : 1;
505 
506 	/** IPCP status (up / down) */
507 	uint16_t is_ipcp_up : 1;
508 
509 	/** IPCP open status (open / closed) */
510 	uint16_t is_ipcp_open : 1;
511 
512 	/** IPV6CP status (up / down) */
513 	uint16_t is_ipv6cp_up : 1;
514 
515 	/** IPV6CP open status (open / closed) */
516 	uint16_t is_ipv6cp_open : 1;
517 
518 	/** PAP status (up / down) */
519 	uint16_t is_pap_up : 1;
520 
521 	/** PAP open status (open / closed) */
522 	uint16_t is_pap_open : 1;
523 };
524 
525 /**
526  * @brief Inform PPP L2 driver that carrier is detected.
527  * This happens when cable is connected etc.
528  *
529  * @param iface Network interface
530  */
531 void net_ppp_carrier_on(struct net_if *iface);
532 
533 /**
534  * @brief Inform PPP L2 driver that carrier was lost.
535  * This happens when cable is disconnected etc.
536  *
537  * @param iface Network interface
538  */
539 void net_ppp_carrier_off(struct net_if *iface);
540 
541 /**
542  * @brief Initialize PPP L2 stack for a given interface
543  *
544  * @param iface A valid pointer to a network interface
545  */
546 void net_ppp_init(struct net_if *iface);
547 
548 /* Management API for PPP */
549 
550 /** @cond INTERNAL_HIDDEN */
551 
552 #define PPP_L2_CTX_TYPE	struct ppp_context
553 
554 #define _NET_PPP_LAYER	NET_MGMT_LAYER_L2
555 #define _NET_PPP_CODE	0x209
556 #define _NET_PPP_BASE	(NET_MGMT_IFACE_BIT |				\
557 			 NET_MGMT_LAYER(_NET_PPP_LAYER) |		\
558 			 NET_MGMT_LAYER_CODE(_NET_PPP_CODE))
559 #define _NET_PPP_EVENT	(_NET_PPP_BASE | NET_MGMT_EVENT_BIT)
560 
561 enum net_event_ppp_cmd {
562 	NET_EVENT_PPP_CMD_CARRIER_ON = 1,
563 	NET_EVENT_PPP_CMD_CARRIER_OFF,
564 	NET_EVENT_PPP_CMD_PHASE_RUNNING,
565 	NET_EVENT_PPP_CMD_PHASE_DEAD,
566 };
567 
568 #define NET_EVENT_PPP_CARRIER_ON					\
569 	(_NET_PPP_EVENT | NET_EVENT_PPP_CMD_CARRIER_ON)
570 
571 #define NET_EVENT_PPP_CARRIER_OFF					\
572 	(_NET_PPP_EVENT | NET_EVENT_PPP_CMD_CARRIER_OFF)
573 
574 #define NET_EVENT_PPP_PHASE_RUNNING					\
575 	(_NET_PPP_EVENT | NET_EVENT_PPP_CMD_PHASE_RUNNING)
576 
577 #define NET_EVENT_PPP_PHASE_DEAD					\
578 	(_NET_PPP_EVENT | NET_EVENT_PPP_CMD_PHASE_DEAD)
579 
580 struct net_if;
581 
582 /** @endcond */
583 
584 /**
585  * @brief Raise CARRIER_ON event when PPP is connected.
586  *
587  * @param iface PPP network interface.
588  */
589 #if defined(CONFIG_NET_L2_PPP_MGMT)
590 void ppp_mgmt_raise_carrier_on_event(struct net_if *iface);
591 #else
ppp_mgmt_raise_carrier_on_event(struct net_if * iface)592 static inline void ppp_mgmt_raise_carrier_on_event(struct net_if *iface)
593 {
594 	ARG_UNUSED(iface);
595 }
596 #endif
597 
598 /**
599  * @brief Raise CARRIER_OFF event when PPP is disconnected.
600  *
601  * @param iface PPP network interface.
602  */
603 #if defined(CONFIG_NET_L2_PPP_MGMT)
604 void ppp_mgmt_raise_carrier_off_event(struct net_if *iface);
605 #else
ppp_mgmt_raise_carrier_off_event(struct net_if * iface)606 static inline void ppp_mgmt_raise_carrier_off_event(struct net_if *iface)
607 {
608 	ARG_UNUSED(iface);
609 }
610 #endif
611 
612 /**
613  * @brief Raise PHASE_RUNNING event when PPP reaching RUNNING phase
614  *
615  * @param iface PPP network interface.
616  */
617 #if defined(CONFIG_NET_L2_PPP_MGMT)
618 void ppp_mgmt_raise_phase_running_event(struct net_if *iface);
619 #else
ppp_mgmt_raise_phase_running_event(struct net_if * iface)620 static inline void ppp_mgmt_raise_phase_running_event(struct net_if *iface)
621 {
622 	ARG_UNUSED(iface);
623 }
624 #endif
625 
626 /**
627  * @brief Raise PHASE_DEAD event when PPP reaching DEAD phase
628  *
629  * @param iface PPP network interface.
630  */
631 #if defined(CONFIG_NET_L2_PPP_MGMT)
632 void ppp_mgmt_raise_phase_dead_event(struct net_if *iface);
633 #else
ppp_mgmt_raise_phase_dead_event(struct net_if * iface)634 static inline void ppp_mgmt_raise_phase_dead_event(struct net_if *iface)
635 {
636 	ARG_UNUSED(iface);
637 }
638 #endif
639 
640 /**
641  * @brief Send PPP Echo-Request to peer. We expect to receive Echo-Reply back.
642  *
643  * @param idx PPP network interface index
644  * @param timeout Amount of time to wait Echo-Reply. The value is in
645  * milliseconds.
646  *
647  * @return 0 if Echo-Reply was received, < 0 if there is a timeout or network
648  * index is not a valid PPP network index.
649  */
650 #if defined(CONFIG_NET_L2_PPP)
651 int net_ppp_ping(int idx, int32_t timeout);
652 #else
net_ppp_ping(int idx,int32_t timeout)653 static inline int net_ppp_ping(int idx, int32_t timeout)
654 {
655 	ARG_UNUSED(idx);
656 	ARG_UNUSED(timeout);
657 
658 	return -ENOTSUP;
659 }
660 #endif
661 
662 /**
663  * @brief Get PPP context information. This is only used by net-shell to
664  * print information about PPP.
665  *
666  * @param idx PPP network interface index
667  *
668  * @return PPP context or NULL if idx is invalid.
669  */
670 #if defined(CONFIG_NET_L2_PPP) && defined(CONFIG_NET_SHELL)
671 struct ppp_context *net_ppp_context_get(int idx);
672 #else
net_ppp_context_get(int idx)673 static inline struct ppp_context *net_ppp_context_get(int idx)
674 {
675 	ARG_UNUSED(idx);
676 
677 	return NULL;
678 }
679 #endif
680 
681 #ifdef __cplusplus
682 }
683 #endif
684 
685 /**
686  * @}
687  */
688 
689 #endif /* ZEPHYR_INCLUDE_NET_PPP_H_ */
690