#ifndef _NPPPD_H
#define _NPPPD_H 1
#define PPP_HDRLEN 4
#define PPP_ALLSTATIONS 0xff
#define PPP_UI 0x03
#define PPP_PROTO_IP 0x0021
#define PPP_PROTO_MPPE 0x00FD
#define PPP_PROTO_LCP 0xC021
#define PPP_PROTO_PAP 0xC023
#define PPP_PROTO_LQR 0xC025
#define PPP_PROTO_CHAP 0xC223
#define PPP_PROTO_EAP 0xC227
#define PPP_PROTO_NCP 0x8000
#define NCP_CCP 0xfd
#define NCP_IPCP 0x21
#define NCP_IPV6CP 0x57
#define PPP_PROTO_ACSP 0x8235
#define PPP_LCP_MRU 1
#define PPP_LCP_ACCM 2
#define PPP_LCP_AUTH_PROTOCOL 3
#define PPP_LCP_QUALITY_PROTOCOL 4
#define PPP_LCP_MAGICNUMBER 5
#define PPP_LCP_PFC 7
#define PPP_LCP_ACFC 8
#define DEFAULT_MRU 1400
#define NPPPD_MIN_MRU 500
#define PPP_AUTH_PAP 0xc023
#define PPP_AUTH_CHAP 0xc223
#define PPP_AUTH_EAP 0xc227
#define PPP_AUTH_EAP_ANY 0x00
#define PPP_AUTH_EAP_IDENTITY 0x01
#define PPP_AUTH_EAP_NOTIFICATION 0x02
#define PPP_AUTH_EAP_NAK 0x03
#define PPP_AUTH_EAP_MD5_CHALLENGE 0x04
#define PPP_AUTH_EAP_OTP 0x05
#define PPP_AUTH_EAP_GTC 0x06
#define PPP_AUTH_EAP_TLS 0x0d
#define PPP_AUTH_EAP_EXPANDED_TYPES 0xFE
#define PPP_AUTH_EAP_EXPERIMENTAL_USE 0xFF
#define PPP_AUTH_CHAP_MD5 0x05
#define PPP_AUTH_CHAP_MS 0x80
#define PPP_AUTH_CHAP_MS_V2 0x81
#define MAX_USERNAME_LENGTH 256
#define MAX_PASSWORD_LENGTH 256
#define MAX_CHALLENGE_LENGTH 96
#define INADDR_IPCP_OBEY_REMOTE_REQ 0x00000000L
#define MPPE_KEYLEN 16
#define CCP_MPPE 0x12
#define CCP_MPPC_ALONE 0x00000001
#define CCP_MPPE_LM_40bit 0x00000010
#define CCP_MPPE_NT_40bit 0x00000020
#define CCP_MPPE_NT_128bit 0x00000040
#define CCP_MPPE_NT_56bit 0x00000080
#define CCP_MPPE_STATELESS 0x01000000
#define CCP_MPPE_KEYLENMASK 0x00000FF0
#define CCP_MPPE_HEADER_LEN 4
#define INADDR_USER_SELECT (htonl(0xFFFFFFFFL))
#define INADDR_NAS_SELECT (htonl(0xFFFFFFFEL))
#define DEFAULT_LCP_ECHO_INTERVAL 300
#define DEFAULT_LCP_ECHO_RETRY_INTERVAL 60
#define DEFAULT_LCP_ECHO_MAX_RETRIES 3
#define NPPPD_PHONE_NUMBER_LEN 32
typedef enum _npppd_ppp_disconnect_code {
PPP_DISCON_NO_INFORMATION = 0,
PPP_DISCON_ADMINITRATIVE = 1,
PPP_DISCON_LCP_RENEGOTIATION_DISABLED = 2,
PPP_DISCON_NORMAL = 3,
PPP_DISCON_COMPULSORY_ENCRYPTION_REQUIRED = 4,
PPP_DISCON_LCP_FSM_TIMEOUT = 5,
PPP_DISCON_RECOGNIZABLE_LCP = 6,
PPP_DISCON_LCP_MAGIC_NUMBER_ERROR = 7,
PPP_DISCON_LCP_TIMEOUT = 8,
PPP_DISCON_LCP_UNEXPECTED_ENDPOINT_DISC = 9,
PPP_DISCON_LCP_UNEXPECTED_MRRU = 10,
PPP_DISCON_LCP_UNEXPECTED_SHORT_SEQNUM = 11,
PPP_DISCON_LCP_COMPULSORY_CALL_BACK_REQUIRED = 12,
PPP_DISCON_AUTH_FSM_TIMEOUT = 13,
PPP_DISCON_AUTH_UNEXPECTED_AUTH_NAME = 14,
PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE= 15,
PPP_DISCON_AUTH_FAILED = 16,
PPP_DISCON_NCP_FSM_TIMEOUT = 17,
PPP_DISCON_NCP_NO_NCP_AVAILABLE = 18,
PPP_DISCON_NCP_NO_ACCEPTABLE_ADDRESS= 19,
PPP_DISCON_NCP_NO_PERMITTED_ADDRESS = 20
} npppd_ppp_disconnect_code;
typedef struct _npppd_ppp npppd_ppp;
#include "fsm.h"
#ifdef USE_NPPPD_RADIUS
#include <radius.h>
#include <radius_req.h>
#endif
typedef struct _lcp {
fsm fsm;
struct _opt {
uint8_t mru;
uint8_t pfc;
uint8_t acfc;
uint8_t pap;
uint8_t chap;
uint8_t chapms;
uint8_t chapms_v2;
uint8_t eap;
} opt;
uint32_t lastauth;
uint32_t magic_number;
uint32_t peer_magic_number;
struct evtimer_wrap timerctx;
int echo_interval;
int echo_max_retries;
int echo_retry_interval;
int echo_failures;
int8_t recv_reqs;
int8_t recv_ress;
uint32_t xxxmru;
int auth_order[16];
uint32_t
dialin_proxy:1,
dialin_proxy_lcp_renegotiation:1;
} lcp;
typedef struct _chap {
npppd_ppp *ppp;
struct evtimer_wrap timerctx;
uint32_t state;
char myname[80];
u_char name[MAX_USERNAME_LENGTH];
u_char chall[MAX_CHALLENGE_LENGTH];
int lchall;
u_char pktid;
u_char challid;
int type;
int ntry;
u_char authenticator[16];
#ifdef USE_NPPPD_RADIUS
RADIUS_REQUEST_CTX radctx;
#endif
} chap;
typedef struct _pap {
npppd_ppp *ppp;
uint32_t state;
u_char name[MAX_USERNAME_LENGTH];
int auth_id;
#ifdef USE_NPPPD_RADIUS
RADIUS_REQUEST_CTX radctx;
#endif
} pap;
#ifdef USE_NPPPD_EAP_RADIUS
#define PPP_EAP_FLAG_NAK_RESPONSE 0x01
typedef struct _eap {
npppd_ppp *ppp;
struct evtimer_wrap timerctx;
uint32_t state;
u_char eapid;
int ntry;
u_char name[MAX_USERNAME_LENGTH];
u_char authenticator[16];
#define RADIUS_ATTR_STATE_LEN 100
int name_len;
u_char attr_state[RADIUS_ATTR_STATE_LEN];
u_char attr_state_len;
unsigned int session_timeout;
u_char flags;
RADIUS_REQUEST_CTX radctx;
} eap;
#endif
typedef struct _ccp {
npppd_ppp *ppp;
fsm fsm;
uint32_t mppe_o_bits;
uint32_t mppe_p_bits;
uint mppe_rej;
} ccp;
typedef struct _ipcp {
fsm fsm;
npppd_ppp *ppp;
struct in_addr ip4_our;
struct in_addr dns_pri;
struct in_addr dns_sec;
struct in_addr nbns_pri;
struct in_addr nbns_sec;
} ipcp;
typedef int (*npppd_iofunc) (
npppd_ppp *ppp,
unsigned char *bytes,
int nbytes,
int flags
);
#define PPP_IO_FLAGS_MPPE_ENCRYPTED 0x0001
#define PPP_IO_FLAGS_DELAYED 0x0002
typedef void (*npppd_voidfunc) (
npppd_ppp *ppp
);
#ifdef USE_NPPPD_MPPE
#define MPPE_NOLDKEY 64
typedef struct _mppe_rc4 {
void *rc4ctx;
uint8_t stateless;
uint8_t resetreq;
uint8_t keylen;
uint8_t keybits;
uint16_t coher_cnt;
uint8_t master_key[MPPE_KEYLEN];
uint8_t session_key[MPPE_KEYLEN];
uint8_t (*old_session_keys)[MPPE_KEYLEN];
} mppe_rc4_t;
typedef struct _mppe {
npppd_ppp *ppp;
uint8_t master_key[MPPE_KEYLEN];
uint16_t pkt_cnt;
uint16_t
enabled :1,
required :1,
mode_auto :1,
mode_stateless :1,
reserved :12;
uint16_t keylenbits;
mppe_rc4_t send, recv;
} mppe;
#endif
typedef struct _npppd_phone_number {
#define NPPPD_AF_PHONE_NUMBER (AF_MAX + 0)
uint8_t pn_len;
sa_family_t pn_family;
char pn_number[NPPPD_PHONE_NUMBER_LEN + 1];
} npppd_phone_number;
struct _npppd_ppp {
npppd *pppd;
u_int id;
uint8_t *outpacket_buf;
npppd_iofunc send_packet;
npppd_iofunc recv_packet;
struct event idle_event;
int timeout_sec;
int tunnel_type;
uint16_t tunnel_session_id;
uint16_t mru;
uint16_t peer_mru;
void *phy_context;
char phy_label[16];
union {
struct sockaddr_in peer_in4;
struct sockaddr_in6 peer_in6;
#if defined(USE_NPPPD_PPPOE)
struct sockaddr_dl peer_dl;
#endif
npppd_phone_number peer_pn;
} phy_info;
char calling_number[NPPPD_PHONE_NUMBER_LEN + 1];
npppd_voidfunc phy_close;
void *realm;
lcp lcp;
chap chap;
pap pap;
#ifdef USE_NPPPD_EAP_RADIUS
eap eap;
#endif
ccp ccp;
ipcp ipcp;
char username[MAX_USERNAME_LENGTH];
int ifidx;
u_char *proxy_authen_resp;
int lproxy_authen_resp;
uint16_t peer_auth;
#ifdef USE_NPPPD_MPPE
uint8_t mppe_started;
mppe mppe;
#endif
struct sockaddr_npppd snp;
#define ppp_framed_ip_address snp.snp_addr
#define ppp_framed_ip_netmask snp.snp_mask
#define ppp_ip_assigned(p) (p->ppp_framed_ip_address.s_addr != 0)
void *assigned_pool;
struct in_addr acct_framed_ip_address;
struct in_addr realm_framed_ip_address;
struct in_addr realm_framed_ip_netmask;
uint8_t
has_acf:1,
adjust_mss:1,
auth_runonce:1,
use_pipex:1,
pipex_started:1,
pipex_enabled:1,
ingress_filter:1,
reserved:2;
uint8_t
assign_dynapool:1,
assigned_ip4_enabled:1,
assigned_ip4_rcvd:6;
uint8_t
log_dump_in:1,
log_dump_out:1,
log_rcvd:6;
uint8_t
logged_naked_ip:1,
logged_acct_start:1,
logged_no_address:1,
logged_rcvd:5;
time_t start_time;
time_t start_monotime;
time_t end_monotime;
uint32_t ipackets;
uint32_t opackets;
uint32_t ierrors;
uint32_t oerrors;
uint64_t ibytes;
uint64_t obytes;
int terminate_cause;
npppd_ppp_disconnect_code disconnect_code;
int16_t disconnect_proto;
int8_t disconnect_direction;
const char *disconnect_message;
struct ipcpstat *ipcpstat;
LIST_ENTRY(_npppd_ppp) ipcpstat_entry;
};
typedef struct _dialin_proxy_info {
struct proxy_lcp {
int ldata;
u_char data[256];
} last_sent_lcp,
last_recv_lcp;
int auth_id;
uint32_t auth_type;
char username[MAX_USERNAME_LENGTH];
u_char auth_chall[MAX_CHALLENGE_LENGTH];
int lauth_chall;
u_char auth_resp[MAX_PASSWORD_LENGTH];
int lauth_resp;
} dialin_proxy_info;
#define DIALIN_PROXY_IS_REQUESTED(dpi) \
(((dpi)->last_sent_lcp.ldata > 0)? 1 : 0)
#define MPPE_MUST_NEGO(ppp) \
(((ppp)->mppe.enabled != 0) && \
(((ppp)->peer_auth == PPP_AUTH_CHAP_MS_V2) || \
((ppp)->peer_auth == PPP_AUTH_EAP)))
#define MPPE_IS_REQUIRED(ppp) \
(((ppp)->mppe.enabled != 0) && ((ppp)->mppe.required != 0))
#define MPPE_SEND_READY(ppp) \
((ppp)->mppe_started != 0 && (ppp)->mppe.send.keybits > 0)
#define MPPE_RECV_READY(ppp) \
((ppp)->mppe_started != 0 && (ppp)->mppe.recv.keybits > 0)
#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 BCOPY(s, d, l) memcpy(d, s, l)
#define BZERO(s, n) memset(s, 0, n)
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
#define MAKEHEADER(p, t) { \
PUTCHAR(PPP_ALLSTATIONS, p); \
PUTCHAR(PPP_UI, p); \
PUTSHORT(t, p); }
#ifndef __printflike
#define __printflike(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#endif
#if !defined(USE_NPPPD_MPPE)
#define MRU_IPMTU(mru) (mru)
#define MRU_PKTLEN(mru, proto) (mru)
#else
#ifdef MRU_INCLUDES_MPPE_CCP
#define MRU_IPMTU(mru) ((mru) - CCP_MPPE_HEADER_LEN)
#define MRU_PKTLEN(mru, proto) (mru)
#else
#define MRU_IPMTU(mru) (mru)
#define MRU_PKTLEN(mru, proto) (((proto) == PPP_PROTO_MPPE) \
? (mru) + CCP_MPPE_HEADER_LEN : (mru))
#endif
#endif
#define PPP_FSM_CONFIG(_fsm, _memb, _val) \
do { \
(_fsm)->_memb = ((_val) == 0) \
? (_fsm)->_memb : (_val); \
} while (0 )
#ifdef __cplusplus
extern "C" {
#endif
npppd_ppp *ppp_create (void);
int ppp_init (npppd *, npppd_ppp *);
void ppp_start (npppd_ppp *);
int ppp_dialin_proxy_prepare (npppd_ppp *, dialin_proxy_info *);
void ppp_stop (npppd_ppp *, const char *);
void ppp_set_disconnect_cause (npppd_ppp *, npppd_ppp_disconnect_code, int, int, const char *);
void ppp_set_radius_terminate_cause(npppd_ppp *, int);
void ppp_destroy (void *);
void ppp_lcp_up (npppd_ppp *);
void ppp_lcp_finished (npppd_ppp *);
void ppp_phy_downed (npppd_ppp *);
void ppp_auth_ok (npppd_ppp *);
void ppp_ipcp_opened (npppd_ppp *);
void ppp_ccp_opened (npppd_ppp *);
void ppp_ccp_stopped (npppd_ppp *);
void ppp_output (npppd_ppp *, uint16_t, u_char, u_char, u_char *, int);
u_char *ppp_packetbuf (npppd_ppp *, int);
int ppp_log (npppd_ppp *, int, const char *, ...) __printflike(3,4);
void ppp_reset_idle_timeout(npppd_ppp *);
#ifdef USE_NPPPD_RADIUS
void ppp_process_radius_attrs (npppd_ppp *, RADIUS_PACKET *);
int ppp_set_radius_attrs_for_authreq (npppd_ppp *, radius_req_setting *, RADIUS_PACKET *);
#endif
struct tunnconf *ppp_get_tunnconf(npppd_ppp *);
void ccp_init (ccp *, npppd_ppp *);
void ipcp_init (ipcp *, npppd_ppp *);
void lcp_init (lcp *, npppd_ppp *);
void lcp_lowerup (lcp *);
void lcp_send_protrej(lcp *, u_char *, int );
int lcp_dialin_proxy(lcp *, dialin_proxy_info *, int, int);
void pap_init (pap *, npppd_ppp *);
int pap_start (pap *);
int pap_stop (pap *);
int pap_input (pap *, u_char *, int);
int pap_proxy_authen_prepare (pap *, dialin_proxy_info *);
void chap_init (chap *, npppd_ppp *);
void chap_stop (chap *);
void chap_start (chap *);
void chap_input (chap *, u_char *, int);
int chap_proxy_authen_prepare (chap *, dialin_proxy_info *);
#ifdef USE_NPPPD_EAP_RADIUS
void eap_init(eap *, npppd_ppp *);
void eap_stop(eap *);
void eap_start(eap *);
void eap_input(eap *, u_char *, int);
#endif
#ifdef USE_NPPPD_MPPE
void mppe_init (mppe *, npppd_ppp *);
void mppe_fini (mppe *);
void mppe_start (mppe *);
uint32_t mppe_create_our_bits (mppe *, uint32_t);
void mppe_input (mppe *, u_char *, int);
void mppe_recv_ccp_reset (mppe *);
void mppe_pkt_output (mppe *, uint16_t, u_char *, int);
#endif
#ifdef __cplusplus
}
#endif
#endif