5113c1418d
In order to bring consistency in-tree, migrate all subsystems code to the new prefix <zephyr/...>. Note that the conversion has been scripted, refer to zephyrproject-rtos#45388 for more details. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
376 lines
8.1 KiB
C
376 lines
8.1 KiB
C
/*
|
|
* Copyright (c) 2019 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);
|
|
|
|
#include <zephyr/net/net_core.h>
|
|
#include <zephyr/net/net_pkt.h>
|
|
|
|
#include <zephyr/net/ppp.h>
|
|
|
|
#include "net_private.h"
|
|
|
|
#include "ppp_internal.h"
|
|
|
|
const char *ppp_phase_str(enum ppp_phase phase)
|
|
{
|
|
#if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) || defined(CONFIG_NET_SHELL)
|
|
switch (phase) {
|
|
case PPP_DEAD:
|
|
return "DEAD";
|
|
case PPP_ESTABLISH:
|
|
return "ESTABLISH";
|
|
case PPP_AUTH:
|
|
return "AUTH";
|
|
case PPP_NETWORK:
|
|
return "NETWORK";
|
|
case PPP_RUNNING:
|
|
return "RUNNING";
|
|
case PPP_TERMINATE:
|
|
return "TERMINATE";
|
|
}
|
|
#else
|
|
ARG_UNUSED(phase);
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
static void validate_phase_transition(enum ppp_phase current,
|
|
enum ppp_phase new)
|
|
{
|
|
static const uint8_t valid_transitions[] = {
|
|
[PPP_DEAD] = 1 << PPP_ESTABLISH,
|
|
[PPP_ESTABLISH] = 1 << PPP_DEAD |
|
|
1 << PPP_AUTH |
|
|
1 << PPP_TERMINATE,
|
|
[PPP_AUTH] = 1 << PPP_TERMINATE |
|
|
1 << PPP_NETWORK,
|
|
[PPP_NETWORK] = 1 << PPP_TERMINATE |
|
|
1 << PPP_RUNNING,
|
|
[PPP_RUNNING] = 1 << PPP_TERMINATE |
|
|
1 << PPP_NETWORK,
|
|
[PPP_TERMINATE] = 1 << PPP_DEAD,
|
|
};
|
|
|
|
if (!(valid_transitions[current] & 1 << new)) {
|
|
NET_DBG("Invalid phase transition: %s (%d) => %s (%d)",
|
|
ppp_phase_str(current), current,
|
|
ppp_phase_str(new), new);
|
|
}
|
|
}
|
|
#else
|
|
static inline void validate_phase_transition(enum ppp_phase current,
|
|
enum ppp_phase new)
|
|
{
|
|
ARG_UNUSED(current);
|
|
ARG_UNUSED(new);
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
void ppp_change_phase_debug(struct ppp_context *ctx, enum ppp_phase new_phase,
|
|
const char *caller, int line)
|
|
#else
|
|
void ppp_change_phase(struct ppp_context *ctx, enum ppp_phase new_phase)
|
|
#endif
|
|
{
|
|
NET_ASSERT(ctx);
|
|
|
|
if (ctx->phase == new_phase) {
|
|
return;
|
|
}
|
|
|
|
NET_ASSERT(new_phase >= PPP_DEAD &&
|
|
new_phase <= PPP_TERMINATE);
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
NET_DBG("[%p] phase %s (%d) => %s (%d) (%s():%d)",
|
|
ctx, ppp_phase_str(ctx->phase), ctx->phase,
|
|
ppp_phase_str(new_phase), new_phase, caller, line);
|
|
#endif
|
|
|
|
validate_phase_transition(ctx->phase, new_phase);
|
|
|
|
ctx->phase = new_phase;
|
|
|
|
if (ctx->phase == PPP_DEAD) {
|
|
ppp_mgmt_raise_phase_dead_event(ctx->iface);
|
|
} else if (ctx->phase == PPP_RUNNING) {
|
|
ppp_mgmt_raise_phase_running_event(ctx->iface);
|
|
}
|
|
}
|
|
|
|
const char *ppp_state_str(enum ppp_state state)
|
|
{
|
|
#if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) || defined(CONFIG_NET_SHELL)
|
|
switch (state) {
|
|
case PPP_INITIAL:
|
|
return "INITIAL";
|
|
case PPP_STARTING:
|
|
return "STARTING";
|
|
case PPP_CLOSED:
|
|
return "CLOSED";
|
|
case PPP_STOPPED:
|
|
return "STOPPED";
|
|
case PPP_CLOSING:
|
|
return "CLOSING";
|
|
case PPP_STOPPING:
|
|
return "STOPPING";
|
|
case PPP_REQUEST_SENT:
|
|
return "REQUEST_SENT";
|
|
case PPP_ACK_RECEIVED:
|
|
return "ACK_RECEIVED";
|
|
case PPP_ACK_SENT:
|
|
return "ACK_SENT";
|
|
case PPP_OPENED:
|
|
return "OPENED";
|
|
}
|
|
#else
|
|
ARG_UNUSED(state);
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
const char *ppp_pkt_type2str(enum ppp_packet_type type)
|
|
{
|
|
#if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) || defined(CONFIG_NET_SHELL)
|
|
switch (type) {
|
|
case PPP_CONFIGURE_REQ:
|
|
return "Configure-Req";
|
|
case PPP_CONFIGURE_ACK:
|
|
return "Configure-Ack";
|
|
case PPP_CONFIGURE_NACK:
|
|
return "Configure-Nack";
|
|
case PPP_CONFIGURE_REJ:
|
|
return "Configure-Rej";
|
|
case PPP_TERMINATE_REQ:
|
|
return "Terminate-Req";
|
|
case PPP_TERMINATE_ACK:
|
|
return "Terminate-Ack";
|
|
case PPP_CODE_REJ:
|
|
return "Code-Rej";
|
|
case PPP_PROTOCOL_REJ:
|
|
return "Protocol-Rej";
|
|
case PPP_ECHO_REQ:
|
|
return "Echo-Req";
|
|
case PPP_ECHO_REPLY:
|
|
return "Echo-Reply";
|
|
case PPP_DISCARD_REQ:
|
|
return "Discard-Req";
|
|
}
|
|
#else
|
|
ARG_UNUSED(type);
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
const char *ppp_proto2str(uint16_t proto)
|
|
{
|
|
#if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG)
|
|
switch (proto) {
|
|
case PPP_IP:
|
|
return "IPv4";
|
|
case PPP_IPV6:
|
|
return "IPv6";
|
|
case PPP_ECP:
|
|
return "ECP";
|
|
case PPP_CCP:
|
|
return "CCP";
|
|
case PPP_LCP:
|
|
return "LCP";
|
|
case PPP_IPCP:
|
|
return "IPCP";
|
|
case PPP_IPV6CP:
|
|
return "IPV6CP";
|
|
case PPP_PAP:
|
|
return "PAP";
|
|
case PPP_CHAP:
|
|
return "CHAP";
|
|
case PPP_EAP:
|
|
return "EAP";
|
|
}
|
|
#else
|
|
ARG_UNUSED(proto);
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
static void validate_state_transition(enum ppp_state current,
|
|
enum ppp_state new)
|
|
{
|
|
/* See RFC 1661 ch. 4.1 */
|
|
static const uint16_t valid_transitions[] = {
|
|
[PPP_INITIAL] = 1 << PPP_CLOSED |
|
|
1 << PPP_STARTING,
|
|
[PPP_STARTING] = 1 << PPP_INITIAL |
|
|
1 << PPP_REQUEST_SENT,
|
|
[PPP_CLOSED] = 1 << PPP_INITIAL |
|
|
1 << PPP_REQUEST_SENT,
|
|
[PPP_STOPPED] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSED |
|
|
1 << PPP_ACK_RECEIVED |
|
|
1 << PPP_REQUEST_SENT,
|
|
[PPP_CLOSING] = 1 << PPP_INITIAL |
|
|
1 << PPP_STOPPING |
|
|
1 << PPP_CLOSED,
|
|
[PPP_STOPPING] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_STOPPED,
|
|
[PPP_REQUEST_SENT] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_STOPPED |
|
|
1 << PPP_ACK_SENT |
|
|
1 << PPP_ACK_RECEIVED,
|
|
[PPP_ACK_RECEIVED] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_OPENED |
|
|
1 << PPP_REQUEST_SENT |
|
|
1 << PPP_STOPPED,
|
|
[PPP_ACK_SENT] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_STOPPED |
|
|
1 << PPP_REQUEST_SENT |
|
|
1 << PPP_OPENED,
|
|
[PPP_OPENED] = 1 << PPP_STARTING |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_ACK_SENT |
|
|
1 << PPP_REQUEST_SENT |
|
|
1 << PPP_CLOSING |
|
|
1 << PPP_STOPPING,
|
|
};
|
|
|
|
if (!(valid_transitions[current] & 1 << new)) {
|
|
NET_DBG("Invalid state transition: %s (%d) => %s (%d)",
|
|
ppp_state_str(current), current,
|
|
ppp_state_str(new), new);
|
|
}
|
|
}
|
|
#else
|
|
static inline void validate_state_transition(enum ppp_state current,
|
|
enum ppp_state new)
|
|
{
|
|
ARG_UNUSED(current);
|
|
ARG_UNUSED(new);
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
void ppp_change_state_debug(struct ppp_fsm *fsm, enum ppp_state new_state,
|
|
const char *caller, int line)
|
|
#else
|
|
void ppp_change_state(struct ppp_fsm *fsm, enum ppp_state new_state)
|
|
#endif
|
|
{
|
|
NET_ASSERT(fsm);
|
|
|
|
if (fsm->state == new_state) {
|
|
return;
|
|
}
|
|
|
|
NET_ASSERT(new_state >= PPP_INITIAL &&
|
|
new_state <= PPP_OPENED);
|
|
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
NET_DBG("[%s/%p] state %s (%d) => %s (%d) (%s():%d)",
|
|
fsm->name, fsm, ppp_state_str(fsm->state), fsm->state,
|
|
ppp_state_str(new_state), new_state, caller, line);
|
|
#endif
|
|
|
|
validate_state_transition(fsm->state, new_state);
|
|
|
|
fsm->state = new_state;
|
|
}
|
|
|
|
const char *ppp_option2str(enum ppp_protocol_type protocol,
|
|
int type)
|
|
{
|
|
#if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) || defined(CONFIG_NET_SHELL)
|
|
switch (protocol) {
|
|
case PPP_LCP:
|
|
switch (type) {
|
|
case LCP_OPTION_RESERVED:
|
|
return "RESERVED";
|
|
case LCP_OPTION_MRU:
|
|
return "MRU";
|
|
case LCP_OPTION_ASYNC_CTRL_CHAR_MAP:
|
|
return "ASYNC_CTRL_CHAR_MAP";
|
|
case LCP_OPTION_AUTH_PROTO:
|
|
return "AUTH_PROTO";
|
|
case LCP_OPTION_QUALITY_PROTO:
|
|
return "QUALITY_PROTO";
|
|
case LCP_OPTION_MAGIC_NUMBER:
|
|
return "MAGIC_NUMBER";
|
|
case LCP_OPTION_PROTO_COMPRESS:
|
|
return "PROTO_COMPRESS";
|
|
case LCP_OPTION_ADDR_CTRL_COMPRESS:
|
|
return "ADDR_CTRL_COMPRESS";
|
|
}
|
|
|
|
break;
|
|
|
|
#if defined(CONFIG_NET_IPV4)
|
|
case PPP_IPCP:
|
|
switch (type) {
|
|
case IPCP_OPTION_RESERVED:
|
|
return "RESERVED";
|
|
case IPCP_OPTION_IP_ADDRESSES:
|
|
return "IP_ADDRESSES";
|
|
case IPCP_OPTION_IP_COMP_PROTO:
|
|
return "IP_COMPRESSION_PROTOCOL";
|
|
case IPCP_OPTION_IP_ADDRESS:
|
|
return "IP_ADDRESS";
|
|
case IPCP_OPTION_DNS1:
|
|
return "DNS1";
|
|
case IPCP_OPTION_NBNS1:
|
|
return "NBNS1";
|
|
case IPCP_OPTION_DNS2:
|
|
return "DNS2";
|
|
case IPCP_OPTION_NBNS2:
|
|
return "NBNS2";
|
|
}
|
|
|
|
break;
|
|
#endif
|
|
|
|
#if defined(CONFIG_NET_IPV6)
|
|
case PPP_IPV6CP:
|
|
switch (type) {
|
|
case IPV6CP_OPTION_RESERVED:
|
|
return "RESERVED";
|
|
case IPV6CP_OPTION_INTERFACE_IDENTIFIER:
|
|
return "INTERFACE_IDENTIFIER";
|
|
}
|
|
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
#else
|
|
ARG_UNUSED(type);
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
void ppp_fsm_name_set(struct ppp_fsm *fsm, const char *name)
|
|
{
|
|
#if CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG
|
|
fsm->name = name;
|
|
#else
|
|
ARG_UNUSED(fsm);
|
|
ARG_UNUSED(name);
|
|
#endif
|
|
}
|