/* $OpenBSD: pptp.h,v 1.12 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 PPTP_H #define PPTP_H 1 /* * PPTP protocol constants */ #define PPTP_MES_TYPE_CTRL 1 #define PPTP_MAGIC_COOKIE 0x1a2b3c4d #define PPTP_RFC_2637_VERSION 0x0100 #ifndef PPTP_MAX_CALL #define PPTP_MAX_CALL 8192 #endif /* Start-Control-Connection-Request */ #define PPTP_CTRL_MES_CODE_SCCRQ 1 /* Start-Control-Connection-Reply */ #define PPTP_CTRL_MES_CODE_SCCRP 2 /* Stop-Control-Connection-Request */ #define PPTP_CTRL_MES_CODE_StopCCRQ 3 /* Stop-Control-Connection-Reply */ #define PPTP_CTRL_MES_CODE_StopCCRP 4 /* Echo-Request */ #define PPTP_CTRL_MES_CODE_ECHO_RQ 5 /* Echo-Reply */ #define PPTP_CTRL_MES_CODE_ECHO_RP 6 /* Outgoing-Call-Request */ #define PPTP_CTRL_MES_CODE_OCRQ 7 /* Outgoing-Call-Reply */ #define PPTP_CTRL_MES_CODE_OCRP 8 /* Incoming-Call-Request */ #define PPTP_CTRL_MES_CODE_ICRQ 9 /* Incoming-Call-Reply */ #define PPTP_CTRL_MES_CODE_ICRP 10 /* Incoming-Call-Connected */ #define PPTP_CTRL_MES_CODE_ICCN 11 /* Call-Clear-Request */ #define PPTP_CTRL_MES_CODE_CCR 12 /* Call-Disconnect-Notify */ #define PPTP_CTRL_MES_CODE_CDN 13 /* Set-Link-Info */ #define PPTP_CTRL_MES_CODE_SLI 15 #define PPTP_CTRL_FRAMING_ASYNC 1 #define PPTP_CTRL_FRAMING_SYNC 2 #define PPTP_CTRL_BEARER_ANALOG 1 #define PPTP_CTRL_BEARER_DIGITAL 2 /* Result Code: Start-Control-Connection-Reply */ #define PPTP_SCCRP_RESULT_SUCCESS 1 #define PPTP_SCCRP_RESULT_GENERIC_ERROR 2 #define PPTP_SCCRP_RESULT_CHANNEL_EXISTS 3 #define PPTP_SCCRP_RESULT_NOT_AUTHORIZIZED 4 #define PPTP_SCCRP_RESULT_BAD_PROTOCOL_VERSION 5 /* General Error Code (RFC 2637 2.16 pp.36) */ #define PPTP_ERROR_NONE 0 #define PPTP_ERROR_NOT_CONNECTED 1 #define PPTP_ERROR_BAD_FORMAT 2 #define PPTP_ERROR_NO_RESOURCE 3 #define PPTP_ERROR_BAD_CALL 4 #define PPTP_ERROR_PAC_ERROR 5 /* Result Code: Outgoing-Call-Reply */ #define PPTP_OCRP_RESULT_CONNECTED 1 #define PPTP_OCRP_RESULT_GENERIC_ERROR 2 #define PPTP_OCRP_RESULT_NO_CARRIER 3 #define PPTP_OCRP_RESULT_BUSY 4 #define PPTP_OCRP_RESULT_NO_DIALTONE 5 #define PPTP_OCRP_RESULT_TIMEOUT 6 #define PPTP_OCRP_RESULT_DO_NOT_ACCEPT 7 /* Result Code: Echo-Reply */ #define PPTP_ECHO_RP_RESULT_OK 1 #define PPTP_ECHO_RP_RESULT_GENERIC_ERROR 2 /* Reason code of the Stop-Control-Connection-Request */ #define PPTP_StopCCRQ_REASON_NONE 1 #define PPTP_StopCCRQ_REASON_STOP_PROTOCOL 2 #define PPTP_StopCCRQ_REASON_STOP_LOCAL_SHUTDOWN 3 /* Result code of the Stop-Control-Connection-Response */ #define PPTP_StopCCRP_RESULT_OK 1 #define PPTP_StopCCRP_RESULT_GENERIC_ERROR 2 #define PPTP_CDN_RESULT_LOST_CARRIER 1 #define PPTP_CDN_RESULT_GENRIC_ERROR 2 #define PPTP_CDN_RESULT_ADMIN_SHUTDOWN 3 #define PPTP_CDN_RESULT_REQUEST 4 /* Default TCP port number */ #define PPTPD_DEFAULT_TCP_PORT 1723 #define PPTP_GRE_PROTOCOL_TYPE 0x880b #define PPTP_GRE_VERSION 1 /* * Constants of the NPPPD implementation */ #include "pptp_conf.h" /* pptpd status */ #define PPTPD_STATE_INIT 0 #define PPTPD_STATE_RUNNING 1 #define PPTPD_STATE_SHUTTING_DOWN 2 #define PPTPD_STATE_STOPPED 3 #define PPTPD_CONFIG_BUFSIZ 65535 #define PPTP_BACKLOG 32 #define PPTP_BUFSIZ 1024 #define PPTPD_DEFAULT_LAYER2_LABEL "PPTP" /* pptp control state code */ #define PPTP_CTRL_STATE_IDLE 0 #define PPTP_CTRL_STATE_WAIT_CTRL_REPLY 1 #define PPTP_CTRL_STATE_ESTABLISHED 2 #define PPTP_CTRL_STATE_WAIT_STOP_REPLY 3 #define PPTP_CTRL_STATE_DISPOSING 4 #ifndef PPTPD_DEFAULT_VENDOR_NAME #define PPTPD_DEFAULT_VENDOR_NAME "" #endif #ifndef PPTP_CALL_DEFAULT_MAXWINSZ #define PPTP_CALL_DEFAULT_MAXWINSZ 64 #endif /* Connection speed that notified by OCRP */ /* XXX: currently we use fixed value */ #ifndef PPTP_CALL_CONNECT_SPEED #define PPTP_CALL_CONNECT_SPEED 10000000 #endif /* Initial packet processing delay that notified by OCRP */ #ifndef PPTP_CALL_INITIAL_PPD #define PPTP_CALL_INITIAL_PPD 0 #endif /** * PPTP_CALL_DELAY_LIMIT indicates how many sequence number can be rewinded * by reordering. */ #define PPTP_CALL_DELAY_LIMIT 64 /* pptp call state machine */ #define PPTP_CALL_STATE_IDLE 0 #define PPTP_CALL_STATE_WAIT_CONN 1 #define PPTP_CALL_STATE_ESTABLISHED 2 #define PPTP_CALL_STATE_CLEANUP_WAIT 3 /* Timeout */ #define PPTPD_SHUTDOWN_TIMEOUT 5 #define PPTPD_IDLE_TIMEOUT 60 #define PPTP_CALL_CLEANUP_WAIT_TIME 3 #define PPTP_CTRL_DEFAULT_ECHO_INTERVAL 60 #define PPTP_CTRL_DEFAULT_ECHO_TIMEOUT 60 #define PPTP_CTRL_StopCCRP_WAIT_TIME 3 /* MAXIMUM bindable IP addresses */ #ifndef PPTP_NLISTENER #define PPTP_NLISTENER 6 #endif /* Utility macro */ #define pptpd_is_stopped(pptpd) \ (((pptpd)->state != PPTPD_STATE_SHUTTING_DOWN && \ (pptpd)->state != PPTPD_STATE_RUNNING)? 1 : 0) #define pptpd_is_shutting_down(pptpd) \ (((pptpd)->state == PPTPD_STATE_SHUTTING_DOWN)? 1 : 0) /* * types */ struct _pptpd; typedef struct _pptpd_listener { struct event ev_sock_gre; /* GRE event context */ struct _pptpd *self; uint16_t index; int sock; /* listing socket */ int sock_gre; /* GRE socket */ struct sockaddr_in bind_sin; /* listing TCP address */ struct sockaddr_in bind_sin_gre; /* listing GRE address */ char tun_name[PPTP_NAME_LEN]; struct pptp_conf *conf; } pptpd_listener; typedef struct _pptpd { unsigned id; slist listener; /* list of listeners */ int state; struct event ev_timer; /* timer event context */ slist ctrl_list; /* list of PPTP controls */ slist call_free_list; /* Free call lists */ hash_table *call_id_map; /* table to map between callid and call */ /* ipv4 networks that is permitted to connect */ uint32_t /* flags */ initialized:1; } pptpd; #define pptp_ctrl_sock_gre(ctrl) \ ((pptpd_listener *)slist_get(&(ctrl)->pptpd->listener,\ (ctrl)->listener_index))->sock_gre /* get listner's physical layer label from pptp_ctrl */ #define PPTP_CTRL_LISTENER_TUN_NAME(ctrl) \ ((pptpd_listener *)slist_get(&(ctrl)->pptpd->listener,\ (ctrl)->listener_index))->tun_name #define PPTP_CTRL_CONF(ctrl) \ ((pptpd_listener *)slist_get(&(ctrl)->pptpd->listener, \ (ctrl)->listener_index))->conf typedef struct _pptp_ctrl { pptpd *pptpd; /* parents */ uint16_t listener_index; unsigned id; int state; int sock; struct sockaddr_storage peer; struct sockaddr_storage our; struct event ev_sock; struct event ev_timer; int echo_interval; /* periods between idle state to ECHO transmit */ int echo_timeout; int send_ready; /* ready to send */ bytebuffer *recv_buf; bytebuffer *send_buf; slist call_list; time_t last_snd_ctrl; /* timestamp of latest ctrl message sent */ time_t last_rcv_ctrl; /* timestamp of latest ctrl message received */ uint32_t echo_seq; /* identifier of Echo Request */ uint16_t /* flags : processing I/O events */ on_io_event:1, reserved:15; } pptp_ctrl; typedef struct _pptp_call { pptp_ctrl *ctrl; /* parent */ unsigned id; int ifidx; /* receive interface index */ int state; unsigned peers_call_id; void *ppp; uint32_t snd_una; /* next ack notification */ uint32_t snd_nxt; /* next transmit sequence # */ uint32_t rcv_nxt; /* received sequence # */ uint32_t rcv_acked; /* latest acked received sequence # */ int winsz; /* current window size */ int maxwinsz; /* maximum window size */ int peers_maxwinsz; time_t last_io; } pptp_call; /* * function prototypes */ #ifdef __cplusplus extern "C" { #endif int pptpd_init (pptpd *); void pptpd_uninit (pptpd *); int pptpd_assign_call (pptpd *, pptp_call *); void pptpd_release_call (pptpd *, pptp_call *); int pptpd_start (pptpd *); void pptpd_stop (pptpd *); void pptpd_stop_immediatly (pptpd *); void pptpd_ctrl_finished_notify(pptpd *, pptp_ctrl *); int pptpd_add_listener(pptpd *, int, struct pptp_conf *, struct sockaddr *); pptp_ctrl *pptp_ctrl_create (void); int pptp_ctrl_init (pptp_ctrl *); int pptp_ctrl_start (pptp_ctrl *); void pptp_ctrl_stop (pptp_ctrl *, int); void pptp_ctrl_destroy (pptp_ctrl *); void pptp_ctrl_output (pptp_ctrl *, u_char *, int); pptp_call *pptp_call_create (void); int pptp_call_init (pptp_call *, pptp_ctrl *); int pptp_call_start (pptp_call *); int pptp_call_stop (pptp_call *); void pptp_call_destroy (pptp_call *); void pptp_call_input (pptp_call *, int, u_char *, int); void pptp_call_gre_input (pptp_call *, uint32_t, uint32_t, int, u_char *, int); void pptp_call_disconnect(pptp_call *, int, int, const char *); int pptpd_reload(pptpd *, struct pptp_confs *); #ifdef __cplusplus } #endif #endif