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