#include "netif/ppp/ppp_opts.h"
#if PPP_SUPPORT
#ifndef PPP_H
#define PPP_H
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#if PPP_IPV6_SUPPORT
#include "lwip/ip6_addr.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PPP_OPTIONS
#define PPP_OPTIONS 0
#endif
#ifndef PPP_NOTIFY
#define PPP_NOTIFY 0
#endif
#ifndef PPP_REMOTENAME
#define PPP_REMOTENAME 0
#endif
#ifndef PPP_IDLETIMELIMIT
#define PPP_IDLETIMELIMIT 0
#endif
#ifndef PPP_LCP_ADAPTIVE
#define PPP_LCP_ADAPTIVE 0
#endif
#ifndef PPP_MAXCONNECT
#define PPP_MAXCONNECT 0
#endif
#ifndef PPP_ALLOWED_ADDRS
#define PPP_ALLOWED_ADDRS 0
#endif
#ifndef PPP_PROTOCOLNAME
#define PPP_PROTOCOLNAME 0
#endif
#ifndef PPP_STATS_SUPPORT
#define PPP_STATS_SUPPORT 0
#endif
#ifndef DEFLATE_SUPPORT
#define DEFLATE_SUPPORT 0
#endif
#ifndef BSDCOMPRESS_SUPPORT
#define BSDCOMPRESS_SUPPORT 0
#endif
#ifndef PREDICTOR_SUPPORT
#define PREDICTOR_SUPPORT 0
#endif
#define PPP_HDRLEN 4
#define PPP_FCSLEN 2
#define PPP_PHASE_DEAD 0
#define PPP_PHASE_MASTER 1
#define PPP_PHASE_HOLDOFF 2
#define PPP_PHASE_INITIALIZE 3
#define PPP_PHASE_SERIALCONN 4
#define PPP_PHASE_DORMANT 5
#define PPP_PHASE_ESTABLISH 6
#define PPP_PHASE_AUTHENTICATE 7
#define PPP_PHASE_CALLBACK 8
#define PPP_PHASE_NETWORK 9
#define PPP_PHASE_RUNNING 10
#define PPP_PHASE_TERMINATE 11
#define PPP_PHASE_DISCONNECT 12
#define PPPERR_NONE 0
#define PPPERR_PARAM 1
#define PPPERR_OPEN 2
#define PPPERR_DEVICE 3
#define PPPERR_ALLOC 4
#define PPPERR_USER 5
#define PPPERR_CONNECT 6
#define PPPERR_AUTHFAIL 7
#define PPPERR_PROTOCOL 8
#define PPPERR_PEERDEAD 9
#define PPPERR_IDLETIMEOUT 10
#define PPPERR_CONNECTTIME 11
#define PPPERR_LOOPBACK 12
#define PPP_AUTH_SUPPORT (PAP_SUPPORT || CHAP_SUPPORT || EAP_SUPPORT)
typedef struct ppp_pcb_s ppp_pcb;
#ifndef __u_char_defined
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
typedef unsigned char u_char;
#endif
#include "fsm.h"
#include "lcp.h"
#if CCP_SUPPORT
#include "ccp.h"
#endif
#if MPPE_SUPPORT
#include "mppe.h"
#endif
#if PPP_IPV4_SUPPORT
#include "ipcp.h"
#endif
#if PPP_IPV6_SUPPORT
#include "ipv6cp.h"
#endif
#if PAP_SUPPORT
#include "upap.h"
#endif
#if CHAP_SUPPORT
#include "chap-new.h"
#endif
#if EAP_SUPPORT
#include "eap.h"
#endif
#if VJ_SUPPORT
#include "vj.h"
#endif
typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx);
typedef struct ppp_settings_s {
#if PPP_SERVER && PPP_AUTH_SUPPORT
unsigned int auth_required :1;
unsigned int null_login :1;
#endif
#if PPP_REMOTENAME
unsigned int explicit_remote :1;
#endif
#if PAP_SUPPORT
unsigned int refuse_pap :1;
#endif
#if CHAP_SUPPORT
unsigned int refuse_chap :1;
#endif
#if MSCHAP_SUPPORT
unsigned int refuse_mschap :1;
unsigned int refuse_mschap_v2 :1;
#endif
#if EAP_SUPPORT
unsigned int refuse_eap :1;
#endif
#if LWIP_DNS
unsigned int usepeerdns :1;
#endif
unsigned int persist :1;
#if PRINTPKT_SUPPORT
unsigned int hide_password :1;
#endif
unsigned int noremoteip :1;
unsigned int lax_recv :1;
unsigned int noendpoint :1;
#if PPP_LCP_ADAPTIVE
unsigned int lcp_echo_adaptive :1;
#endif
#if MPPE_SUPPORT
unsigned int require_mppe :1;
unsigned int refuse_mppe_40 :1;
unsigned int refuse_mppe_128 :1;
unsigned int refuse_mppe_stateful :1;
#endif
u16_t listen_time;
#if PPP_IDLETIMELIMIT
u16_t idle_time_limit;
#endif
#if PPP_MAXCONNECT
u32_t maxconnect;
#endif
#if PPP_AUTH_SUPPORT
const char *user;
const char *passwd;
#if PPP_REMOTENAME
char remote_name[MAXNAMELEN + 1];
#endif
#if PAP_SUPPORT
u8_t pap_timeout_time;
u8_t pap_max_transmits;
#if PPP_SERVER
u8_t pap_req_timeout;
#endif
#endif
#if CHAP_SUPPORT
#if PPP_SERVER
u8_t chap_timeout_time;
u8_t chap_max_transmits;
u8_t chap_rechallenge_time;
#endif
#endif
#if EAP_SUPPORT
u8_t eap_req_time;
u8_t eap_allow_req;
#if PPP_SERVER
u8_t eap_timeout_time;
u8_t eap_max_transmits;
#endif
#endif
#endif
u8_t fsm_timeout_time;
u8_t fsm_max_conf_req_transmits;
u8_t fsm_max_term_transmits;
u8_t fsm_max_nak_loops;
u8_t lcp_loopbackfail;
u8_t lcp_echo_interval;
u8_t lcp_echo_fails;
} ppp_settings;
#if PPP_SERVER
struct ppp_addrs {
#if PPP_IPV4_SUPPORT
ip4_addr_t our_ipaddr, his_ipaddr, netmask;
#if LWIP_DNS
ip4_addr_t dns1, dns2;
#endif
#endif
#if PPP_IPV6_SUPPORT
ip6_addr_t our6_ipaddr, his6_ipaddr;
#endif
};
#endif
struct ppp_pcb_s {
ppp_settings settings;
const struct link_callbacks *link_cb;
void *link_ctx_cb;
void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx);
#if PPP_NOTIFY_PHASE
void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx);
#endif
void *ctx_cb;
struct netif *netif;
u8_t phase;
u8_t err_code;
#if PPP_IPV4_SUPPORT
unsigned int ask_for_local :1;
unsigned int ipcp_is_open :1;
unsigned int ipcp_is_up :1;
unsigned int if4_up :1;
#if 0#endif
#endif
#if PPP_IPV6_SUPPORT
unsigned int ipv6cp_is_up :1;
unsigned int if6_up :1;
#endif
unsigned int lcp_echo_timer_running :1;
#if VJ_SUPPORT
unsigned int vj_enabled :1;
#endif
#if CCP_SUPPORT
unsigned int ccp_all_rejected :1;
#endif
#if MPPE_SUPPORT
unsigned int mppe_keys_set :1;
#endif
#if PPP_AUTH_SUPPORT
#if PPP_SERVER && defined(HAVE_MULTILINK)
char peer_authname[MAXNAMELEN + 1];
#endif
u16_t auth_pending;
u16_t auth_done;
#if PAP_SUPPORT
upap_state upap;
#endif
#if CHAP_SUPPORT
chap_client_state chap_client;
#if PPP_SERVER
chap_server_state chap_server;
#endif
#endif
#if EAP_SUPPORT
eap_state eap;
#endif
#endif
fsm lcp_fsm;
lcp_options lcp_wantoptions;
lcp_options lcp_gotoptions;
lcp_options lcp_allowoptions;
lcp_options lcp_hisoptions;
u16_t peer_mru;
u8_t lcp_echos_pending;
u8_t lcp_echo_number;
u8_t num_np_open;
u8_t num_np_up;
#if VJ_SUPPORT
struct vjcompress vj_comp;
#endif
#if CCP_SUPPORT
fsm ccp_fsm;
ccp_options ccp_wantoptions;
ccp_options ccp_gotoptions;
ccp_options ccp_allowoptions;
ccp_options ccp_hisoptions;
u8_t ccp_localstate;
u8_t ccp_receive_method;
u8_t ccp_transmit_method;
#if MPPE_SUPPORT
ppp_mppe_state mppe_comp;
ppp_mppe_state mppe_decomp;
#endif
#endif
#if PPP_IPV4_SUPPORT
fsm ipcp_fsm;
ipcp_options ipcp_wantoptions;
ipcp_options ipcp_gotoptions;
ipcp_options ipcp_allowoptions;
ipcp_options ipcp_hisoptions;
#endif
#if PPP_IPV6_SUPPORT
fsm ipv6cp_fsm;
ipv6cp_options ipv6cp_wantoptions;
ipv6cp_options ipv6cp_gotoptions;
ipv6cp_options ipv6cp_allowoptions;
ipv6cp_options ipv6cp_hisoptions;
#endif
};
#if PPP_AUTH_SUPPORT
#define PPPAUTHTYPE_NONE 0x00
#define PPPAUTHTYPE_PAP 0x01
#define PPPAUTHTYPE_CHAP 0x02
#define PPPAUTHTYPE_MSCHAP 0x04
#define PPPAUTHTYPE_MSCHAP_V2 0x08
#define PPPAUTHTYPE_EAP 0x10
#define PPPAUTHTYPE_ANY 0xff
void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd);
#define ppp_set_auth_required(ppp, boolval) (ppp->settings.auth_required = boolval)
#endif
#if PPP_IPV4_SUPPORT
#define ppp_set_ipcp_ouraddr(ppp, addr) do { ppp->ipcp_wantoptions.ouraddr = ip4_addr_get_u32(addr); \
ppp->ask_for_local = ppp->ipcp_wantoptions.ouraddr != 0; } while(0)
#define ppp_set_ipcp_hisaddr(ppp, addr) (ppp->ipcp_wantoptions.hisaddr = ip4_addr_get_u32(addr))
#if LWIP_DNS
#define ppp_set_ipcp_dnsaddr(ppp, index, addr) (ppp->ipcp_allowoptions.dnsaddr[index] = ip4_addr_get_u32(addr))
#define ppp_set_usepeerdns(ppp, boolval) (ppp->settings.usepeerdns = boolval)
#endif
#endif
#if MPPE_SUPPORT
#define PPP_MPPE_DISABLE 0x00
#define PPP_MPPE_ENABLE 0x01
#define PPP_MPPE_ALLOW_STATEFUL 0x02
#define PPP_MPPE_REFUSE_40 0x04
#define PPP_MPPE_REFUSE_128 0x08
void ppp_set_mppe(ppp_pcb *pcb, u8_t flags);
#endif
#define ppp_set_listen_time(ppp, intval) (ppp->settings.listen_time = intval)
#define ppp_set_passive(ppp, boolval) (ppp->lcp_wantoptions.passive = boolval)
#define ppp_set_silent(ppp, boolval) (ppp->lcp_wantoptions.silent = boolval)
#define ppp_set_neg_pcomp(ppp, boolval) (ppp->lcp_wantoptions.neg_pcompression = \
ppp->lcp_allowoptions.neg_pcompression = boolval)
#define ppp_set_neg_accomp(ppp, boolval) (ppp->lcp_wantoptions.neg_accompression = \
ppp->lcp_allowoptions.neg_accompression = boolval)
#define ppp_set_neg_asyncmap(ppp, boolval) (ppp->lcp_wantoptions.neg_asyncmap = \
ppp->lcp_allowoptions.neg_asyncmap = boolval)
#define ppp_set_asyncmap(ppp, intval) (ppp->lcp_wantoptions.asyncmap = intval)
#define ppp_set_default(ppp) netif_set_default(ppp->netif)
#if PPP_NOTIFY_PHASE
typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx);
void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb);
#endif
err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff);
#if PPP_SERVER
err_t ppp_listen(ppp_pcb *pcb);
#endif
err_t ppp_close(ppp_pcb *pcb, u8_t nocarrier);
err_t ppp_free(ppp_pcb *pcb);
#define PPPCTLG_UPSTATUS 0
#define PPPCTLG_ERRCODE 1
#define PPPCTLG_FD 2
err_t ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg);
#define ppp_netif(ppp) (ppp->netif)
#define ppp_set_netif_statuscallback(ppp, status_cb) \
netif_set_status_callback(ppp->netif, status_cb);
#define ppp_set_netif_linkcallback(ppp, link_cb) \
netif_set_link_callback(ppp->netif, link_cb);
#ifdef __cplusplus
}
#endif
#endif
#endif