#ifndef LWIP_HDR_PPP_IMPL_H
#define LWIP_HDR_PPP_IMPL_H
#include "netif/ppp/ppp_opts.h"
#if PPP_SUPPORT
#ifdef PPP_INCLUDE_SETTINGS_HEADER
#include "ppp_settings.h"
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/netif.h"
#include "lwip/def.h"
#include "lwip/timeouts.h"
#include "ppp.h"
#include "pppdebug.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PPP_CTRL_PBUF_UNKNOWN_SIZE 512
#define PPP_ADDRESS(p) (((u_char *)(p))[0])
#define PPP_CONTROL(p) (((u_char *)(p))[1])
#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3])
#define PPP_ALLSTATIONS 0xff
#define PPP_UI 0x03
#define PPP_FLAG 0x7e
#define PPP_ESCAPE 0x7d
#define PPP_TRANS 0x20
#define PPP_DEFMRU 1500
#if PPP_IPV4_SUPPORT
#define PPP_IP 0x21
#endif
#if 0#endif
#if VJ_SUPPORT
#define PPP_VJC_COMP 0x2d
#define PPP_VJC_UNCOMP 0x2f
#endif
#if PPP_IPV6_SUPPORT
#define PPP_IPV6 0x57
#endif
#if CCP_SUPPORT
#define PPP_COMP 0xfd
#endif
#define PPP_IPCP 0x8021
#if 0#endif
#if PPP_IPV6_SUPPORT
#define PPP_IPV6CP 0x8057
#endif
#if CCP_SUPPORT
#define PPP_CCP 0x80fd
#endif
#if ECP_SUPPORT
#define PPP_ECP 0x8053
#endif
#define PPP_LCP 0xc021
#if PAP_SUPPORT
#define PPP_PAP 0xc023
#endif
#if LQR_SUPPORT
#define PPP_LQR 0xc025
#endif
#if CHAP_SUPPORT
#define PPP_CHAP 0xc223
#endif
#if CBCP_SUPPORT
#define PPP_CBCP 0xc029
#endif
#if EAP_SUPPORT
#define PPP_EAP 0xc227
#endif
struct link_callbacks {
void (*connect) (ppp_pcb *pcb, void *ctx);
#if PPP_SERVER
void (*listen) (ppp_pcb *pcb, void *ctx);
#endif
void (*disconnect) (ppp_pcb *pcb, void *ctx);
err_t (*free) (ppp_pcb *pcb, void *ctx);
err_t (*write)(ppp_pcb *pcb, void *ctx, struct pbuf *p);
err_t (*netif_output)(ppp_pcb *pcb, void *ctx, struct pbuf *p, u_short protocol);
void (*send_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
void (*recv_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
};
enum NPmode {
NPMODE_PASS,
NPMODE_DROP,
NPMODE_ERROR,
NPMODE_QUEUE
};
#if PPP_STATS_SUPPORT
struct pppstat {
unsigned int ppp_ibytes;
unsigned int ppp_ipackets;
unsigned int ppp_ierrors;
unsigned int ppp_obytes;
unsigned int ppp_opackets;
unsigned int ppp_oerrors;
};
#if VJ_SUPPORT
struct vjstat {
unsigned int vjs_packets;
unsigned int vjs_compressed;
unsigned int vjs_searches;
unsigned int vjs_misses;
unsigned int vjs_uncompressedin;
unsigned int vjs_compressedin;
unsigned int vjs_errorin;
unsigned int vjs_tossed;
};
#endif
struct ppp_stats {
struct pppstat p;
#if VJ_SUPPORT
struct vjstat vj;
#endif
};
#if CCP_SUPPORT
struct compstat {
unsigned int unc_bytes;
unsigned int unc_packets;
unsigned int comp_bytes;
unsigned int comp_packets;
unsigned int inc_bytes;
unsigned int inc_packets;
unsigned int ratio;
};
struct ppp_comp_stats {
struct compstat c;
struct compstat d;
};
#endif
#endif
#if PPP_IDLETIMELIMIT
struct ppp_idle {
time_t xmit_idle;
time_t recv_idle;
};
#endif
#define EPD_NULL 0
#define EPD_LOCAL 1
#define EPD_IP 2
#define EPD_MAC 3
#define EPD_MAGIC 4
#define EPD_PHONENUM 5
#ifdef HAVE_MULTILINK
extern u8_t multilink;
extern u8_t doing_multilink;
extern u8_t multilink_master;
extern u8_t bundle_eof;
extern u8_t bundle_terminating;
#endif
#ifdef MAXOCTETS
extern unsigned int maxoctets;
extern int maxoctets_dir;
extern int maxoctets_timeout;
#define PPP_OCTETS_DIRECTION_SUM 0
#define PPP_OCTETS_DIRECTION_IN 1
#define PPP_OCTETS_DIRECTION_OUT 2
#define PPP_OCTETS_DIRECTION_MAXOVERAL 3
#define PPP_OCTETS_DIRECTION_MAXSESSION 4
#endif
#define PPP_DATAINPUT 0
struct protent {
u_short protocol;
void (*init) (ppp_pcb *pcb);
void (*input) (ppp_pcb *pcb, u_char *pkt, int len);
void (*protrej) (ppp_pcb *pcb);
void (*lowerup) (ppp_pcb *pcb);
void (*lowerdown) (ppp_pcb *pcb);
void (*open) (ppp_pcb *pcb);
void (*close) (ppp_pcb *pcb, const char *reason);
#if PRINTPKT_SUPPORT
int (*printpkt) (const u_char *pkt, int len,
void (*printer) (void *, const char *, ...),
void *arg);
#endif
#if PPP_DATAINPUT
void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len);
#endif
#if PRINTPKT_SUPPORT
const char *name;
const char *data_name;
#endif
#if PPP_OPTIONS
option_t *options;
void (*check_options) (void);
#endif
#if DEMAND_SUPPORT
int (*demand_conf) (int unit);
int (*active_pkt) (u_char *pkt, int len);
#endif
};
extern const struct protent* const protocols[];
#if PAP_SUPPORT
#define PAP_WITHPEER 0x1
#define PAP_PEER 0x2
#endif
#if CHAP_SUPPORT
#define CHAP_WITHPEER 0x4
#define CHAP_PEER 0x8
#endif
#if EAP_SUPPORT
#define EAP_WITHPEER 0x10
#define EAP_PEER 0x20
#endif
#if CHAP_SUPPORT
#define CHAP_MD5_WITHPEER 0x40
#define CHAP_MD5_PEER 0x80
#if MSCHAP_SUPPORT
#define CHAP_MS_SHIFT 8
#define CHAP_MS_WITHPEER 0x100
#define CHAP_MS_PEER 0x200
#define CHAP_MS2_WITHPEER 0x400
#define CHAP_MS2_PEER 0x800
#endif
#endif
#if CHAP_SUPPORT
#if MSCHAP_SUPPORT
#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5)
#else
#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5)
#endif
#else
#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE)
#endif
#if PPP_STATS_SUPPORT
struct pppd_stats {
unsigned int bytes_in;
unsigned int bytes_out;
unsigned int pkts_in;
unsigned int pkts_out;
};
#endif
int ppp_init(void);
ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb,
ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
void ppp_start(ppp_pcb *pcb);
void ppp_link_failed(ppp_pcb *pcb);
void ppp_link_end(ppp_pcb *pcb);
void ppp_input(ppp_pcb *pcb, struct pbuf *pb);
err_t ppp_write(ppp_pcb *pcb, struct pbuf *p);
void ppp_link_terminated(ppp_pcb *pcb);
void new_phase(ppp_pcb *pcb, int p);
int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp);
int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp);
#if PPP_IPV4_SUPPORT
int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask);
int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr);
#if 0#endif
#if LWIP_DNS
int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2);
int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2);
#endif
#if VJ_SUPPORT
int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid);
#endif
int sifup(ppp_pcb *pcb);
int sifdown (ppp_pcb *pcb);
u32_t get_mask(u32_t addr);
#endif
#if PPP_IPV6_SUPPORT
int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64);
int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64);
int sif6up(ppp_pcb *pcb);
int sif6down (ppp_pcb *pcb);
#endif
#if DEMAND_SUPPORT
int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode);
#endif
void ppp_netif_set_mtu(ppp_pcb *pcb, int mtu);
int ppp_netif_get_mtu(ppp_pcb *pcb);
#if CCP_SUPPORT
#if 0#endif
void ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method);
void ccp_reset_comp(ppp_pcb *pcb);
void ccp_reset_decomp(ppp_pcb *pcb);
#if 0#endif
#endif
#if PPP_IDLETIMELIMIT
int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip);
#endif
#if DEMAND_SUPPORT
int get_loop_output(void);
#endif
#if PPP_PROTOCOLNAME
const char * protocol_name(int proto);
#endif
#if PPP_STATS_SUPPORT
void print_link_stats(void);
void reset_link_stats(int u);
void update_link_stats(int u);
#endif
#define GETCHAR(c, cp) { \
(c) = *(cp)++; \
}
#define PUTCHAR(c, cp) { \
*(cp)++ = (u_char) (c); \
}
#define GETSHORT(s, cp) { \
(s) = *(cp)++ << 8; \
(s) |= *(cp)++; \
}
#define PUTSHORT(s, cp) { \
*(cp)++ = (u_char) ((s) >> 8); \
*(cp)++ = (u_char) (s); \
}
#define GETLONG(l, cp) { \
(l) = *(cp)++ << 8; \
(l) |= *(cp)++; (l) <<= 8; \
(l) |= *(cp)++; (l) <<= 8; \
(l) |= *(cp)++; \
}
#define PUTLONG(l, cp) { \
*(cp)++ = (u_char) ((l) >> 24); \
*(cp)++ = (u_char) ((l) >> 16); \
*(cp)++ = (u_char) ((l) >> 8); \
*(cp)++ = (u_char) (l); \
}
#define INCPTR(n, cp) ((cp) += (n))
#define DECPTR(n, cp) ((cp) -= (n))
#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0)
#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0)
#define UNTIMEOUT(f, a) sys_untimeout((f), (a))
#define BZERO(s, n) memset(s, 0, n)
#define BCMP(s1, s2, l) memcmp(s1, s2, l)
#define PRINTMSG(m, l) { ppp_info(("Remote message: %0.*v", l, m)); }
#define MAKEHEADER(p, t) { \
PUTCHAR(PPP_ALLSTATIONS, p); \
PUTCHAR(PPP_UI, p); \
PUTSHORT(t, p); }
void link_required(ppp_pcb *pcb);
void link_terminated(ppp_pcb *pcb);
void link_down(ppp_pcb *pcb);
void upper_layers_down(ppp_pcb *pcb);
void link_established(ppp_pcb *pcb);
void start_networks(ppp_pcb *pcb);
void continue_networks(ppp_pcb *pcb);
#if PPP_AUTH_SUPPORT
#if PPP_SERVER
int auth_check_passwd(ppp_pcb *pcb, char *auser, unsigned int userlen, char *apasswd, unsigned int passwdlen, const char **msg, int *msglen);
void auth_peer_fail(ppp_pcb *pcb, int protocol);
void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen);
#endif
void auth_withpeer_fail(ppp_pcb *pcb, int protocol);
void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor);
#endif
void np_up(ppp_pcb *pcb, int proto);
void np_down(ppp_pcb *pcb, int proto);
void np_finished(ppp_pcb *pcb, int proto);
#if PPP_AUTH_SUPPORT
int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server);
#endif
#if DEMAND_SUPPORT
void demand_conf (void);
void demand_block (void);
void demand_unblock (void);
void demand_discard (void);
void demand_rexmit (int, u32_t);
int loop_chars (unsigned char *, int);
int loop_frame (unsigned char *, int);
#endif
#ifdef HAVE_MULTILINK
void mp_check_options (void);
int mp_join_bundle (void);
void mp_exit_bundle (void);
void mp_bundle_terminated (void);
char *epdisc_to_str (struct epdisc *);
int str_to_epdisc (struct epdisc *, char *);
#else
#define mp_bundle_terminated()
#define mp_exit_bundle()
#define doing_multilink 0
#define multilink_master 0
#endif
void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg);
int ppp_slprintf(char *buf, int buflen, const char *fmt, ...);
int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args);
size_t ppp_strlcpy(char *dest, const char *src, size_t len);
size_t ppp_strlcat(char *dest, const char *src, size_t len);
void ppp_dbglog_impl(const char *fmt, ...);
void ppp_info_impl(const char *fmt, ...);
void ppp_notice_impl(const char *fmt, ...);
void ppp_warn_impl(const char *fmt, ...);
void ppp_error_impl(const char *fmt, ...);
void ppp_fatal_impl(const char *fmt, ...);
#define ppp_dbglog(x) do { if (LWIP_DEBUG_ENABLED(LOG_DEBUG)) { ppp_dbglog_impl x; }} while(0)
#define ppp_info(x) do { if (LWIP_DEBUG_ENABLED(LOG_INFO)) { ppp_info_impl x; }} while(0)
#define ppp_notice(x) do { if (LWIP_DEBUG_ENABLED(LOG_NOTICE)) { ppp_notice_impl x; }} while(0)
#define ppp_warn(x) do { if (LWIP_DEBUG_ENABLED(LOG_WARNING)) { ppp_warn_impl x; }} while(0)
#define ppp_error(x) do { if (LWIP_DEBUG_ENABLED(LOG_ERR)) { ppp_error_impl x; }} while(0)
#define ppp_fatal(x) do { if (LWIP_DEBUG_ENABLED(LOG_CRITICAL)) { ppp_fatal_impl x; }} while(0)
#if PRINTPKT_SUPPORT
void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif