1 /*
2 * Copyright (c) 2019-2020 Grinn
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);
9
10 #include <zephyr/net/net_pkt.h>
11
12 #include "ppp_internal.h"
13
pap_handle(struct ppp_context * ctx,struct net_if * iface,struct net_pkt * pkt)14 static enum net_verdict pap_handle(struct ppp_context *ctx,
15 struct net_if *iface,
16 struct net_pkt *pkt)
17 {
18 return ppp_fsm_input(&ctx->pap.fsm, PPP_PAP, pkt);
19 }
20
pap_config_info_add(struct ppp_fsm * fsm)21 static struct net_pkt *pap_config_info_add(struct ppp_fsm *fsm)
22 {
23 uint8_t payload[] = { 5, 'b', 'l', 'a', 'n', 'k',
24 5, 'b', 'l', 'a', 'n', 'k' };
25 struct net_pkt *pkt;
26
27 pkt = net_pkt_alloc_with_buffer(ppp_fsm_iface(fsm), sizeof(payload),
28 AF_UNSPEC, 0, PPP_BUF_ALLOC_TIMEOUT);
29 if (!pkt) {
30 return NULL;
31 }
32
33 (void)net_pkt_write(pkt, payload, sizeof(payload));
34
35 return pkt;
36 }
37
pap_config_info_ack(struct ppp_fsm * fsm,struct net_pkt * pkt,uint16_t length)38 static int pap_config_info_ack(struct ppp_fsm *fsm,
39 struct net_pkt *pkt,
40 uint16_t length)
41 {
42 /*
43 * We only support one way negotiation for now, so move to ACK_SENT
44 * phase right away.
45 */
46 if (fsm->state == PPP_REQUEST_SENT) {
47 ppp_change_state(fsm, PPP_ACK_SENT);
48 }
49
50 return 0;
51 }
52
pap_lower_down(struct ppp_context * ctx)53 static void pap_lower_down(struct ppp_context *ctx)
54 {
55 ppp_fsm_lower_down(&ctx->pap.fsm);
56 }
57
pap_lower_up(struct ppp_context * ctx)58 static void pap_lower_up(struct ppp_context *ctx)
59 {
60 ppp_fsm_lower_up(&ctx->pap.fsm);
61 }
62
pap_open(struct ppp_context * ctx)63 static void pap_open(struct ppp_context *ctx)
64 {
65 ppp_fsm_open(&ctx->pap.fsm);
66 }
67
pap_close(struct ppp_context * ctx,const uint8_t * reason)68 static void pap_close(struct ppp_context *ctx, const uint8_t *reason)
69 {
70 ppp_fsm_close(&ctx->pap.fsm, reason);
71 }
72
pap_up(struct ppp_fsm * fsm)73 static void pap_up(struct ppp_fsm *fsm)
74 {
75 struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
76 pap.fsm);
77
78 if (ctx->is_pap_up) {
79 return;
80 }
81
82 ctx->is_pap_up = true;
83
84 NET_DBG("[%s/%p] Current state %s (%d)", fsm->name, fsm,
85 ppp_state_str(fsm->state), fsm->state);
86
87 ppp_link_authenticated(ctx);
88 }
89
pap_down(struct ppp_fsm * fsm)90 static void pap_down(struct ppp_fsm *fsm)
91 {
92 struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
93 pap.fsm);
94
95 if (!ctx->is_pap_up) {
96 return;
97 }
98
99 ctx->is_pap_up = false;
100 }
101
pap_finished(struct ppp_fsm * fsm)102 static void pap_finished(struct ppp_fsm *fsm)
103 {
104 struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
105 pap.fsm);
106
107 if (!ctx->is_pap_open) {
108 return;
109 }
110
111 ctx->is_pap_open = false;
112 }
113
pap_proto_reject(struct ppp_fsm * fsm)114 static void pap_proto_reject(struct ppp_fsm *fsm)
115 {
116 ppp_fsm_lower_down(fsm);
117 }
118
pap_init(struct ppp_context * ctx)119 static void pap_init(struct ppp_context *ctx)
120 {
121 NET_DBG("proto %s (0x%04x) fsm %p", ppp_proto2str(PPP_PAP), PPP_PAP,
122 &ctx->pap.fsm);
123
124 memset(&ctx->pap.fsm, 0, sizeof(ctx->pap.fsm));
125
126 ppp_fsm_init(&ctx->pap.fsm, PPP_PAP);
127
128 ppp_fsm_name_set(&ctx->pap.fsm, ppp_proto2str(PPP_PAP));
129
130 ctx->pap.fsm.cb.up = pap_up;
131 ctx->pap.fsm.cb.down = pap_down;
132 ctx->pap.fsm.cb.finished = pap_finished;
133 ctx->pap.fsm.cb.proto_reject = pap_proto_reject;
134 ctx->pap.fsm.cb.config_info_add = pap_config_info_add;
135 ctx->pap.fsm.cb.config_info_ack = pap_config_info_ack;
136 }
137
138 PPP_PROTOCOL_REGISTER(PAP, PPP_PAP,
139 pap_init, pap_handle,
140 pap_lower_up, pap_lower_down,
141 pap_open, pap_close);
142