#ifndef L2TP_H
#define L2TP_H 1
#define L2TP_RFC2661_VERSION 1
#define L2TP_RFC2661_REVISION 0
#define L2TP_AVP_MAXSIZ 1024
#define L2TP_HEADER_FLAG_TOM 0x8000
#define L2TP_HEADER_FLAG_LENGTH 0x4000
#define L2TP_HEADER_FLAG_SEQUENCE 0x0800
#define L2TP_HEADER_FLAG_OFFSET 0x0200
#define L2TP_HEADER_FLAG_PRIORITY 0x0100
#define L2TP_HEADER_FLAG_VERSION_MASK 0x000f
#define L2TP_HEADER_VERSION_RFC2661 0x02
#define L2TP_AVP_TYPE_MESSAGE_TYPE 0
#define L2TP_AVP_TYPE_RESULT_CODE 1
#define L2TP_AVP_TYPE_PROTOCOL_VERSION 2
#define L2TP_AVP_TYPE_FRAMING_CAPABILITIES 3
#define L2TP_AVP_TYPE_BEARER_CAPABILITIES 4
#define L2TP_AVP_TYPE_TIE_BREAKER 5
#define L2TP_AVP_TYPE_FIRMWARE_REVISION 6
#define L2TP_AVP_TYPE_HOST_NAME 7
#define L2TP_AVP_TYPE_VENDOR_NAME 8
#define L2TP_AVP_TYPE_ASSINGED_TUNNEL_ID 9
#define L2TP_AVP_TYPE_RECV_WINDOW_SIZE 10
#define L2TP_AVP_TYPE_CHALLENGE 11
#define L2TP_AVP_TYPE_CAUSE_CODE 12
#define L2TP_AVP_TYPE_CHALLENGE_RESPONSE 13
#define L2TP_AVP_TYPE_ASSIGNED_SESSION_ID 14
#define L2TP_AVP_TYPE_CALL_SERIAL_NUMBER 15
#define L2TP_AVP_TYPE_MINIMUM_BPS 16
#define L2TP_AVP_TYPE_MAXIMUM_BPS 17
#define L2TP_AVP_TYPE_BEARER_TYPE 18
#define L2TP_AVP_TYPE_FRAMING_TYPE 19
#define L2TP_AVP_TYPE_CALLED_NUMBER 21
#define L2TP_AVP_TYPE_CALLING_NUMBER 22
#define L2TP_AVP_TYPE_SUB_ADDRESS 23
#define L2TP_AVP_TYPE_TX_CONNECT_SPEED 24
#define L2TP_AVP_TYPE_PHYSICAL_CHANNEL_ID 25
#define L2TP_AVP_TYPE_INITIAL_RECV_LCP_CONFREQ 26
#define L2TP_AVP_TYPE_LAST_SENT_LCP_CONFREQ 27
#define L2TP_AVP_TYPE_LAST_RECV_LCP_CONFREQ 28
#define L2TP_AVP_TYPE_PROXY_AUTHEN_TYPE 29
#define L2TP_AVP_TYPE_PROXY_AUTHEN_NAME 30
#define L2TP_AVP_TYPE_PROXY_AUTHEN_CHALLENGE 31
#define L2TP_AVP_TYPE_PROXY_AUTHEN_ID 32
#define L2TP_AVP_TYPE_PROXY_AUTHEN_RESPONSE 33
#define L2TP_AVP_TYPE_CALL_ERRORS 34
#define L2TP_AVP_TYPE_ACCM 35
#define L2TP_AVP_TYPE_RANDOM_VECTOR 36
#define L2TP_AVP_TYPE_PRIVATE_GROUP_ID 37
#define L2TP_AVP_TYPE_RX_CONNECT_SPEED 38
#define L2TP_AVP_TYPE_SEQUENCING_REQUIRED 39
#define L2TP_AVP_TYPE_TX_MINIMUM 40
#define L2TP_AVP_TYPE_CALLING_SUB_ADDRESS 44
#define L2TP_AVP_TYPE_PPP_DISCONNECT_CAUSE_CODE 46
#define L2TP_AVP_TYPE_CCDS 47
#define L2TP_AVP_TYPE_SDS 48
#define L2TP_AVP_TYPE_LCP_WANT_OPTIONS 49
#define L2TP_AVP_TYPE_LCP_ALLOW_OPTIONS 50
#define L2TP_AVP_TYPE_LNS_LAST_SENT_LCP_CONFREQ 51
#define L2TP_AVP_TYPE_LNS_LAST_RECV_LCP_CONFREQ 52
#define L2TP_AVP_TYPE_MODEM_ON_HOLD_CAPABLE 53
#define L2TP_AVP_TYPE_MODEM_ON_HOLD_STATUS 54
#define L2TP_AVP_TYPE_PPPOE_RELAY 55
#define L2TP_AVP_TYPE_PPPOE_RELAY_RESP_CAP 56
#define L2TP_AVP_TYPE_PPPOE_RELAY_FORW_CAP 57
#define L2TP_AVP_TYPE_EXTENDED_VENDOR_ID 58
#define L2TP_AVP_TYPE_PSEUDOWIRE_CAP_LIST 62
#define L2TP_AVP_TYPE_LOCAL_SESSION_ID 63
#define L2TP_AVP_TYPE_REMOTE_SESSION_ID 64
#define L2TP_AVP_TYPE_ASSIGNED_COOKIE 65
#define L2TP_AVP_TYPE_REMOTE_END_ID 66
#define L2TP_AVP_TYPE_APPLICATION_CODE 67
#define L2TP_AVP_TYPE_PSEUDOWIRE_TYPE 68
#define L2TP_AVP_TYPE_L2_SPECIFIC_SUBLAYER 69
#define L2TP_AVP_TYPE_DATA_SEQUENCING 70
#define L2TP_AVP_TYPE_CIRCUIT_STATUS 71
#define L2TP_AVP_TYPE_PREFERRED_LANGUAGE 72
#define L2TP_AVP_TYPE_CTRL_MSG_AUTH_NONCE 73
#define L2TP_AVP_TYPE_FAILOVER_CAPABILITY 76
#define L2TP_AVP_TYPE_TUNNEL_RECOVERY 77
#define L2TP_AVP_TYPE_SUGGESTED_CTRL_SEQUENCE 78
#define L2TP_AVP_TYPE_FAILOVER_SESSION_STATE 79
#define L2TP_AVP_TYPE_MULTICAST_CAPABILITY 80
#define L2TP_AVP_TYPE_NEW_OUTGOING_SESSIONS 81
#define L2TP_AVP_TYPE_NEW_OUTGOING_SESSIONS_ACK 82
#define L2TP_AVP_TYPE_WITHDRAW_OUTGOING_SESSIONS 83
#define L2TP_AVP_TYPE_MULTICAST_PACKETS_PRIORITY 84
#define L2TP_AVP_MESSAGE_TYPE_SCCRQ 1
#define L2TP_AVP_MESSAGE_TYPE_SCCRP 2
#define L2TP_AVP_MESSAGE_TYPE_SCCCN 3
#define L2TP_AVP_MESSAGE_TYPE_StopCCN 4
#define L2TP_AVP_MESSAGE_TYPE_HELLO 6
#define L2TP_AVP_MESSAGE_TYPE_OCRQ 7
#define L2TP_AVP_MESSAGE_TYPE_OCRP 8
#define L2TP_AVP_MESSAGE_TYPE_OCCN 9
#define L2TP_AVP_MESSAGE_TYPE_ICRQ 10
#define L2TP_AVP_MESSAGE_TYPE_ICRP 11
#define L2TP_AVP_MESSAGE_TYPE_ICCN 12
#define L2TP_AVP_MESSAGE_TYPE_CDN 14
#define L2TP_FRAMING_CAP_FLAGS_SYNC 0x00000001
#define L2TP_FRAMING_CAP_FLAGS_ASYNC 0x00000002
#define L2TP_BEARER_CAP_FLAGS_DIGITAL 0x00000001
#define L2TP_BEARER_CAP_FLAGS_ANALOG 0x00000002
#define L2TP_STOP_CCN_RCODE_GENERAL 1
#define L2TP_STOP_CCN_RCODE_GENERAL_ERROR 2
#define L2TP_STOP_CCN_RCODE_ALREADY_EXISTS 3
#define L2TP_STOP_CCN_RCODE_UNAUTHORIZED 4
#define L2TP_STOP_CCN_RCODE_BAD_PROTOCOL_VERSION 5
#define L2TP_STOP_CCN_RCODE_SHUTTING_DOWN 6
#define L2TP_STOP_CCN_RCODE_FSM_ERROR 7
#define L2TP_CDN_RCODE_LOST_CARRIER 1
#define L2TP_CDN_RCODE_ERROR_CODE 2
#define L2TP_CDN_RCODE_ADMINISTRATIVE_REASON 3
#define L2TP_CDN_RCODE_TEMP_NOT_AVALIABLE 4
#define L2TP_CDN_RCODE_PERM_NOT_AVALIABLE 5
#define L2TP_CDN_RCODE_INVALID_DESTINATION 6
#define L2TP_CDN_RCODE_NO_CARRIER 7
#define L2TP_CDN_RCODE_BUSY 8
#define L2TP_CDN_RCODE_NO_DIALTONE 9
#define L2TP_CDN_RCODE_CALL_TIMEOUT_BY_LAC 10
#define L2TP_CDN_RCODE_NO_FRAMING_DETECTED 11
#define L2TP_ECODE_NO_CONTROL_CONNECTION 1
#define L2TP_ECODE_WRONG_LENGTH 2
#define L2TP_ECODE_INVALID_MESSAGE 3
#define L2TP_ECODE_NO_RESOURCE 4
#define L2TP_ECODE_INVALID_SESSION_ID 5
#define L2TP_ECODE_GENERIC_ERROR 6
#define L2TP_ECODE_TRY_ANOTHER 7
#define L2TP_ECODE_UNKNOWN_MANDATORY_AVP 8
#define L2TP_AUTH_TYPE_RESERVED 0
#define L2TP_AUTH_TYPE_TEXUAL 1
#define L2TP_AUTH_TYPE_PPP_CHAP 2
#define L2TP_AUTH_TYPE_PPP_PAP 3
#define L2TP_AUTH_TYPE_NO_AUTH 4
#define L2TP_AUTH_TYPE_MS_CHAP_V1 5
#include "l2tp_conf.h"
#define L2TPD_TUNNEL_HASH_SIZ 127
#define L2TPD_SND_BUFSIZ 2048
#define L2TPD_DEFAULT_SEND_WINSZ 4
#define L2TPD_DEFAULT_LAYER2_LABEL "L2TP"
#define L2TPD_DIALIN_LAYER2_LABEL "DialIn"
#define L2TPD_CONFIG_BUFSIZ 65535
#define L2TP_CTRL_WINDOW_SIZE 8
#ifndef L2TPD_VENDOR_NAME
#define L2TPD_VENDOR_NAME ""
#endif
#define L2TPD_DEFAULT_UDP_PORT 1701
#ifndef L2TP_NLISTENER
#define L2TP_NLISTENER 6
#endif
#define L2TPD_STATE_INIT 0
#define L2TPD_STATE_RUNNING 1
#define L2TPD_STATE_SHUTTING_DOWN 2
#define L2TPD_STATE_STOPPED 3
#define L2TP_CTRL_STATE_IDLE 0
#define L2TP_CTRL_STATE_WAIT_CTL_CONN 1
#define L2TP_CTRL_STATE_WAIT_CTL_REPLY 2
#define L2TP_CTRL_STATE_ESTABLISHED 3
#define L2TP_CTRL_STATE_CLEANUP_WAIT 4
#define L2TP_CALL_STATE_IDLE 0
#define L2TP_CALL_STATE_WAIT_CONN 1
#define L2TP_CALL_STATE_ESTABLISHED 2
#define L2TP_CALL_STATE_CLEANUP_WAIT 3
#define L2TP_CTRL_CTRL_PKT_TIMEOUT 12
#define L2TP_CTRL_WAIT_CALL_TIMEOUT 16
#define L2TP_CTRL_CLEANUP_WAIT_TIME 3
#define L2TP_CTRL_DEFAULT_HELLO_INTERVAL 60
#define L2TP_CTRL_DEFAULT_HELLO_TIMEOUT 30
#define L2TPD_SHUTDOWN_TIMEOUT 5
#define l2tpd_is_stopped(l2tpd) \
(((l2tpd)->state != L2TPD_STATE_SHUTTING_DOWN && \
(l2tpd)->state != L2TPD_STATE_RUNNING)? 1 : 0)
#define l2tpd_is_shutting_down(l2tpd) \
(((l2tpd)->state == L2TPD_STATE_SHUTTING_DOWN)? 1 : 0)
#define L2TP_CTRL_LISTENER_TUN_NAME(ctrl) \
((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \
(ctrl)->listener_index))->tun_name
#define L2TP_CTRL_CONF(ctrl) \
((l2tpd_listener *)slist_get(&(ctrl)->l2tpd->listener, \
(ctrl)->listener_index))->conf
#define L2TP_CALL_DELAY_LIMIT 64
struct _l2tpd;
typedef struct _l2tpd_listener {
struct l2tp_conf *conf;
struct event ev_sock;
struct _l2tpd *self;
uint16_t index;
uint16_t enabled;
int sock;
union {
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
} bind;
char tun_name[L2TP_NAME_LEN];
} l2tpd_listener;
typedef struct _l2tpd {
struct event ev_timeout;
u_int id;
slist listener;
int state;
hash_table *ctrl_map;
slist free_session_id_list;
uint32_t
purge_ipsec_sa:1;
} l2tpd;
typedef struct _l2tp_ctrl {
struct event ev_timeout;
u_int id;
l2tpd *l2tpd;
uint16_t listener_index;
int state;
int tunnel_id;
int winsz;
int peer_tunnel_id;
int peer_winsz;
uint16_t snd_una;
uint16_t snd_nxt;
uint16_t snd_last;
uint16_t snd_lastnr;
uint16_t rcv_nxt;
struct sockaddr_storage peer;
struct sockaddr_storage sock;
void *sa_cookie;
slist call_list;
bytebuffer **snd_buffers;
int snd_buffercnt;
bytebuffer *zlb_buffer;
time_t last_snd_ctrl;
time_t last_rcv;
int active_closing;
int hello_interval;
int hello_timeout;
time_t hello_io_time;
int ncalls;
unsigned int
data_use_seq:1,
hello_wait_ack:1;
} l2tp_ctrl;
typedef struct _l2tp_call {
u_int id;
int state;
l2tp_ctrl *ctrl;
void *ppp;
uint16_t session_id;
uint16_t peer_session_id;
uint16_t snd_nxt;
uint16_t rcv_nxt;
char calling_number[32];
uint32_t
seq_required:1,
use_seq:1;
} l2tp_call;
#ifdef __cplusplus
extern "C" {
#endif
l2tp_call *l2tp_call_create (void);
int l2tp_call_init (l2tp_call *, l2tp_ctrl *);
void l2tp_call_destroy (l2tp_call *, int);
void l2tp_call_admin_disconnect(l2tp_call *);
void l2tp_call_drop (l2tp_call *);
int l2tp_call_recv_packet (l2tp_ctrl *, l2tp_call *, int, u_char *, int);
void l2tp_call_ppp_input (l2tp_call *, u_char *, int, int);
void l2tp_ctrl_destroy (l2tp_ctrl *);
l2tp_ctrl *l2tp_ctrl_create (void);
void l2tp_ctrl_input (l2tpd *, int, struct sockaddr *, struct sockaddr *, void *, u_char *, int);
int l2tp_ctrl_send(l2tp_ctrl *, const void *, int);
int l2tp_ctrl_send_packet(l2tp_ctrl *, int, bytebuffer *);
int l2tp_ctrl_stop (l2tp_ctrl *, int);
bytebuffer *l2tp_ctrl_prepare_snd_buffer (l2tp_ctrl *, int);
void l2tp_ctrl_log (l2tp_ctrl *, int, const char *, ...) __attribute__((__format__ (__printf__, 3, 4)));
int l2tpd_init (l2tpd *);
void l2tpd_uninit (l2tpd *);
int l2tpd_assign_call (l2tpd *, l2tp_call *);
void l2tpd_release_call (l2tpd *, l2tp_call *);
int l2tpd_start (l2tpd *);
void l2tpd_stop (l2tpd *);
void l2tpd_stop_immediatly (l2tpd *);
l2tp_ctrl *l2tpd_get_ctrl (l2tpd *, u_int);
void l2tpd_add_ctrl (l2tpd *, l2tp_ctrl *);
void l2tpd_ctrl_finished_notify(l2tpd *);
void l2tpd_remove_ctrl (l2tpd *, u_int);
int l2tpd_add_listener (l2tpd *, int, struct l2tp_conf *, struct sockaddr *);
void l2tpd_log (l2tpd *, int, const char *, ...) __attribute__((__format__ (__printf__, 3, 4)));
int l2tpd_reload(l2tpd *, struct l2tp_confs *);
void l2tpd_log_access_deny(l2tpd *, const char *, struct sockaddr *);
#ifdef __cplusplus
}
#endif
#endif