root/usr.sbin/npppd/l2tp/l2tp.h
/*      $OpenBSD: l2tp.h,v 1.15 2024/02/26 08:29:37 yasuoka Exp $       */

/*-
 * Copyright (c) 2009 Internet Initiative Japan Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef L2TP_H
#define L2TP_H 1
/*@file
 * header file for the L2TP module
 */
/* $Id: l2tp.h,v 1.15 2024/02/26 08:29:37 yasuoka Exp $ */

/************************************************************************
 * Protocol Constants
 ************************************************************************/

#define L2TP_RFC2661_VERSION                    1
#define L2TP_RFC2661_REVISION                   0
#define L2TP_AVP_MAXSIZ                         1024

/* Header */

#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

/* AVP Attribute Types */

/* RFC 2661 */
#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


/* RFC 3301 */
#define L2TP_AVP_TYPE_TX_MINIMUM                40
#define L2TP_AVP_TYPE_CALLING_SUB_ADDRESS       44

/* RFC 3145 */
#define L2TP_AVP_TYPE_PPP_DISCONNECT_CAUSE_CODE 46

/* RFC 3308 */
#define L2TP_AVP_TYPE_CCDS                      47
#define L2TP_AVP_TYPE_SDS                       48

/* RFC 3437 */
#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

/* RFC 3573 */
#define L2TP_AVP_TYPE_MODEM_ON_HOLD_CAPABLE     53
#define L2TP_AVP_TYPE_MODEM_ON_HOLD_STATUS      54

/* RFC 3817 */
#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

/* No RFC yet */
#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_TX_CONNECT_SPEED          74 */
/* #define      L2TP_AVP_TYPE_RX_CONNECT_SPEED          75 */
#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

/* RFC 4045 */
#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

/* Control Message Type */

#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

/*
 * Constants on pp.19-22 of RFC2661
 * macro names may be inappropriate.
 */
#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

/* Proxy Authen Type */
#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

/************************************************************************
 * Implementation Specific Constants
 ************************************************************************/
#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

/** maximum number of addresses we will listen on */
#ifndef L2TP_NLISTENER
#define L2TP_NLISTENER                          6
#endif

/*
 * state of daemon
 */
#define L2TPD_STATE_INIT                        0
#define L2TPD_STATE_RUNNING                     1
#define L2TPD_STATE_SHUTTING_DOWN               2
#define L2TPD_STATE_STOPPED                     3

/*
 * state of a control connection
 */
#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

/*
 * state of a call
 */
#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

/*
 * timeout
 */
#define L2TP_CTRL_CTRL_PKT_TIMEOUT              12
/** wait time for the first call */
#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

/** returns whether an L2TP daemon is stopped */
#define l2tpd_is_stopped(l2tpd)                                 \
        (((l2tpd)->state != L2TPD_STATE_SHUTTING_DOWN &&        \
            (l2tpd)->state != L2TPD_STATE_RUNNING)? 1 : 0)

/** returns whether an L2TP daemon is going to shutdown */
#define l2tpd_is_shutting_down(l2tpd)                           \
        (((l2tpd)->state == L2TPD_STATE_SHUTTING_DOWN)? 1 : 0)

/** macro to retrieve a physical layer label from l2tp_ctrl */
#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

/** datatype represents L2TP daemon */
struct _l2tpd;

typedef struct _l2tpd_listener {
        /* configuration */
        struct l2tp_conf *conf;
        /** event context */
        struct event ev_sock;
        /** L2TPD itself */
        struct _l2tpd   *self;
        /** index number */
        uint16_t        index;
        /** enable/disable */
        uint16_t        enabled;
        /** listening socket */
        int             sock;
        /** listening socket address for UDP packets */
        union {
                struct sockaddr_in      sin4;
                struct sockaddr_in6     sin6;
        } bind;
        /** tunnel name */
        char    tun_name[L2TP_NAME_LEN];
} l2tpd_listener;

/** datatype represents L2TP daemon */
typedef struct _l2tpd {
        /** timeout event context */
        struct event ev_timeout;
        /** instance ID */
        u_int id;
        /** listener list */
        slist listener;
        /** state */
        int state;
        /** mappings from tunnel ID to {@link ::_l2tp_ctrl L2TP control} */
        hash_table *ctrl_map;
        /** unique and free Session-ID list */
        slist free_session_id_list;

        /** flags */
        uint32_t
            purge_ipsec_sa:1;
} l2tpd;

/** datatype represents L2TP control connection */
typedef struct _l2tp_ctrl {
        struct event ev_timeout;
        /** ID */
        u_int id;
        /** parent L2TPD */
        l2tpd   *l2tpd;
        /** listener index number */
        uint16_t        listener_index;
        /** state */
        int     state;
        /** tunnel Id */
        int     tunnel_id;
        /** window size */
        int     winsz;
        /** peer's tunnel Id */
        int     peer_tunnel_id;
        /** peer's window size */
        int     peer_winsz;
        /** next acknowledgement number */
        uint16_t        snd_una;
        /** next send sequence number */
        uint16_t        snd_nxt;
        /** last send sequence number */
        uint16_t        snd_last;
        /** last send ack number */
        uint16_t        snd_lastnr;
        /** receive sequence number */
        uint16_t        rcv_nxt;
        /** peer's IP address */
        struct  sockaddr_storage peer;
        /** my IP address */
        struct  sockaddr_storage sock;
        /** IPSEC NAT-T SA cookie */
        void    *sa_cookie;

        /** list of L2TP calls */
        slist   call_list;
        /*
         * Note about send window:
         *      pos == lim when buffer is full.
         *      pos == -1, lim == 0 when buffer is empty.
         */
        /** bytes available in send buffer.  it is a list of length #winsz */
        bytebuffer **snd_buffers;
        int snd_buffercnt;
        /** sending buffer for ZLB */
        bytebuffer *zlb_buffer;

        /** the time when last control message sent */
        time_t  last_snd_ctrl;
        /** the time when last packet received */
        time_t  last_rcv;

        /**
         * If we are on active close and have not sent a StopCCN message yet,
         * active_closing has the result code to be in the StopCCN message.
         */
        int     active_closing;

        /**
         * delay between transition to idle state and sending HELLO in seconds.
         */
        int hello_interval;
        /** HELLO timeout */
        int hello_timeout;
        /** time when the last HELLO packet was sent */
        time_t  hello_io_time;
        /** number of calls established */
        int     ncalls;

        unsigned int /** use sequence number in L2TP Data Message? */
            data_use_seq:1,
            /** waiting to acknowledge HELLO? */
            hello_wait_ack:1;

} l2tp_ctrl;

/**
 * datatype represents a L2TP call
 */
typedef struct _l2tp_call {
        /** ID */
        u_int           id;
        /** state */
        int             state;
        /** parent control connection */
        l2tp_ctrl       *ctrl;
        /** bound {@link ::_npppd_ppp ppp} */
        void            *ppp;
        /** session ID */
        uint16_t        session_id;
        /** peer's session ID */
        uint16_t        peer_session_id;
        /** next sequence number  */
        uint16_t        snd_nxt;
        /** receiving sequence number */
        uint16_t        rcv_nxt;
        /** calling number */
        char            calling_number[32];

        uint32_t        /** Sequencing required */
                        seq_required:1,
                        /** Use sequencing in the data connection */
                        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