Annotation of embedaddon/libpdel/ppp/ppp_l2tp_ctrl.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (c) 2001-2002 Packet Design, LLC.
                      4:  * All rights reserved.
                      5:  * 
                      6:  * Subject to the following obligations and disclaimer of warranty,
                      7:  * use and redistribution of this software, in source or object code
                      8:  * forms, with or without modifications are expressly permitted by
                      9:  * Packet Design; provided, however, that:
                     10:  * 
                     11:  *    (i)  Any and all reproductions of the source or object code
                     12:  *         must include the copyright notice above and the following
                     13:  *         disclaimer of warranties; and
                     14:  *    (ii) No rights are granted, in any manner or form, to use
                     15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
                     16:  *         on advertising, endorsements, or otherwise except as such
                     17:  *         appears in the above copyright notice or in the software.
                     18:  * 
                     19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     36:  * THE POSSIBILITY OF SUCH DAMAGE.
                     37:  *
                     38:  * Author: Archie Cobbs <archie@freebsd.org>
                     39:  */
                     40: 
                     41: #include "ppp/ppp_defs.h"
                     42: #include "ppp/ppp_log.h"
                     43: #include "ppp/ppp_l2tp_avp.h"
                     44: #include "ppp/ppp_l2tp_ctrl.h"
                     45: #include <netgraph/ng_message.h>
                     46: #include <netgraph/ng_socket.h>
                     47: #include <netgraph/ng_l2tp.h>
                     48: #include <netgraph/ng_tee.h>
                     49: 
                     50: #ifndef __FreeBSD__
                     51: #define __printflike(x,y)
                     52: #endif
                     53: 
                     54: /*
                     55:  * Bugs:
                     56:  *
                     57:  * - We don't handle sending or receiving challenge/response
                     58:  */
                     59: 
                     60: #define CTRL_MEM_TYPE          "ppp_l2tp_ctrl"
                     61: #define SESS_MEM_TYPE          "ppp_l2tp_sess"
                     62: 
                     63: /* Retransmit timeout parameters */
                     64: #define L2TP_REXMIT_MAX                8
                     65: #define L2TP_REXMIT_MAX_TO     20
                     66: 
                     67: #define L2TP_CHALLENGE_LEN     16
                     68: 
                     69: #define L2TP_CONNECT_SPEED     10000000                /* XXX hardcoded */
                     70: #define L2TP_FRAMING_TYPE      L2TP_FRAMING_SYNC       /* XXX hardcoded */
                     71: 
                     72: /* Idle timeout for sending 'HELLO' message */
                     73: #define L2TP_IDLE_TIMEOUT      60
                     74: 
                     75: /* Reply timeout for messages */
                     76: #define L2TP_REPLY_TIMEOUT     60
                     77: 
                     78: /* Linger time for dying tunnels and sessions */
                     79: #define L2TP_CTRL_DEATH_TIMEOUT        31
                     80: #define L2TP_SESS_DEATH_TIMEOUT        31
                     81: 
                     82: /* Control message types */
                     83: enum l2tp_msg_type {
                     84:        SCCRQ           =1,
                     85:        SCCRP           =2,
                     86:        SCCCN           =3,
                     87:        StopCCN         =4,
                     88:        HELLO           =6,
                     89:        OCRQ            =7,
                     90:        OCRP            =8,
                     91:        OCCN            =9,
                     92:        ICRQ            =10,
                     93:        ICRP            =11,
                     94:        ICCN            =12,
                     95:        CDN             =14,
                     96:        WEN             =15,
                     97:        SLI             =16,
                     98: };
                     99: 
                    100: /* Control connection states */
                    101: enum l2tp_ctrl_state {
                    102:        CS_IDLE = 0,
                    103:        CS_WAIT_CTL_REPLY,
                    104:        CS_WAIT_CTL_CONNECT,
                    105:        CS_ESTABLISHED,
                    106:        CS_DYING
                    107: };
                    108: 
                    109: /* Session states */
                    110: enum l2tp_sess_state {
                    111:        SS_WAIT_REPLY = 1,
                    112:        SS_WAIT_CONNECT,
                    113:        SS_WAIT_ANSWER,
                    114:        SS_ESTABLISHED,
                    115:        SS_DYING
                    116: };
                    117: 
                    118: /* Session origination */
                    119: enum l2tp_sess_orig {
                    120:        ORIG_LOCAL      =0,
                    121:        ORIG_REMOTE     =1
                    122: };
                    123: 
                    124: /* Session side */
                    125: enum l2tp_sess_side {
                    126:        SIDE_LNS        =0,
                    127:        SIDE_LAC        =1
                    128: };
                    129: 
                    130: /*
                    131:  * Control message handler function types.
                    132:  *
                    133:  * Messages are either session-specific, or apply to the entire tunnel.
                    134:  */
                    135: typedef int    l2tp_ctrl_msg_handler_t(struct ppp_l2tp_ctrl *ctrl,
                    136:                        const struct ppp_l2tp_avp_list *avps,
                    137:                        struct ppp_l2tp_avp_ptrs *ptrs);
                    138: typedef int    l2tp_sess_msg_handler_t(struct ppp_l2tp_sess *sess,
                    139:                        const struct ppp_l2tp_avp_list *avps,
                    140:                        struct ppp_l2tp_avp_ptrs *ptrs);
                    141: 
                    142: /* Descriptor for one control message */
                    143: struct l2tp_msg_info {
                    144:        const char              *name;
                    145:        enum l2tp_msg_type      type;
                    146:        l2tp_ctrl_msg_handler_t *ctrl_handler;
                    147:        l2tp_sess_msg_handler_t *sess_handler;
                    148:        int                     valid_states[12];
                    149:        int                     valid_orig[3];
                    150:        int                     valid_side[3];
                    151:        int                     req_avps[AVP_MAX + 1];
                    152: };
                    153: 
                    154: /* Control connection */
                    155: struct ppp_l2tp_ctrl {
                    156:        enum l2tp_ctrl_state    state;                  /* control state */
                    157:        const struct ppp_l2tp_ctrl_cb *cb;              /* link callbacks */
                    158:        struct pevent_ctx       *ctx;                   /* event context */
                    159:        pthread_mutex_t         *mutex;                 /* mutex */
                    160:        u_int32_t               serial;                 /* next call serial */
                    161:        ng_ID_t                 node_id;                /* l2tp node id */
                    162:        u_int32_t               peer_id;                /* peer unique id */
                    163:        char                    path[32];               /* l2tp node path */
                    164:        int                     csock;                  /* netgraph ctrl sock */
                    165:        int                     dsock;                  /* netgraph data sock */
                    166:        u_char                  *secret;                /* shared secret */
                    167:        u_int                   seclen;                 /* share secret len */
                    168:        struct ppp_log          *log;                   /* log */
                    169:        struct ng_l2tp_config   config;                 /* netgraph node cfg. */
                    170:        struct ghash            *sessions;              /* sessions */
                    171:        struct ppp_l2tp_avp_list *avps;                 /* avps for SCCR[QP] */
                    172:        struct pevent           *idle_timer;            /* ctrl idle timer */
                    173:        struct pevent           *reply_timer;           /* reply timer */
                    174:        struct pevent           *close_timer;           /* close timer */
                    175:        struct pevent           *death_timer;           /* death timer */
                    176:        struct pevent           *ctrl_event;            /* ctrl socket event */
                    177:        struct pevent           *data_event;            /* data socket event */
                    178:        void                    *link_cookie;           /* opaque link cookie */
                    179:        u_int16_t               result;                 /* close result code */
                    180:        u_int16_t               error;                  /* close error code */
                    181:        u_int32_t               peer_bearer;            /* peer bearer types */
                    182:        u_int32_t               peer_framing;           /* peer framing types */
                    183:        u_int                   active_sessions;        /* # non-dying sessns */
                    184:        char                    *errmsg;                /* close error msg */
                    185:        u_char                  link_notified;          /* link notified down */
                    186:        u_char                  peer_notified;          /* peer notified down */
                    187: };
                    188: 
                    189: /* Session */
                    190: struct ppp_l2tp_sess {
                    191:        struct ppp_l2tp_ctrl    *ctrl;                  /* associated ctrl */
                    192:        enum l2tp_sess_state    state;                  /* session state */
                    193:        enum l2tp_sess_orig     orig;                   /* who originated it? */
                    194:        enum l2tp_sess_side     side;                   /* are we lac or lns? */
                    195:        u_int32_t               serial;                 /* call serial number */
                    196:        struct ng_l2tp_sess_config config;              /* netgraph hook cfg. */
                    197:        struct ppp_l2tp_avp_list *my_avps;              /* avps in [IO]CR[QP] */
                    198:        struct ppp_l2tp_avp_list *peer_avps;            /* avps in [IO]CCN */
                    199:        u_int16_t               session_id;             /* session id */
                    200:        u_int16_t               peer_id;                /* peer session id */
                    201:        struct ppp_log          *log;                   /* log */
                    202:        ng_ID_t                 node_id;                /* tee node id */
                    203:        char                    hook[NG_HOOKSIZ];       /* session hook name */
                    204:        void                    *link_cookie;           /* opaque link cookie */
                    205:        u_int16_t               result;                 /* close result code */
                    206:        u_int16_t               error;                  /* close error code */
                    207:        char                    *errmsg;                /* close error msg */
                    208:        struct pevent           *reply_timer;           /* reply timer */
                    209:        struct pevent           *notify_timer;          /* link notify timer */
                    210:        struct pevent           *close_timer;           /* close timer */
                    211:        struct pevent           *death_timer;           /* death timer */
                    212:        u_char                  link_responded;         /* link notified up */
                    213:        u_char                  peer_responded;         /* got icrp from lns */
                    214:        u_char                  dseq_required;          /* data seq. req'd */
                    215:        u_char                  link_notified;          /* link notified down */
                    216:        u_char                  peer_notified;          /* peer notified down */
                    217: };
                    218: 
                    219: /***
                    220: 
                    221: Notes
                    222: 
                    223:     - "link_notified" means the link side has been notified that
                    224:       the control connection or session has gone down.
                    225:     - "peer_notified" means the peer has been notified that
                    226:       the control connection or session has gone down.
                    227:     - "link_responded" and "peer_responded" are only used for
                    228:       outgoing calls when we are the LAC; they indicate acceptance
                    229:       from the link side and the remote peer, respectively. Both
                    230:       must be true before we send the OCCN.
                    231:     - "sess->my_avps" are the AVP's included my ICRQ or OCRQ. In case
                    232:       of ICRQ, these get overwritten by AVP's included in ICCN.
                    233:     - "sess->peer_avps" are the AVPS included peer's ICCN or OCCN
                    234: 
                    235: ***/
                    236: 
                    237: /************************************************************************
                    238:                        INTERNAL FUNCTIONS
                    239: ************************************************************************/
                    240: 
                    241: static int     ppp_l2tp_ctrl_setup_1(struct ppp_l2tp_ctrl *ctrl,
                    242:                        struct ppp_l2tp_avp_ptrs *ptrs);
                    243: static int     ppp_l2tp_ctrl_setup_2(struct ppp_l2tp_ctrl *ctrl,
                    244:                        struct ppp_l2tp_avp_ptrs *ptrs);
                    245: static void    ppp_l2tp_ctrl_send(struct ppp_l2tp_ctrl *ctrl,
                    246:                        u_int16_t session_id, enum l2tp_msg_type msgtype,
                    247:                        const struct ppp_l2tp_avp_list *avps0);
                    248: static void    ppp_l2tp_ctrl_check_reply(struct ppp_l2tp_ctrl *ctrl);
                    249: static void    ppp_l2tp_ctrl_close(struct ppp_l2tp_ctrl *ctrl,
                    250:                        u_int16_t result, u_int16_t error, const char *errmsg);
                    251: static void    ppp_l2tp_ctrl_death_start(struct ppp_l2tp_ctrl *ctrl);
                    252: 
                    253: static struct  ppp_l2tp_sess *ppp_l2tp_sess_create(struct ppp_l2tp_ctrl *ctrl,
                    254:                        enum l2tp_sess_orig orig, enum l2tp_sess_side side);
                    255: static void    ppp_l2tp_sess_destroy(struct ppp_l2tp_sess **sessp);
                    256: static void    ppp_l2tp_sess_close(struct ppp_l2tp_sess *sess,
                    257:                        u_int16_t result, u_int16_t error, const char *errmsg);
                    258: static int     ppp_l2tp_sess_setup(struct ppp_l2tp_sess *sess);
                    259: static int     ppp_l2tp_sess_check_liic(struct ppp_l2tp_sess *sess);
                    260: static void    ppp_l2tp_sess_check_reply(struct ppp_l2tp_sess *sess);
                    261: 
                    262: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_SCCRQ;
                    263: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_SCCRP;
                    264: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_SCCCN;
                    265: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_StopCCN;
                    266: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_HELLO;
                    267: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_OCRQ;
                    268: static l2tp_ctrl_msg_handler_t ppp_l2tp_handle_ICRQ;
                    269: 
                    270: static l2tp_sess_msg_handler_t ppp_l2tp_handle_OCRP;
                    271: static l2tp_sess_msg_handler_t ppp_l2tp_handle_xCCN;
                    272: static l2tp_sess_msg_handler_t ppp_l2tp_handle_ICRP;
                    273: static l2tp_sess_msg_handler_t ppp_l2tp_handle_CDN;
                    274: static l2tp_sess_msg_handler_t ppp_l2tp_handle_WEN;
                    275: static l2tp_sess_msg_handler_t ppp_l2tp_handle_SLI;
                    276: 
                    277: static pevent_handler_t                ppp_l2tp_ctrl_event;
                    278: static pevent_handler_t                ppp_l2tp_data_event;
                    279: 
                    280: static pevent_handler_t                ppp_l2tp_idle_timeout;
                    281: static pevent_handler_t                ppp_l2tp_ctrl_do_close;
                    282: static pevent_handler_t                ppp_l2tp_ctrl_death_timeout;
                    283: 
                    284: static pevent_handler_t                ppp_l2tp_sess_notify;
                    285: static pevent_handler_t                ppp_l2tp_sess_do_close;
                    286: static pevent_handler_t                ppp_l2tp_sess_death_timeout;
                    287: 
                    288: static void    ppp_l2tp_ctrl_dump(struct ppp_l2tp_ctrl *ctrl,
                    289:                        struct ppp_l2tp_avp_list *list, const char *fmt, ...)
                    290:                        __printflike(3, 4);
                    291: static const   char *ppp_l2tp_ctrl_state_str(enum l2tp_ctrl_state state);
                    292: static const   char *ppp_l2tp_sess_state_str(enum l2tp_ctrl_state state);
                    293: static const   char *ppp_l2tp_sess_orig_str(enum l2tp_sess_orig orig);
                    294: static const   char *ppp_l2tp_sess_side_str(enum l2tp_sess_side side);
                    295: 
                    296: static ghash_hash_t    ppp_l2tp_ctrl_hash;
                    297: static ghash_equal_t   ppp_l2tp_ctrl_equal;
                    298: 
                    299: static ghash_hash_t    ppp_l2tp_sess_hash;
                    300: static ghash_equal_t   ppp_l2tp_sess_equal;
                    301: 
                    302: /************************************************************************
                    303:                        INTERNAL VARIABLES
                    304: ************************************************************************/
                    305: 
                    306: /* Descriptors for each L2TP message type */
                    307: static const   struct l2tp_msg_info ppp_l2tp_msg_info[] = {
                    308: 
                    309:        /* Control connection messages */
                    310:        { "SCCRQ", SCCRQ,       ppp_l2tp_handle_SCCRQ, NULL,
                    311:            { CS_IDLE, -1 },
                    312:            { -1 }, { -1 },
                    313:            { AVP_PROTOCOL_VERSION, AVP_HOST_NAME,
                    314:                AVP_FRAMING_CAPABILITIES, AVP_ASSIGNED_TUNNEL_ID, -1 } },
                    315:        { "SCCRP", SCCRP,       ppp_l2tp_handle_SCCRP, NULL,
                    316:            { CS_WAIT_CTL_REPLY, -1 },
                    317:            { -1 }, { -1 },
                    318:            { AVP_PROTOCOL_VERSION, AVP_HOST_NAME,
                    319:                AVP_FRAMING_CAPABILITIES, AVP_ASSIGNED_TUNNEL_ID, -1 } },
                    320:        { "SCCCN", SCCCN,       ppp_l2tp_handle_SCCCN, NULL,
                    321:            { CS_WAIT_CTL_CONNECT, -1 },
                    322:            { -1 }, { -1 },
                    323:            { -1 } },
                    324:        { "StopCCN", StopCCN,   ppp_l2tp_handle_StopCCN, NULL,
                    325:            { CS_IDLE, CS_WAIT_CTL_REPLY, CS_WAIT_CTL_CONNECT,
                    326:                CS_ESTABLISHED, CS_DYING, -1 },
                    327:            { -1 }, { -1 },
                    328:            { AVP_ASSIGNED_TUNNEL_ID, AVP_RESULT_CODE, -1 } },
                    329:        { "HELLO", HELLO,       ppp_l2tp_handle_HELLO, NULL,
                    330:            { CS_IDLE, CS_WAIT_CTL_REPLY, CS_WAIT_CTL_CONNECT,
                    331:                CS_ESTABLISHED, CS_DYING, -1 },
                    332:            { -1 }, { -1 },
                    333:            { -1 } },
                    334:        { "ICRQ", ICRQ,         ppp_l2tp_handle_ICRQ, NULL,
                    335:            { CS_ESTABLISHED, -1 },
                    336:            { -1 }, { -1 },
                    337:            { AVP_ASSIGNED_SESSION_ID, AVP_CALL_SERIAL_NUMBER, -1 } },
                    338:        { "OCRQ", OCRQ,         ppp_l2tp_handle_OCRQ, NULL,
                    339:            { CS_ESTABLISHED, -1 },
                    340:            { -1 }, { -1 },
                    341:            { AVP_ASSIGNED_SESSION_ID, AVP_CALL_SERIAL_NUMBER,
                    342:                AVP_MINIMUM_BPS, AVP_MAXIMUM_BPS, AVP_BEARER_TYPE,
                    343:                AVP_FRAMING_TYPE, AVP_CALLED_NUMBER, -1 } },
                    344: 
                    345:        /* Session connection messages */
                    346:        { "ICRP", ICRP,         NULL, ppp_l2tp_handle_ICRP,
                    347:            { SS_WAIT_REPLY, SS_DYING, -1 },
                    348:            { ORIG_LOCAL, -1 }, { SIDE_LAC, -1 },
                    349:            { AVP_ASSIGNED_SESSION_ID, -1 } },
                    350:        { "OCRP", OCRP,         NULL, ppp_l2tp_handle_OCRP,
                    351:            { SS_WAIT_REPLY, SS_DYING, -1 },
                    352:            { ORIG_LOCAL, -1 }, { SIDE_LNS, -1 },
                    353:            { AVP_ASSIGNED_SESSION_ID, -1 } },
                    354:        { "ICCN", ICCN,         NULL, ppp_l2tp_handle_xCCN,
                    355:            { SS_WAIT_CONNECT, SS_DYING, -1 },
                    356:            { ORIG_REMOTE, -1 }, { SIDE_LNS, -1 },
                    357:            { AVP_TX_CONNECT_SPEED, AVP_FRAMING_TYPE, -1 } },
                    358:        { "OCCN", OCCN,         NULL, ppp_l2tp_handle_xCCN,
                    359:            { SS_WAIT_CONNECT, SS_DYING, -1 },
                    360:            { ORIG_LOCAL, -1 }, { SIDE_LNS, -1 },
                    361:            { AVP_TX_CONNECT_SPEED, AVP_FRAMING_TYPE, -1 } },
                    362:        { "CDN", CDN,           NULL, ppp_l2tp_handle_CDN,
                    363:            { SS_WAIT_REPLY, SS_WAIT_CONNECT,
                    364:                SS_WAIT_ANSWER, SS_ESTABLISHED, SS_DYING, -1 },
                    365:            { ORIG_LOCAL, ORIG_REMOTE, -1 }, { SIDE_LAC, SIDE_LNS, -1 },
                    366:            { AVP_RESULT_CODE, AVP_ASSIGNED_SESSION_ID, -1 } },
                    367:        { "WEN", WEN,           NULL, ppp_l2tp_handle_WEN,
                    368:            { SS_ESTABLISHED, SS_DYING, -1 },
                    369:            { ORIG_LOCAL, ORIG_REMOTE, -1 }, { SIDE_LNS, -1 },
                    370:            { AVP_CALL_ERRORS, -1 } },
                    371:        { "SLI", SLI,           NULL, ppp_l2tp_handle_SLI,
                    372:            { SS_ESTABLISHED, SS_DYING, -1 },
                    373:            { ORIG_LOCAL, ORIG_REMOTE, -1 }, { SIDE_LAC, -1 },
                    374:            { AVP_ACCM, -1 } },
                    375:        { NULL }
                    376: };
                    377: 
                    378: /* Descriptors for each AVP */
                    379: 
                    380: #define AVP_ITEM(x,m,h,min,max)        \
                    381:        { #x, ppp_l2tp_avp_decode_ ## x, 0, AVP_ ## x, m, h, min, max }
                    382: 
                    383: static const   struct ppp_l2tp_avp_info ppp_l2tp_avp_info_list[] = {
                    384:        AVP_ITEM(MESSAGE_TYPE,          0,  1,  2,  2),
                    385:        AVP_ITEM(RANDOM_VECTOR,         0,  1,  0,  AVP_MAX_LENGTH),
                    386:        AVP_ITEM(RESULT_CODE,           0,  1,  2,  AVP_MAX_LENGTH),
                    387:        AVP_ITEM(PROTOCOL_VERSION,      0,  1,  2,  2),
                    388:        AVP_ITEM(FRAMING_CAPABILITIES,  1,  1,  4,  4),
                    389:        AVP_ITEM(BEARER_CAPABILITIES,   1,  1,  4,  4),
                    390:        AVP_ITEM(TIE_BREAKER,           0,  0,  8,  8),
                    391:        AVP_ITEM(FIRMWARE_REVISION,     1,  0,  2,  2),
                    392:        AVP_ITEM(HOST_NAME,             0,  1,  1,  AVP_MAX_LENGTH),
                    393:        AVP_ITEM(VENDOR_NAME,           1,  0,  0,  AVP_MAX_LENGTH),
                    394:        AVP_ITEM(ASSIGNED_TUNNEL_ID,    1,  1,  2,  2),
                    395:        AVP_ITEM(RECEIVE_WINDOW_SIZE,   0,  1,  2,  2),
                    396:        AVP_ITEM(CHALLENGE,             1,  1,  0,  AVP_MAX_LENGTH),
                    397:        AVP_ITEM(CHALLENGE_RESPONSE,    1,  1, 16,  16),
                    398:        AVP_ITEM(CAUSE_CODE,            0,  1,  3,  AVP_MAX_LENGTH),
                    399:        AVP_ITEM(ASSIGNED_SESSION_ID,   1,  1,  2,  2),
                    400:        AVP_ITEM(CALL_SERIAL_NUMBER,    1,  1,  4,  4),
                    401:        AVP_ITEM(MINIMUM_BPS,           1,  1,  4,  4),
                    402:        AVP_ITEM(MAXIMUM_BPS,           1,  1,  4,  4),
                    403:        AVP_ITEM(BEARER_TYPE,           1,  1,  4,  4),
                    404:        AVP_ITEM(FRAMING_TYPE,          1,  1,  4,  4),
                    405:        AVP_ITEM(CALLED_NUMBER,         1,  1,  0,  AVP_MAX_LENGTH),
                    406:        AVP_ITEM(CALLING_NUMBER,        1,  1,  0,  AVP_MAX_LENGTH),
                    407:        AVP_ITEM(SUB_ADDRESS,           1,  1,  0,  AVP_MAX_LENGTH),
                    408:        AVP_ITEM(TX_CONNECT_SPEED,      1,  1,  4,  4),
                    409:        AVP_ITEM(RX_CONNECT_SPEED,      1,  0,  4,  4),
                    410:        AVP_ITEM(PHYSICAL_CHANNEL_ID,   1,  0,  4,  4),
                    411:        AVP_ITEM(PRIVATE_GROUP_ID,      1,  0,  0,  AVP_MAX_LENGTH),
                    412:        AVP_ITEM(SEQUENCING_REQUIRED,   0,  1,  0,  0),
                    413:        AVP_ITEM(INITIAL_RECV_CONFREQ,  1,  0,  0,  AVP_MAX_LENGTH),
                    414:        AVP_ITEM(LAST_SENT_CONFREQ,     1,  0,  0,  AVP_MAX_LENGTH),
                    415:        AVP_ITEM(LAST_RECV_CONFREQ,     1,  0,  0,  AVP_MAX_LENGTH),
                    416:        AVP_ITEM(PROXY_AUTHEN_TYPE,     1,  0,  2,  2),
                    417:        AVP_ITEM(PROXY_AUTHEN_NAME,     1,  0,  0,  AVP_MAX_LENGTH),
                    418:        AVP_ITEM(PROXY_AUTHEN_CHALLENGE,1,  0,  0,  AVP_MAX_LENGTH),
                    419:        AVP_ITEM(PROXY_AUTHEN_ID,       1,  0,  2,  2),
                    420:        AVP_ITEM(PROXY_AUTHEN_RESPONSE, 1,  0,  0,  AVP_MAX_LENGTH),
                    421:        AVP_ITEM(CALL_ERRORS,           1,  1, 26,  26),
                    422:        AVP_ITEM(ACCM,                  1,  1, 10,  10),
                    423:        { NULL, NULL, 0, 0, 0, 0, 0, 0 }
                    424: };
                    425: 
                    426: /* All control connections */
                    427: struct ghash   *ppp_l2tp_ctrls;
                    428: 
                    429: /* Macros for logging */
                    430: #define CLOG(sev, fmt, args...)        PPP_LOG(ctrl->log, sev, fmt , ## args)
                    431: #define SLOG(sev, fmt, args...)        PPP_LOG(sess->log, sev, fmt , ## args)
                    432: 
                    433: /************************************************************************
                    434:                        PUBLIC FUNCTIONS
                    435: ************************************************************************/
                    436: 
                    437: /*
                    438:  * Create a new control connection.
                    439:  */
                    440: struct ppp_l2tp_ctrl *
                    441: ppp_l2tp_ctrl_create(struct pevent_ctx *ctx, pthread_mutex_t *mutex,
                    442:        const struct ppp_l2tp_ctrl_cb *cb, struct ppp_log *log,
                    443:        int initiate, u_int32_t peer_id, ng_ID_t *nodep, char *hook,
                    444:        const struct ppp_l2tp_avp_list *avps, const void *secret, size_t seclen)
                    445: {
                    446:        union {
                    447:            u_char buf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)];
                    448:            struct ng_mesg reply;
                    449:        } repbuf;
                    450:        struct ng_mesg *const reply = &repbuf.reply;
                    451:        struct nodeinfo ninfo;
                    452:        struct ppp_l2tp_ctrl *ctrl;
                    453:        struct ngm_mkpeer mkpeer;
                    454:        struct ppp_l2tp_avp *avp = NULL;
                    455:        u_int16_t value16;
                    456:        int index;
                    457: 
                    458:        /* Create global control structure hash table */
                    459:        if (ppp_l2tp_ctrls == NULL
                    460:            && (ppp_l2tp_ctrls = ghash_create(NULL, 0, 0, CTRL_MEM_TYPE,
                    461:              ppp_l2tp_ctrl_hash, ppp_l2tp_ctrl_equal, NULL, NULL)) == NULL)
                    462:                return (NULL);
                    463: 
                    464:        /* Create control connection */
                    465:        if ((ctrl = MALLOC(CTRL_MEM_TYPE, sizeof(*ctrl))) == NULL)
                    466:                return (NULL);
                    467:        memset(ctrl, 0, sizeof(*ctrl));
                    468:        ctrl->ctx = ctx;
                    469:        ctrl->mutex = mutex;
                    470:        ctrl->cb = cb;
                    471:        ctrl->peer_id = peer_id;
                    472:        ctrl->csock = -1;
                    473:        ctrl->dsock = -1;
                    474:        ctrl->log = log;
                    475: 
                    476:        /* Debugging */
                    477:        CLOG(LOG_DEBUG, "%s: invoked", __FUNCTION__);
                    478: 
                    479:        /* Select an unused, non-zero local tunnel ID */
                    480:        while (ctrl->config.tunnel_id == 0
                    481:            || ghash_get(ppp_l2tp_ctrls, ctrl) != NULL)
                    482:                ctrl->config.tunnel_id = random() & 0xffff;
                    483: 
                    484:        /* Add control structure to hash table */
                    485:        if (ghash_put(ppp_l2tp_ctrls, ctrl) == -1)
                    486:                goto fail;
                    487: 
                    488:        /* Copy shared secret, if any */
                    489:        if (seclen > 0) {
                    490:                if ((ctrl->secret = MALLOC(CTRL_MEM_TYPE, seclen)) == NULL)
                    491:                        goto fail;
                    492:                memcpy(ctrl->secret, secret, seclen);
                    493:        }
                    494:        ctrl->seclen = seclen;
                    495: 
                    496:        /* Create sessions hash table */
                    497:        if ((ctrl->sessions = ghash_create(NULL, 0, 0, CTRL_MEM_TYPE,
                    498:            ppp_l2tp_sess_hash, ppp_l2tp_sess_equal, NULL, NULL)) == NULL)
                    499:                goto fail;
                    500: 
                    501:        /* Create netgraph node */
                    502:        if (NgMkSockNode(NULL, &ctrl->csock, &ctrl->dsock) == -1)
                    503:                goto fail;
                    504:        memset(&mkpeer, 0, sizeof(mkpeer));
                    505:        strlcpy(mkpeer.type, NG_L2TP_NODE_TYPE, sizeof(mkpeer.type));
                    506:        strlcpy(mkpeer.ourhook, NG_L2TP_HOOK_CTRL, sizeof(mkpeer.ourhook));
                    507:        strlcpy(mkpeer.peerhook, NG_L2TP_HOOK_CTRL, sizeof(mkpeer.peerhook));
                    508:        if (NgSendMsg(ctrl->csock, ".", NGM_GENERIC_COOKIE,
                    509:            NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1)
                    510:                goto fail;
                    511: 
                    512:        /* Get l2tp node ID */
                    513:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL,
                    514:            NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) == -1)
                    515:                goto fail;
                    516:        if (NgRecvMsg(ctrl->csock, reply, sizeof(repbuf), NULL) == -1)
                    517:                goto fail;
                    518:        memcpy(&ninfo, reply->data, sizeof(ninfo));
                    519:        ctrl->node_id = ninfo.id;
                    520:        snprintf(ctrl->path, sizeof(ctrl->path),
                    521:            "[%lx]:", (u_long)ctrl->node_id);
                    522: 
                    523:        /* Configure netgraph node with initial configuration */
                    524:        ctrl->config.enabled = 1;
                    525:        ctrl->config.peer_win = 1;              /* we increase this later */
                    526:        ctrl->config.rexmit_max = L2TP_REXMIT_MAX;
                    527:        ctrl->config.rexmit_max_to = L2TP_REXMIT_MAX_TO;
                    528:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
                    529:            NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1)
                    530:                goto fail;
                    531: 
                    532:        /* Listen for control messages and control packets */
                    533:        if (pevent_register(ctrl->ctx, &ctrl->ctrl_event, PEVENT_RECURRING,
                    534:            ctrl->mutex, ppp_l2tp_ctrl_event, ctrl, PEVENT_READ,
                    535:            ctrl->csock) == -1)
                    536:                goto fail;
                    537:        if (pevent_register(ctrl->ctx, &ctrl->data_event, PEVENT_RECURRING,
                    538:            ctrl->mutex, ppp_l2tp_data_event, ctrl, PEVENT_READ,
                    539:            ctrl->dsock) == -1)
                    540:                goto fail;
                    541: 
                    542:        /* Copy initial AVP list */
                    543:        ctrl->avps = (avps == NULL) ?
                    544:            ppp_l2tp_avp_list_create() :
                    545:            ppp_l2tp_avp_list_copy(avps);
                    546:        if (ctrl->avps == NULL)
                    547:                goto fail;
                    548: 
                    549:        /* Add required AVP's */
                    550:        if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    551:            0, AVP_PROTOCOL_VERSION)) == -1) {
                    552:                const u_char pv[] = { L2TP_PROTO_VERS, L2TP_PROTO_REV };
                    553: 
                    554:                if (ppp_l2tp_avp_list_append(ctrl->avps, 1,
                    555:                    0, AVP_PROTOCOL_VERSION, pv, sizeof(pv)) == -1)
                    556:                        goto fail;
                    557:        }
                    558:        if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    559:            0, AVP_HOST_NAME)) == -1) {
                    560:                char hostname[MAXHOSTNAMELEN + 1];
                    561: 
                    562:                (void)gethostname(hostname, sizeof(hostname) - 1);
                    563:                hostname[sizeof(hostname) - 1] = '\0';
                    564:                if (ppp_l2tp_avp_list_append(ctrl->avps, 1,
                    565:                    0, AVP_HOST_NAME, hostname, strlen(hostname)) == -1)
                    566:                        goto fail;
                    567:        }
                    568:        if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    569:            0, AVP_FRAMING_CAPABILITIES)) == -1) {
                    570:                const u_int32_t value = htonl(L2TP_FRAMING_SYNC);
                    571: 
                    572:                if (ppp_l2tp_avp_list_append(ctrl->avps, 1,
                    573:                    0, AVP_FRAMING_CAPABILITIES, &value, sizeof(value)) == -1)
                    574:                        goto fail;
                    575:        }
                    576:        if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    577:            0, AVP_ASSIGNED_TUNNEL_ID)) != -1)
                    578:                ppp_l2tp_avp_list_remove(ctrl->avps, index);
                    579:        value16 = htons(ctrl->config.tunnel_id);
                    580:        if (ppp_l2tp_avp_list_append(ctrl->avps, 1,
                    581:            0, AVP_ASSIGNED_TUNNEL_ID, &value16, sizeof(value16)) == -1)
                    582:                goto fail;
                    583:        if (ctrl->secret == NULL) {
                    584:                if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    585:                    0, AVP_CHALLENGE)) != -1)
                    586:                        ppp_l2tp_avp_list_remove(ctrl->avps, index);
                    587:        } else if ((index = ppp_l2tp_avp_list_find(ctrl->avps,
                    588:            0, AVP_CHALLENGE)) == -1) {
                    589:                u_int32_t cbuf[(L2TP_CHALLENGE_LEN + 3) / 4];
                    590:                int i;
                    591: 
                    592:                for (i = 0; i < sizeof(cbuf) / sizeof(*cbuf); i++)
                    593:                        cbuf[i] = random();
                    594:                if (ppp_l2tp_avp_list_append(ctrl->avps, 1,
                    595:                    0, AVP_CHALLENGE, &cbuf, sizeof(cbuf)) == -1)
                    596:                        goto fail;
                    597:        }
                    598: 
                    599:        /* Initiate connection if we're the initiator */
                    600:        if (initiate) {
                    601:                ppp_l2tp_ctrl_send(ctrl, 0, SCCRQ, ctrl->avps);
                    602:                ctrl->state = CS_WAIT_CTL_REPLY;
                    603:        } else
                    604:                ctrl->state = CS_IDLE;          /* wait for peer's sccrq */
                    605: 
                    606:        /* Expect some sort of reply */
                    607:        ppp_l2tp_ctrl_check_reply(ctrl);
                    608: 
                    609:        /* Done */
                    610:        *nodep = ctrl->node_id;
                    611:        strlcpy(hook, NG_L2TP_HOOK_LOWER, NG_HOOKSIZ);
                    612:        return (ctrl);
                    613: 
                    614: fail:
                    615:        /* Clean up after failure */
                    616:        ppp_l2tp_avp_destroy(&avp);
                    617:        if (ctrl->csock >= 0)
                    618:                (void)close(ctrl->csock);       /* l2tp node will go away too */
                    619:        if (ctrl->dsock >= 0)
                    620:                (void)close(ctrl->dsock);
                    621:        pevent_unregister(&ctrl->reply_timer);
                    622:        pevent_unregister(&ctrl->ctrl_event);
                    623:        pevent_unregister(&ctrl->data_event);
                    624:        ppp_l2tp_avp_list_destroy(&ctrl->avps);
                    625:        ghash_remove(ppp_l2tp_ctrls, ctrl);
                    626:        ghash_destroy(&ctrl->sessions);
                    627:        FREE(CTRL_MEM_TYPE, ctrl->secret);
                    628:        FREE(CTRL_MEM_TYPE, ctrl);
                    629:        if (ppp_l2tp_ctrls != NULL && ghash_size(ppp_l2tp_ctrls) == 0)
                    630:                ghash_destroy(&ppp_l2tp_ctrls);
                    631:        return (NULL);
                    632: }
                    633: 
                    634: /*
                    635:  * Shutdown a control connection.
                    636:  */
                    637: void
                    638: ppp_l2tp_ctrl_shutdown(struct ppp_l2tp_ctrl *ctrl,
                    639:         u_int16_t result, u_int16_t error, const char *errmsg)
                    640: {
                    641:        /* Debugging */
                    642:        CLOG(LOG_DEBUG, "%s: invoked, ctrl=%p errmsg=\"%s\"",
                    643:            __FUNCTION__, ctrl, errmsg);
                    644: 
                    645:        /* Close control connection */
                    646:        ppp_l2tp_ctrl_close(ctrl, result, error, errmsg);
                    647: }
                    648: 
                    649: /*
                    650:  * Initiate a new session.
                    651:  */
                    652: struct ppp_l2tp_sess *
                    653: ppp_l2tp_initiate(struct ppp_l2tp_ctrl *ctrl, int out,
                    654:        const struct ppp_l2tp_avp_list *avps)
                    655: {
                    656:        struct ppp_l2tp_sess *sess;
                    657:        u_int32_t value32;
                    658:        int index;
                    659:        int i;
                    660: 
                    661:        /* Debugging */
                    662:        CLOG(LOG_DEBUG, "%s: invoked, ctrl=%p out=%d", __FUNCTION__, ctrl);
                    663: 
                    664:        /* Check control connection */
                    665:        /* XXX add support for sessions waiting for open ctrl conection */
                    666:        if (ctrl->state != CS_ESTABLISHED) {
                    667:                errno = ENXIO;
                    668:                return (NULL);
                    669:        }
                    670: 
                    671:        /* Verify peer supports outgoing calls */
                    672:        if (out
                    673:            && (ctrl->peer_bearer
                    674:              & (L2TP_BEARER_DIGITAL|L2TP_BEARER_ANALOG)) == 0) {
                    675:                errno = EOPNOTSUPP;
                    676:                return (NULL);
                    677:        }
                    678: 
                    679:        /* Create new session */
                    680:        if ((sess = ppp_l2tp_sess_create(ctrl,
                    681:            ORIG_LOCAL, out ? SIDE_LNS : SIDE_LAC)) == NULL)
                    682:                return (NULL);
                    683: 
                    684:        /* Copy AVP's supplied by caller */
                    685:        for (i = 0; i < avps->length; i++) {
                    686:                const struct ppp_l2tp_avp *const avp = &avps->avps[i];
                    687: 
                    688:                if (ppp_l2tp_avp_list_append(sess->my_avps,
                    689:                    avp->mandatory, avp->vendor, avp->type,
                    690:                    avp->value, avp->vlen) == -1)
                    691:                        goto fail;
                    692:        }
                    693: 
                    694:        /* Add other AVP's required by OCRQ */
                    695:        if (!out)
                    696:                goto send_msg;
                    697:        if ((index = ppp_l2tp_avp_list_find(sess->my_avps,
                    698:            0, AVP_MINIMUM_BPS)) == -1) {
                    699:                value32 = htonl(0);
                    700:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    701:                    0, AVP_MINIMUM_BPS, &value32, sizeof(value32)) == -1)
                    702:                        goto fail;
                    703:        }
                    704:        if ((index = ppp_l2tp_avp_list_find(sess->my_avps,
                    705:            0, AVP_MAXIMUM_BPS)) == -1) {
                    706:                value32 = htonl(0x7fffffff);
                    707:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    708:                    0, AVP_MAXIMUM_BPS, &value32, sizeof(value32)) == -1)
                    709:                        goto fail;
                    710:        }
                    711:        if ((index = ppp_l2tp_avp_list_find(sess->my_avps,
                    712:            0, AVP_FRAMING_TYPE)) == -1) {
                    713:                value32 = (ctrl->peer_framing
                    714:                    & (L2TP_FRAMING_SYNC|L2TP_FRAMING_SYNC));
                    715:                value32 = htonl(value32);
                    716:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    717:                    0, AVP_FRAMING_TYPE, &value32, sizeof(value32)) == -1)
                    718:                        goto fail;
                    719:        }
                    720:        if ((index = ppp_l2tp_avp_list_find(sess->my_avps,
                    721:            0, AVP_CALLED_NUMBER)) == -1) {
                    722:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    723:                    0, AVP_CALLED_NUMBER, NULL, 0) == -1)
                    724:                        goto fail;
                    725:        }
                    726: 
                    727: send_msg:
                    728:        /* Send request to peer */
                    729:        ppp_l2tp_ctrl_send(ctrl, 0, out ? OCRQ : ICRQ, sess->my_avps);
                    730: 
                    731:        /* Await reply from peer */
                    732:        ppp_l2tp_sess_check_reply(sess);
                    733:        return (sess);
                    734: 
                    735: fail:
                    736:        /* Clean up after failure */
                    737:        ppp_l2tp_sess_destroy(&sess);
                    738:        return (NULL);
                    739: }
                    740: 
                    741: /*
                    742:  * Report successful connection of a remotely initiated outgoing call
                    743:  * or a locally initiated incoming call.
                    744:  */
                    745: int
                    746: ppp_l2tp_connected(struct ppp_l2tp_sess *sess,
                    747:        const struct ppp_l2tp_avp_list *avps)
                    748: {
                    749:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                    750:        u_int32_t value32;
                    751:        int i;
                    752: 
                    753:        /* Debugging */
                    754:        SLOG(LOG_DEBUG, "%s: invoked, sess=%p", __FUNCTION__, sess);
                    755: 
                    756:        /* Check control connection */
                    757:        if (ctrl->state != CS_ESTABLISHED) {
                    758:                SLOG(LOG_ERR, "inappropriate call to %s", __FUNCTION__);
                    759:                errno = ENXIO;
                    760:                return (-1);
                    761:        }
                    762: 
                    763:        /* Check session state */
                    764:        if (sess->side != SIDE_LAC
                    765:            || !((sess->orig == ORIG_REMOTE && sess->state == SS_WAIT_ANSWER)
                    766:              || (sess->orig == ORIG_LOCAL && sess->state == SS_WAIT_REPLY))) {
                    767:                SLOG(LOG_ERR, "inappropriate call to %s", __FUNCTION__);
                    768:                errno = ENOTTY;
                    769:                return (-1);
                    770:        }
                    771: 
                    772:        /* Copy AVP's supplied by caller */
                    773:        while (sess->my_avps->length > 0)
                    774:                ppp_l2tp_avp_list_remove(sess->my_avps, 0);
                    775:        if (avps != NULL) {
                    776:                for (i = 0; i < avps->length; i++) {
                    777:                        struct ppp_l2tp_avp *const avp = &avps->avps[i];
                    778: 
                    779:                        if (ppp_l2tp_avp_list_append(sess->my_avps,
                    780:                            avp->mandatory, avp->vendor, avp->type,
                    781:                            avp->value, avp->vlen) == -1)
                    782:                                goto fail;
                    783:                }
                    784:        }
                    785: 
                    786:        /* Add other AVP's required by ICCN and OCCN */
                    787:        if (ppp_l2tp_avp_list_find(sess->my_avps,
                    788:            0, AVP_TX_CONNECT_SPEED) == -1) {
                    789:                value32 = htonl(L2TP_CONNECT_SPEED);
                    790:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    791:                    0, AVP_TX_CONNECT_SPEED, &value32, sizeof(value32)) == -1)
                    792:                        goto fail;
                    793:        }
                    794:        if (ppp_l2tp_avp_list_find(sess->my_avps,
                    795:            0, AVP_FRAMING_TYPE) == -1) {
                    796:                value32 = htonl(L2TP_FRAMING_TYPE);
                    797:                if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                    798:                    0, AVP_FRAMING_TYPE, &value32, sizeof(value32)) == -1)
                    799:                        goto fail;
                    800:        }
                    801: 
                    802:        /* Handle incoming or outgoing call */
                    803:        if (sess->orig == ORIG_LOCAL) {
                    804:                sess->link_responded = 1;
                    805:                if (ppp_l2tp_sess_check_liic(sess) == -1)
                    806:                        goto fail;
                    807:        } else {
                    808:                if (ppp_l2tp_sess_setup(sess) == -1)
                    809:                        goto fail;
                    810:                ppp_l2tp_ctrl_send(ctrl, sess->peer_id, OCCN, sess->my_avps);
                    811:        }
                    812: 
                    813:        /* Done */
                    814:        return (0);
                    815: 
                    816: fail:
                    817:        /* Clean up after failure */
                    818:        ppp_l2tp_sess_close(sess, L2TP_RESULT_ERROR,
                    819:            L2TP_ERROR_GENERIC, strerror(errno));
                    820:        return (-1);
                    821: }
                    822: 
                    823: /*
                    824:  * Terminate a session.
                    825:  */
                    826: void
                    827: ppp_l2tp_terminate(struct ppp_l2tp_sess *sess,
                    828:        u_int16_t result, u_int16_t error, const char *errmsg)
                    829: {
                    830:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                    831: 
                    832:        /* Debugging */
                    833:        SLOG(LOG_DEBUG, "%s: invoked, sess=%p errmsg=\"%s\"",
                    834:            __FUNCTION__, sess, errmsg != NULL ? errmsg : "");
                    835: 
                    836:        /* Check control connection state */
                    837:        if (ctrl->state == CS_DYING) {
                    838:                sess->link_notified = 1;
                    839:                sess->link_cookie = NULL;
                    840:                return;
                    841:        }
                    842:        if (ctrl->state != CS_ESTABLISHED) {
                    843:                SLOG(LOG_ERR, "inappropriate call to %s", __FUNCTION__);
                    844:                return;
                    845:        }
                    846: 
                    847:        /* Close connection */
                    848:        sess->link_notified = 1;
                    849:        sess->link_cookie = NULL;
                    850:        ppp_l2tp_sess_close(sess, result, error, errmsg);
                    851: }
                    852: 
                    853: /*
                    854:  * Get the link side cookie corresponding to a control connection.
                    855:  */
                    856: void *
                    857: ppp_l2tp_ctrl_get_cookie(struct ppp_l2tp_ctrl *ctrl)
                    858: {
                    859:        return (ctrl->link_cookie);
                    860: }
                    861: 
                    862: /*
                    863:  * Set the link side cookie corresponding to a control connection.
                    864:  */
                    865: void
                    866: ppp_l2tp_ctrl_set_cookie(struct ppp_l2tp_ctrl *ctrl, void *cookie)
                    867: {
                    868:        ctrl->link_cookie = cookie;
                    869: }
                    870: 
                    871: /*
                    872:  * Get the link side cookie corresponding to a session.
                    873:  */
                    874: void *
                    875: ppp_l2tp_sess_get_cookie(struct ppp_l2tp_sess *sess)
                    876: {
                    877:        return (sess->link_cookie);
                    878: }
                    879: 
                    880: /*
                    881:  * Set the link side cookie corresponding to a session.
                    882:  */
                    883: void
                    884: ppp_l2tp_sess_set_cookie(struct ppp_l2tp_sess *sess, void *cookie)
                    885: {
                    886:        sess->link_cookie = cookie;
                    887: }
                    888: 
                    889: /*
                    890:  * Get the node path and hook name for the hook that corresponds
                    891:  * to a control connection's L2TP frames.
                    892:  */
                    893: void
                    894: ppp_l2tp_ctrl_get_hook(struct ppp_l2tp_ctrl *ctrl,
                    895:        ng_ID_t *nodep, const char **hookp)
                    896: {
                    897:        if (nodep != NULL)
                    898:                *nodep = ctrl->node_id;
                    899:        if (hookp != NULL)
                    900:                *hookp = NG_L2TP_HOOK_LOWER;
                    901: }
                    902: 
                    903: /*
                    904:  * Get the node path and hook name for the hook that corresponds
                    905:  * to a session's data packets.
                    906:  */
                    907: void
                    908: ppp_l2tp_sess_get_hook(struct ppp_l2tp_sess *sess,
                    909:        ng_ID_t *nodep, const char **hookp)
                    910: {
                    911:        if (nodep != NULL)
                    912:                *nodep = sess->node_id;
                    913:        if (hookp != NULL)
                    914:                *hookp = NG_TEE_HOOK_RIGHT;
                    915: }
                    916: 
                    917: /************************************************************************
                    918:                INTERNAL FUNCTIONS: CONTROL CONNECTION
                    919: ************************************************************************/
                    920: 
                    921: /*
                    922:  * Extract peer information from AVP's contained in a SCCRQ or SCCRP.
                    923:  * This is the first part of tunnel setup.
                    924:  */
                    925: static int
                    926: ppp_l2tp_ctrl_setup_1(struct ppp_l2tp_ctrl *ctrl,
                    927:        struct ppp_l2tp_avp_ptrs *ptrs)
                    928: {
                    929:        /* Log */
                    930:        CLOG(LOG_INFO, "connected to \"%s\", version=%u.%u",
                    931:            ptrs->hostname->hostname, ptrs->protocol->version,
                    932:            ptrs->protocol->revision);
                    933: 
                    934:        /* Get peer's tunnel ID */
                    935:        ctrl->config.peer_id = ptrs->tunnelid->id;
                    936: 
                    937:        /* Get peer's receive window size */
                    938:        ctrl->config.peer_win = L2TP_DEFAULT_PEER_WIN;
                    939:        if (ptrs->winsize != NULL) {
                    940:                if (ptrs->winsize->size == 0)
                    941:                        CLOG(LOG_WARNING, "ignoring zero recv window size AVP");
                    942:                else
                    943:                        ctrl->config.peer_win = ptrs->winsize->size;
                    944:        }
                    945: 
                    946:        /* Get peer's bearer and framing types */
                    947:        if (ptrs->bearercap != NULL) {
                    948:                if (ptrs->bearercap->digital)
                    949:                        ctrl->peer_bearer |= L2TP_BEARER_DIGITAL;
                    950:                if (ptrs->bearercap->analog)
                    951:                        ctrl->peer_bearer |= L2TP_BEARER_ANALOG;
                    952:        }
                    953:        if (ptrs->framingcap->sync)
                    954:                ctrl->peer_framing |= L2TP_FRAMING_SYNC;
                    955:        if (ptrs->framingcap->async)
                    956:                ctrl->peer_framing |= L2TP_FRAMING_ASYNC;
                    957: 
                    958:        /* Update netgraph node configuration */
                    959:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
                    960:            NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1)
                    961:                return (-1);
                    962: 
                    963:        /* See if there is a challenge AVP */
                    964:        if (ptrs->challenge != NULL) {
                    965: 
                    966:                /* Make sure response was included */
                    967:                if (ctrl->secret == NULL) {
                    968:                        CLOG(LOG_WARNING, "tunnel challenge received but"
                    969:                            " no shared secret is configured");
                    970:                        ppp_l2tp_ctrl_close(ctrl,
                    971:                            L2TP_RESULT_NOT_AUTH, 0, NULL);
                    972:                        return (0);
                    973:                }
                    974: 
                    975:                /* Compute challenge response XXX unimplemented */
                    976:                CLOG(LOG_WARNING, "tunnel challenge/response unimplemented");
                    977:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_NOT_AUTH, 0, NULL);
                    978:                return (0);
                    979:        }
                    980: 
                    981:        /* Done */
                    982:        return (0);
                    983: }
                    984: 
                    985: /*
                    986:  * Extract peer information from AVP's contained in a SCCRP or SCCCN.
                    987:  * This is the second part of tunnel setup.
                    988:  */
                    989: static int
                    990: ppp_l2tp_ctrl_setup_2(struct ppp_l2tp_ctrl *ctrl,
                    991:        struct ppp_l2tp_avp_ptrs *ptrs)
                    992: {
                    993:        /* Peer now knows our tunnel ID */
                    994:        ctrl->config.match_id = 1;
                    995:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
                    996:            NGM_L2TP_SET_CONFIG, &ctrl->config, sizeof(ctrl->config)) == -1)
                    997:                return (-1);
                    998: 
                    999:        /* Verify peer's challenge response */
                   1000:        if (ctrl->secret != NULL) {
                   1001: 
                   1002:                /* Make sure response was included */
                   1003:                if (ptrs->challengresp == NULL) {
                   1004:                        CLOG(LOG_WARNING, "SCCRP lacks challenge response");
                   1005:                        ppp_l2tp_ctrl_close(ctrl,
                   1006:                            L2TP_RESULT_NOT_AUTH, 0, NULL);
                   1007:                        return (0);
                   1008:                }
                   1009: 
                   1010:                /* Validate challenge response XXX unimplemented */
                   1011:                CLOG(LOG_WARNING, "tunnel challenge/response unimplemented");
                   1012:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_NOT_AUTH, 0, NULL);
                   1013:                return (0);
                   1014:        }
                   1015: 
                   1016:        /* Done */
                   1017:        return (0);
                   1018: }
                   1019: 
                   1020: /*
                   1021:  * Create a new session.
                   1022:  */
                   1023: static struct ppp_l2tp_sess *
                   1024: ppp_l2tp_sess_create(struct ppp_l2tp_ctrl *ctrl,
                   1025:        enum l2tp_sess_orig orig, enum l2tp_sess_side side)
                   1026: {
                   1027:        struct ppp_l2tp_sess *sess = NULL;
                   1028:        u_int16_t value16;
                   1029:        u_int32_t value32;
                   1030: 
                   1031:        /* Create new session object */
                   1032:        if ((sess = MALLOC(SESS_MEM_TYPE, sizeof(*sess))) == NULL) {
                   1033:                CLOG(LOG_ERR, "error creating session: %m");
                   1034:                return (NULL);
                   1035:        }
                   1036:        memset(sess, 0, sizeof(*sess));
                   1037:        sess->ctrl = ctrl;
                   1038:        sess->orig = orig;
                   1039:        sess->side = side;
                   1040:        sess->serial = ctrl->serial++;
                   1041:        sess->state = (orig == ORIG_LOCAL) ? SS_WAIT_REPLY :
                   1042:            (side == SIDE_LNS) ? SS_WAIT_CONNECT : SS_WAIT_ANSWER;
                   1043:        if ((sess->log = ppp_log_prefix(ctrl->log,
                   1044:            "call #%u: ", sess->serial)) == NULL) {
                   1045:                FREE(SESS_MEM_TYPE, sess);
                   1046:                return (NULL);
                   1047:        }
                   1048: 
                   1049:        /* Get unique session ID */
                   1050:        while (sess->config.session_id == 0
                   1051:            || ghash_get(ctrl->sessions, sess) != NULL)
                   1052:                sess->config.session_id = random() & 0xffff;
                   1053:        snprintf(sess->hook, sizeof(sess->hook),
                   1054:            NG_L2TP_HOOK_SESSION_F, sess->config.session_id);
                   1055: 
                   1056:        /* Add to control connection hash table */
                   1057:        ctrl->active_sessions++;
                   1058:        if (ghash_put(ctrl->sessions, sess) == -1) {
                   1059:                ppp_l2tp_sess_destroy(&sess);
                   1060:                return (NULL);
                   1061:        }
                   1062: 
                   1063:        /* Create session AVP list to send to peer */
                   1064:        if ((sess->my_avps = ppp_l2tp_avp_list_create()) == NULL) {
                   1065:                ppp_l2tp_sess_destroy(&sess);
                   1066:                return (NULL);
                   1067:        }
                   1068: 
                   1069:        /* Add assigned session ID AVP */
                   1070:        value16 = htons(sess->config.session_id);
                   1071:        if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                   1072:            0, AVP_ASSIGNED_SESSION_ID, &value16, sizeof(value16)) == -1) {
                   1073:                ppp_l2tp_sess_destroy(&sess);
                   1074:                return (NULL);
                   1075:        }
                   1076: 
                   1077:        /* Add call serial number AVP */
                   1078:        value32 = htonl(sess->serial);
                   1079:        if (ppp_l2tp_avp_list_append(sess->my_avps, 1,
                   1080:            0, AVP_CALL_SERIAL_NUMBER, &value32, sizeof(value32)) == -1) {
                   1081:                ppp_l2tp_sess_destroy(&sess);
                   1082:                return (NULL);
                   1083:        }
                   1084: 
                   1085:        /* Done */
                   1086:        CLOG(LOG_DEBUG, "created new session #%u id 0x%04x orig=%s side=%s"
                   1087:            " state=%s", sess->serial, sess->config.session_id,
                   1088:            ppp_l2tp_sess_orig_str(sess->orig),
                   1089:            ppp_l2tp_sess_side_str(sess->side),
                   1090:            ppp_l2tp_sess_state_str(sess->state));
                   1091:        return (sess);
                   1092: }
                   1093: 
                   1094: /*
                   1095:  * Send a control message.
                   1096:  */
                   1097: static void
                   1098: ppp_l2tp_ctrl_send(struct ppp_l2tp_ctrl *ctrl, u_int16_t session_id,
                   1099:        enum l2tp_msg_type msgtype, const struct ppp_l2tp_avp_list *avps0)
                   1100: {
                   1101:        struct ppp_l2tp_avp_list *avps = NULL;
                   1102:        struct ppp_l2tp_avp *avp = NULL;
                   1103:        u_char *data = NULL;
                   1104:        u_int16_t value;
                   1105:        int index;
                   1106:        int len;
                   1107: 
                   1108:        /* Copy AVP list */
                   1109:        avps = (avps0 == NULL) ? ppp_l2tp_avp_list_create()
                   1110:            : ppp_l2tp_avp_list_copy(avps0);
                   1111:        if (avps == NULL)
                   1112:                goto fail;
                   1113: 
                   1114:        /* Remove any message type AVP in the way */
                   1115:        if ((index = ppp_l2tp_avp_list_find(avps, 0, AVP_MESSAGE_TYPE)) != -1)
                   1116:                ppp_l2tp_avp_list_remove(avps, index);
                   1117: 
                   1118:        /* Add message type AVP as first in the list */
                   1119:        value = htons(msgtype);
                   1120:        if ((avp = ppp_l2tp_avp_create(1, 0,
                   1121:            AVP_MESSAGE_TYPE, &value, sizeof(value))) == NULL)
                   1122:                goto fail;
                   1123:        if (ppp_l2tp_avp_list_insert(avps, &avp, 0) == -1)
                   1124:                goto fail;
                   1125: 
                   1126:        /* Encoded AVP's into a packet */
                   1127:        if ((len = ppp_l2tp_avp_pack(ppp_l2tp_avp_info_list,
                   1128:            avps, ctrl->secret, ctrl->seclen, NULL)) == -1)
                   1129:                goto fail;
                   1130:        if ((data = MALLOC(TYPED_MEM_TEMP, 2 + len)) == NULL)
                   1131:                goto fail;
                   1132:        session_id = htons(session_id);
                   1133:        memcpy(data, &session_id, 2);
                   1134:        (void)ppp_l2tp_avp_pack(ppp_l2tp_avp_info_list,
                   1135:            avps, ctrl->secret, ctrl->seclen, data + 2);
                   1136: 
                   1137:        /* Write packet */
                   1138:        if (session_id == 0)
                   1139:                ppp_l2tp_ctrl_dump(ctrl, avps, "XMIT: ");
                   1140:        else {
                   1141:                ppp_l2tp_ctrl_dump(ctrl, avps, "XMIT(0x%04x): ",
                   1142:                    ntohs(session_id));
                   1143:        }
                   1144:        if (NgSendData(ctrl->dsock, NG_L2TP_HOOK_CTRL, data, 2 + len) == -1)
                   1145:                goto fail;
                   1146: 
                   1147:        /* Done */
                   1148:        goto done;
                   1149: 
                   1150: fail:
                   1151:        /* Close up shop */
                   1152:        CLOG(LOG_ERR, "error sending ctrl packet: %m");
                   1153:        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1154:            L2TP_ERROR_GENERIC, strerror(errno));
                   1155: 
                   1156: done:
                   1157:        /* Clean up */
                   1158:        ppp_l2tp_avp_destroy(&avp);
                   1159:        ppp_l2tp_avp_list_destroy(&avps);
                   1160:        FREE(TYPED_MEM_TEMP, data);
                   1161: }
                   1162: 
                   1163: /*
                   1164:  * Close a control connection gracefully, after the next context switch.
                   1165:  */
                   1166: static void
                   1167: ppp_l2tp_ctrl_close(struct ppp_l2tp_ctrl *ctrl,
                   1168:        u_int16_t result, u_int16_t error, const char *errmsg)
                   1169: {
                   1170:        /* Sanity check */
                   1171:        if (ctrl->state == CS_DYING)
                   1172:                return;
                   1173:        ctrl->state = CS_DYING;
                   1174: 
                   1175:        /* Save result code and error string */
                   1176:        ctrl->result = result;
                   1177:        ctrl->error = error;
                   1178:        FREE(CTRL_MEM_TYPE, ctrl->errmsg);
                   1179:        ctrl->errmsg = (errmsg == NULL) ? NULL : STRDUP(CTRL_MEM_TYPE, errmsg);
                   1180: 
                   1181:        /* Notify peer if necessary */
                   1182:        if (!ctrl->peer_notified) {
                   1183:                struct ppp_l2tp_avp_list *avps = NULL;
                   1184:                const size_t elen = (ctrl->errmsg == NULL) ?
                   1185:                    0 : strlen(ctrl->errmsg);
                   1186:                struct ppp_l2tp_sess *sess;
                   1187:                struct ghash_walk walk;
                   1188:                u_char *rbuf = NULL;
                   1189:                u_int16_t value16;
                   1190: 
                   1191:                /* Create AVP list */
                   1192:                ctrl->peer_notified = 1;
                   1193:                if ((avps = ppp_l2tp_avp_list_create()) == NULL) {
                   1194:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_create");
                   1195:                        goto notify_done;
                   1196:                }
                   1197: 
                   1198:                /* Add assigned tunnel ID AVP */
                   1199:                value16 = htons(ctrl->config.tunnel_id);
                   1200:                if (ppp_l2tp_avp_list_append(avps, 1, 0,
                   1201:                    AVP_ASSIGNED_TUNNEL_ID, &value16, sizeof(value16)) == -1) {
                   1202:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_append");
                   1203:                        goto notify_done;
                   1204:                }
                   1205: 
                   1206:                /* Add result code AVP */
                   1207:                if ((rbuf = MALLOC(TYPED_MEM_TEMP, 4 + elen)) == NULL)
                   1208:                        goto notify_done;
                   1209:                value16 = htons(ctrl->result);
                   1210:                memcpy(rbuf, &value16, sizeof(value16));
                   1211:                value16 = htons(ctrl->error);
                   1212:                memcpy(rbuf + 2, &value16, sizeof(value16));
                   1213:                memcpy(rbuf + 4, ctrl->errmsg, elen);
                   1214:                if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RESULT_CODE,
                   1215:                    rbuf, 4 + elen) == -1) {
                   1216:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_append");
                   1217:                        goto notify_done;
                   1218:                }
                   1219: 
                   1220:                /* Send StopCCN */
                   1221:                ppp_l2tp_ctrl_send(ctrl, 0, StopCCN, avps);
                   1222: 
                   1223:                /* StopCCN implies closing all sessions */
                   1224:                ghash_walk_init(ctrl->sessions, &walk);
                   1225:                while ((sess = ghash_walk_next(ctrl->sessions, &walk)) != NULL)
                   1226:                        sess->peer_notified = 1;
                   1227: 
                   1228: notify_done:
                   1229:                /* Clean up */
                   1230:                ppp_l2tp_avp_list_destroy(&avps);
                   1231:                FREE(TYPED_MEM_TEMP, rbuf);
                   1232:        }
                   1233: 
                   1234:        /* Stop all timers */
                   1235:        pevent_unregister(&ctrl->idle_timer);
                   1236:        pevent_unregister(&ctrl->reply_timer);
                   1237:        pevent_unregister(&ctrl->close_timer);
                   1238:        pevent_unregister(&ctrl->death_timer);
                   1239: 
                   1240:        /* Start timer to call ppp_l2tp_ctrl_do_close() */
                   1241:        if (pevent_register(ctrl->ctx, &ctrl->close_timer, 0, ctrl->mutex,
                   1242:            ppp_l2tp_ctrl_do_close, ctrl, PEVENT_TIME, 0) == -1)
                   1243:                CLOG(LOG_ERR, "error starting close timer: %m");
                   1244: }
                   1245: 
                   1246: /*
                   1247:  * Close a control connection gracefully.
                   1248:  *
                   1249:  * We call this in a separate event thread to avoid reentrancy problems.
                   1250:  */
                   1251: static void
                   1252: ppp_l2tp_ctrl_do_close(void *arg)
                   1253: {
                   1254:        struct ppp_l2tp_ctrl *const ctrl = arg;
                   1255:        struct ppp_l2tp_sess *sess;
                   1256:        struct ghash_walk walk;
                   1257: 
                   1258:        /* Remove event */
                   1259:        pevent_unregister(&ctrl->close_timer);
                   1260: 
                   1261:        /* Notify link side about all sessions first */
                   1262:        ghash_walk_init(ctrl->sessions, &walk);
                   1263:        while ((sess = ghash_walk_next(ctrl->sessions, &walk)) != NULL) {
                   1264:                if (sess->link_notified)
                   1265:                        continue;
                   1266:                sess->link_notified = 1;
                   1267:                sess->result = L2TP_RESULT_ERROR;
                   1268:                sess->error = L2TP_ERROR_GENERIC;
                   1269:                FREE(SESS_MEM_TYPE, sess->errmsg);
                   1270:                sess->errmsg = STRDUP(SESS_MEM_TYPE,
                   1271:                    "control connection closing");
                   1272:                (*ctrl->cb->terminated)(sess,
                   1273:                    sess->result, sess->error, sess->errmsg);
                   1274:                sess->link_cookie = NULL;
                   1275:        }
                   1276: 
                   1277:        /* Now notify link side about control connection */
                   1278:        if (!ctrl->link_notified) {
                   1279:                ctrl->link_notified = 1;
                   1280:                (*ctrl->cb->ctrl_terminated)(ctrl, ctrl->result, ctrl->error,
                   1281:                    (ctrl->errmsg != NULL) ? ctrl->errmsg : "");
                   1282:                ctrl->link_cookie = NULL;
                   1283:        }
                   1284: 
                   1285:        /* If no active sessions exist, start dying */
                   1286:        if (ctrl->active_sessions == 0) {
                   1287:                ppp_l2tp_ctrl_death_start(ctrl);
                   1288:                return;
                   1289:        }
                   1290: 
                   1291:        /* Close all active sessions */
                   1292:        ghash_walk_init(ctrl->sessions, &walk);
                   1293:        while ((sess = ghash_walk_next(ctrl->sessions, &walk)) != NULL) {
                   1294:                sess->peer_notified = 1;        /* no need to notify peer */
                   1295:                ppp_l2tp_sess_close(sess, L2TP_RESULT_ERROR,
                   1296:                    L2TP_ERROR_GENERIC, "control connection closing");
                   1297:        }
                   1298: }
                   1299: 
                   1300: /*
                   1301:  * Notify link side that the control connection has gone away
                   1302:  * and begin death timer.
                   1303:  *
                   1304:  * We rig things so that all the session death notifications happen
                   1305:  * before the control connection notification, which happens here.
                   1306:  */
                   1307: static void
                   1308: ppp_l2tp_ctrl_death_start(struct ppp_l2tp_ctrl *ctrl)
                   1309: {
                   1310:        /* Sanity */
                   1311:        assert(ctrl->state == CS_DYING);
                   1312: 
                   1313:        /* Stop timers */
                   1314:        pevent_unregister(&ctrl->idle_timer);
                   1315:        pevent_unregister(&ctrl->reply_timer);
                   1316:        pevent_unregister(&ctrl->close_timer);
                   1317:        pevent_unregister(&ctrl->death_timer);
                   1318: 
                   1319:        /* Linger for a while before going away */
                   1320:        if (pevent_register(ctrl->ctx, &ctrl->death_timer, 0,
                   1321:            ctrl->mutex, ppp_l2tp_ctrl_death_timeout, ctrl,
                   1322:            PEVENT_TIME, L2TP_CTRL_DEATH_TIMEOUT * 1000) == -1)
                   1323:                CLOG(LOG_ERR, "error starting death timer: %m");
                   1324: }
                   1325: 
                   1326: /*
                   1327:  * Handle idle timeout on control connection.
                   1328:  */
                   1329: static void
                   1330: ppp_l2tp_idle_timeout(void *arg)
                   1331: {
                   1332:        struct ppp_l2tp_ctrl *const ctrl = arg;
                   1333: 
                   1334:        /* Remove event */
                   1335:        pevent_unregister(&ctrl->idle_timer);
                   1336: 
                   1337:        /* Restart idle timer */
                   1338:        if (pevent_register(ctrl->ctx, &ctrl->idle_timer, 0,
                   1339:            ctrl->mutex, ppp_l2tp_idle_timeout, ctrl, PEVENT_TIME,
                   1340:            L2TP_IDLE_TIMEOUT * 1000) == -1)
                   1341:                CLOG(LOG_ERR, "error restarting idle timer: %m");
                   1342: 
                   1343:        /* Send a 'hello' packet */
                   1344:        ppp_l2tp_ctrl_send(ctrl, 0, HELLO, NULL);
                   1345: }
                   1346: 
                   1347: /*
                   1348:  * Remove a control connection that has been dead for a while.
                   1349:  */
                   1350: static void
                   1351: ppp_l2tp_ctrl_death_timeout(void *arg)
                   1352: {
                   1353:        struct ppp_l2tp_ctrl *ctrl = arg;
                   1354: 
                   1355:        pevent_unregister(&ctrl->death_timer);
                   1356:        ppp_l2tp_ctrl_destroy(&ctrl);
                   1357: }
                   1358: 
                   1359: /************************************************************************
                   1360:                        INTERNAL FUNCTIONS: SESSIONS
                   1361: ************************************************************************/
                   1362: 
                   1363: /*
                   1364:  * This function handles the situation of a locally initiated incoming
                   1365:  * call, i.e., we are the LAC. Before sending the ICCN to the LNS, two
                   1366:  * events must happen: the LNS must reply with a ICRP, and the link
                   1367:  * side must invoke the ppp_l2tp_connected() function.
                   1368:  */
                   1369: static int
                   1370: ppp_l2tp_sess_check_liic(struct ppp_l2tp_sess *sess)
                   1371: {
                   1372:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   1373: 
                   1374:        /* Are we ready to send ICCN yet? */
                   1375:        if (!sess->link_responded || !sess->peer_responded)
                   1376:                return (0);
                   1377: 
                   1378:        /* Set up session */
                   1379:        if (ppp_l2tp_sess_setup(sess) == -1)
                   1380:                return (-1);
                   1381: 
                   1382:        /* Now send ICCN to peer */
                   1383:        ppp_l2tp_ctrl_send(ctrl, sess->peer_id, ICCN, sess->my_avps);
                   1384: 
                   1385:        /* Done */
                   1386:        return (0);
                   1387: }
                   1388: 
                   1389: /*
                   1390:  * Set up a session that has reached the established state.
                   1391:  */
                   1392: static int
                   1393: ppp_l2tp_sess_setup(struct ppp_l2tp_sess *sess)
                   1394: {
                   1395:        union {
                   1396:            u_char buf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)];
                   1397:            struct ng_mesg reply;
                   1398:        } repbuf;
                   1399:        struct ng_mesg *const reply = &repbuf.reply;
                   1400:        struct nodeinfo ninfo;
                   1401:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   1402:        struct ngm_mkpeer mkpeer;
                   1403:        char path[64];
                   1404: 
                   1405:        /* If link side is waiting for confirmation, schedule it */
                   1406:        if (sess->side == SIDE_LNS) {
                   1407:                pevent_unregister(&sess->notify_timer);
                   1408:                if (pevent_register(ctrl->ctx, &sess->notify_timer, 0,
                   1409:                    ctrl->mutex, ppp_l2tp_sess_notify, sess, PEVENT_TIME,
                   1410:                    0) == -1) {
                   1411:                        CLOG(LOG_ERR, "error starting notify timer: %m");
                   1412:                        goto fail;
                   1413:                }
                   1414:        }
                   1415: 
                   1416:        /* Attach a 'tee' node so l2tp node never sees hook disconnect */
                   1417:        memset(&mkpeer, 0, sizeof(mkpeer));
                   1418:        strlcpy(mkpeer.type, NG_TEE_NODE_TYPE, sizeof(mkpeer.type));
                   1419:        strlcpy(mkpeer.ourhook, sess->hook, sizeof(mkpeer.ourhook));
                   1420:        strlcpy(mkpeer.peerhook, NG_TEE_HOOK_LEFT, sizeof(mkpeer.peerhook));
                   1421:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_GENERIC_COOKIE,
                   1422:            NGM_MKPEER, &mkpeer, sizeof(mkpeer)) == -1) {
                   1423:                CLOG(LOG_ERR, "%s: %m", "mkpeer");
                   1424:                goto fail;
                   1425:        }
                   1426: 
                   1427:        /* Get ng_tee node ID */
                   1428:        snprintf(path, sizeof(path), "%s.%s", NG_L2TP_HOOK_CTRL, sess->hook);
                   1429:        if (NgSendMsg(ctrl->csock, path,
                   1430:            NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) == -1)
                   1431:                goto fail;
                   1432:        if (NgRecvMsg(ctrl->csock, reply, sizeof(repbuf), NULL) == -1)
                   1433:                goto fail;
                   1434:        memcpy(&ninfo, reply->data, sizeof(ninfo));
                   1435:        sess->node_id = ninfo.id;
                   1436: 
                   1437:        /* Configure session hook */
                   1438:        sess->config.control_dseq = sess->dseq_required;
                   1439:        sess->config.enable_dseq = 1;
                   1440:        sess->config.peer_id = sess->peer_id;
                   1441:        if (NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL, NGM_L2TP_COOKIE,
                   1442:            NGM_L2TP_SET_SESS_CONFIG, &sess->config,
                   1443:            sizeof(sess->config)) == -1) {
                   1444:                CLOG(LOG_ERR, "error configuring session hook: %m");
                   1445:                goto fail;
                   1446:        }
                   1447: 
                   1448:        /* Call is now established */
                   1449:        sess->state = SS_ESTABLISHED;
                   1450:        return (0);
                   1451: 
                   1452: fail:
                   1453:        /* Clean up after failure */
                   1454:        pevent_unregister(&sess->notify_timer);
                   1455:        return (-1);
                   1456: }
                   1457: 
                   1458: /*
                   1459:  * Close a session gracefully, after the next context switch.
                   1460:  */
                   1461: static void
                   1462: ppp_l2tp_sess_close(struct ppp_l2tp_sess *sess,
                   1463:        u_int16_t result, u_int16_t error, const char *errmsg)
                   1464: {
                   1465:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   1466: 
                   1467:        /* Sanity check */
                   1468:        if (sess->state == SS_DYING)
                   1469:                return;
                   1470:        sess->state = SS_DYING;
                   1471:        ctrl->active_sessions--;
                   1472: 
                   1473:        /* Save result code and error string */
                   1474:        sess->result = result;
                   1475:        sess->error = error;
                   1476:        FREE(SESS_MEM_TYPE, sess->errmsg);
                   1477:        sess->errmsg = (errmsg == NULL) ? NULL : STRDUP(SESS_MEM_TYPE, errmsg);
                   1478: 
                   1479:        /* Notify peer if necessary */
                   1480:        if (!sess->peer_notified) {
                   1481:                struct ppp_l2tp_avp_list *avps = NULL;
                   1482:                const size_t elen = (sess->errmsg == NULL) ?
                   1483:                    0 : strlen(sess->errmsg);
                   1484:                u_char *rbuf = NULL;
                   1485:                u_int16_t value16;
                   1486: 
                   1487:                /* Create AVP list */
                   1488:                sess->peer_notified = 1;
                   1489:                if ((avps = ppp_l2tp_avp_list_create()) == NULL) {
                   1490:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_create");
                   1491:                        goto notify_done;
                   1492:                }
                   1493: 
                   1494:                /* Add assigned session ID AVP */
                   1495:                value16 = htons(sess->config.session_id);
                   1496:                if (ppp_l2tp_avp_list_append(avps, 1, 0,
                   1497:                    AVP_ASSIGNED_TUNNEL_ID, &value16, sizeof(value16)) == -1) {
                   1498:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_append");
                   1499:                        goto notify_done;
                   1500:                }
                   1501: 
                   1502:                /* Add result code AVP */
                   1503:                if ((rbuf = MALLOC(TYPED_MEM_TEMP, 4 + elen)) == NULL)
                   1504:                        goto notify_done;
                   1505:                value16 = htons(sess->result);
                   1506:                memcpy(rbuf, &value16, sizeof(value16));
                   1507:                value16 = htons(sess->error);
                   1508:                memcpy(rbuf + 2, &value16, sizeof(value16));
                   1509:                memcpy(rbuf + 4, sess->errmsg, elen);
                   1510:                if (ppp_l2tp_avp_list_append(avps, 1, 0, AVP_RESULT_CODE,
                   1511:                    rbuf, 4 + elen) == -1) {
                   1512:                        CLOG(LOG_ERR, "%s: %m", "ppp_l2tp_avp_list_append");
                   1513:                        goto notify_done;
                   1514:                }
                   1515: 
                   1516:                /* Send CDN */
                   1517:                ppp_l2tp_ctrl_send(ctrl, sess->peer_id, CDN, avps);
                   1518: 
                   1519: notify_done:
                   1520:                /* Clean up */
                   1521:                ppp_l2tp_avp_list_destroy(&avps);
                   1522:                FREE(TYPED_MEM_TEMP, rbuf);
                   1523:        }
                   1524: 
                   1525:        /* Stop all session timers */
                   1526:        pevent_unregister(&sess->notify_timer);
                   1527:        pevent_unregister(&sess->reply_timer);
                   1528:        pevent_unregister(&sess->death_timer);
                   1529:        pevent_unregister(&sess->close_timer);
                   1530: 
                   1531:        /* Start timer to call ppp_l2tp_sess_do_close() */
                   1532:        if (pevent_register(ctrl->ctx, &sess->close_timer, 0,
                   1533:            ctrl->mutex, ppp_l2tp_sess_do_close, sess, PEVENT_TIME, 0) == -1)
                   1534:                SLOG(LOG_ERR, "error starting close timer: %m");
                   1535: }
                   1536: 
                   1537: /*
                   1538:  * Close a session gracefully.
                   1539:  *
                   1540:  * We call this in a separate event thread to avoid reentrancy problems.
                   1541:  */
                   1542: static void
                   1543: ppp_l2tp_sess_do_close(void *arg)
                   1544: {
                   1545:        struct ppp_l2tp_sess *const sess = arg;
                   1546:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   1547: 
                   1548:        /* Remove event */
                   1549:        pevent_unregister(&sess->close_timer);
                   1550: 
                   1551:        /* Linger for a while before going away */
                   1552:        if (pevent_register(ctrl->ctx, &sess->death_timer, 0,
                   1553:            ctrl->mutex, ppp_l2tp_sess_death_timeout, sess, PEVENT_TIME,
                   1554:            L2TP_SESS_DEATH_TIMEOUT * 1000) == -1)
                   1555:                CLOG(LOG_ERR, "error starting death timer: %m");
                   1556: 
                   1557:        /* Notify link side about session if necessary */
                   1558:        if (!sess->link_notified) {
                   1559:                sess->link_notified = 1;
                   1560:                (*ctrl->cb->terminated)(sess, sess->result, sess->error,
                   1561:                    (sess->errmsg != NULL) ? sess->errmsg : "");
                   1562:                sess->link_cookie = NULL;
                   1563:        }
                   1564: 
                   1565:        /* Close control connection after last session closes */
                   1566:        if (ctrl->active_sessions == 0) {
                   1567:                if (ctrl->state != CS_DYING) {
                   1568:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_CLEARED,
                   1569:                            0, "no more sessions exist in this tunnel");
                   1570:                } else
                   1571:                        ppp_l2tp_ctrl_death_start(ctrl);
                   1572:        }
                   1573: }
                   1574: 
                   1575: /*
                   1576:  * Notify link side that a session is connected.
                   1577:  *
                   1578:  * We call this in a separate event thread to avoid reentrancy problems.
                   1579:  */
                   1580: static void
                   1581: ppp_l2tp_sess_notify(void *arg)
                   1582: {
                   1583:        struct ppp_l2tp_sess *const sess = arg;
                   1584:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   1585: 
                   1586:        pevent_unregister(&sess->notify_timer);
                   1587:        (*ctrl->cb->connected)(sess, sess->peer_avps);
                   1588: }
                   1589: 
                   1590: /*
                   1591:  * Remove a session that has been dead for a while.
                   1592:  */
                   1593: static void
                   1594: ppp_l2tp_sess_death_timeout(void *arg)
                   1595: {
                   1596:        struct ppp_l2tp_sess *sess = arg;
                   1597: 
                   1598:        pevent_unregister(&sess->death_timer);
                   1599:        ppp_l2tp_sess_destroy(&sess);
                   1600: }
                   1601: 
                   1602: /************************************************************************
                   1603:                        NETGRAPH SOCKET READERS
                   1604: ************************************************************************/
                   1605: 
                   1606: /*
                   1607:  * Read from netgraph data socket. This is where incoming L2TP
                   1608:  * control connection messages appear.
                   1609:  */
                   1610: static void
                   1611: ppp_l2tp_data_event(void *arg)
                   1612: {
                   1613:        struct ppp_l2tp_ctrl *const ctrl = arg;
                   1614:        const struct l2tp_msg_info *msg_info;
                   1615:        struct ppp_l2tp_avp_list *avps = NULL;
                   1616:        struct ppp_l2tp_avp_ptrs *ptrs = NULL;
                   1617:        struct ppp_l2tp_sess *sess;
                   1618:        struct ppp_l2tp_sess key;
                   1619:        static u_char buf[8192];
                   1620:        u_int16_t msgtype;
                   1621:        char ebuf[64];
                   1622:        int len;
                   1623:        int i;
                   1624:        int j;
                   1625: 
                   1626:        /* Restart idle timer */
                   1627:        pevent_unregister(&ctrl->idle_timer);
                   1628:        if (pevent_register(ctrl->ctx, &ctrl->idle_timer, 0,
                   1629:            ctrl->mutex, ppp_l2tp_idle_timeout, ctrl, PEVENT_TIME,
                   1630:            L2TP_IDLE_TIMEOUT * 1000) == -1) {
                   1631:                CLOG(LOG_ERR, "error restarting idle timer: %m");
                   1632:                goto fail_errno;
                   1633:        }
                   1634: 
                   1635:        /* Read packet */
                   1636:        if ((len = read(ctrl->dsock, buf, sizeof(buf))) == -1) {
                   1637:                CLOG(LOG_ERR, "error reading ctrl hook: %m");
                   1638:                goto fail_errno;
                   1639:        }
                   1640: 
                   1641:        /* Extract session ID */
                   1642:        memcpy(&key.config.session_id, buf, 2);
                   1643:        key.config.session_id = ntohs(key.config.session_id);
                   1644: 
                   1645:        /* Parse out AVP's */
                   1646:        if ((avps = ppp_l2tp_avp_unpack(ppp_l2tp_avp_info_list,
                   1647:            buf + 2, len - 2, ctrl->secret, ctrl->seclen)) == NULL) {
                   1648:                switch (errno) {
                   1649:                case EILSEQ:
                   1650:                        CLOG(LOG_WARNING,
                   1651:                            "rec'd improperly formatted control message");
                   1652:                        goto fail_invalid;
                   1653:                case EAUTH:
                   1654:                        CLOG(LOG_WARNING,
                   1655:                            "rec'd hidden AVP, but no shared secret");
                   1656:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1657:                            L2TP_ERROR_GENERIC, "hidden AVP found"
                   1658:                            " but no shared secret configured");
                   1659:                        goto done;
                   1660:                case ENOSYS:
                   1661:                        CLOG(LOG_WARNING, "rec'd mandatory but unknown AVP");
                   1662:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1663:                            L2TP_ERROR_MANDATORY, NULL);
                   1664:                        goto done;
                   1665:                default:
                   1666:                        CLOG(LOG_ERR, "error decoding control message: %m");
                   1667:                        goto fail_errno;
                   1668:                }
                   1669:        }
                   1670: 
                   1671:        /* Debugging */
                   1672:        if (key.config.session_id == 0)
                   1673:                ppp_l2tp_ctrl_dump(ctrl, avps, "RECV: ");
                   1674:        else {
                   1675:                ppp_l2tp_ctrl_dump(ctrl, avps, "RECV(0x%04x): ",
                   1676:                    ntohs(key.config.session_id));
                   1677:        }
                   1678: 
                   1679:        /* Message type AVP must be present and first */
                   1680:        if (avps->length == 0 || avps->avps[0].type != AVP_MESSAGE_TYPE) {
                   1681:                CLOG(LOG_WARNING,
                   1682:                    "rec'd ctrl message lacking message type AVP");
                   1683:                goto fail_invalid;
                   1684:        }
                   1685: 
                   1686:        /* Get message type from message type AVP */
                   1687:        memcpy(&msgtype, avps->avps[0].value, 2);
                   1688:        msgtype = ntohs(msgtype);
                   1689: 
                   1690:        /* Find descriptor for this message type */
                   1691:        for (i = 0; ppp_l2tp_msg_info[i].name != NULL
                   1692:            && msgtype != ppp_l2tp_msg_info[i].type; i++);
                   1693:        if ((msg_info = &ppp_l2tp_msg_info[i])->name == NULL) {
                   1694:                if (avps->avps[0].mandatory) {
                   1695:                        snprintf(ebuf, sizeof(ebuf), "rec'd unsupported"
                   1696:                            " but mandatory message type %u", msgtype);
                   1697:                        CLOG(LOG_WARNING, "%s", ebuf);
                   1698:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1699:                            L2TP_ERROR_BAD_VALUE, ebuf);
                   1700:                        goto done;
                   1701:                }
                   1702:                CLOG(LOG_NOTICE,
                   1703:                    "rec'd unknown message type %u; ignoring", msgtype);
                   1704:                goto done;                              /* just ignore it */
                   1705:        }
                   1706: 
                   1707:        /* Check for missing required AVP's */
                   1708:        for (i = 0; msg_info->req_avps[i] != -1; i++) {
                   1709:                for (j = 0; j < avps->length
                   1710:                    && avps->avps[j].type != msg_info->req_avps[i]; j++);
                   1711:                if (j == avps->length) {
                   1712:                        snprintf(ebuf, sizeof(ebuf), "rec'd %s control"
                   1713:                            " message lacking required AVP #%u",
                   1714:                            msg_info->name, msg_info->req_avps[i]);
                   1715:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1716:                            L2TP_ERROR_BAD_VALUE, ebuf);
                   1717:                        goto done;
                   1718:                }
                   1719:        }
                   1720: 
                   1721:        /* Convert AVP's to friendly form */
                   1722:        if ((ptrs = ppp_l2tp_avp_list2ptrs(avps)) == NULL) {
                   1723:                CLOG(LOG_ERR, "error decoding AVP list: %m");
                   1724:                goto fail_errno;
                   1725:        }
                   1726: 
                   1727:        /* If this is a tunnel-level command, do it */
                   1728:        if (msg_info->ctrl_handler != NULL) {
                   1729: 
                   1730:                /* Check for valid control connection state */
                   1731:                for (i = 0; msg_info->valid_states[i] != -1
                   1732:                    && msg_info->valid_states[i] != ctrl->state; i++);
                   1733:                if (msg_info->valid_states[i] == -1) {
                   1734: 
                   1735:                        /* Could be in CS_DYING if we just closed the tunnel */
                   1736:                        if (ctrl->state == CS_DYING) {
                   1737:                                snprintf(ebuf, sizeof(ebuf),
                   1738:                                    "ignoring %s in state %s", msg_info->name,
                   1739:                                    ppp_l2tp_ctrl_state_str(ctrl->state));
                   1740:                                CLOG(LOG_INFO, "%s", ebuf);
                   1741:                                goto done;
                   1742:                        }
                   1743: 
                   1744:                        /* Log a warning message because the peer is broken */
                   1745:                        snprintf(ebuf, sizeof(ebuf),
                   1746:                            "rec'd %s in state %s", msg_info->name,
                   1747:                            ppp_l2tp_ctrl_state_str(ctrl->state));
                   1748:                        CLOG(LOG_WARNING, "%s", ebuf);
                   1749:                        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_FSM, 0, ebuf);
                   1750:                        goto done;
                   1751:                }
                   1752: 
                   1753:                /* Cancel reply timer and invoke handler */
                   1754:                CLOG((msgtype == HELLO) ? LOG_DEBUG : LOG_INFO,
                   1755:                    "rec'd %s in state %s", msg_info->name,
                   1756:                    ppp_l2tp_ctrl_state_str(ctrl->state));
                   1757:                pevent_unregister(&ctrl->reply_timer);
                   1758:                if ((*msg_info->ctrl_handler)(ctrl, avps, ptrs) == -1)
                   1759:                        goto fail_errno;
                   1760: 
                   1761:                /* If we're now expecting a reply, start expecting it */
                   1762:                ppp_l2tp_ctrl_check_reply(ctrl);
                   1763:                goto done;
                   1764:        }
                   1765: 
                   1766:        /* Find associated session */
                   1767:        if (key.config.session_id == 0) {
                   1768:                struct ghash_walk walk;
                   1769: 
                   1770:                /* This should only happen with CDN messages */
                   1771:                if (msgtype != CDN) {
                   1772:                        CLOG(LOG_NOTICE, "rec'd %s with zero session ID",
                   1773:                            msg_info->name);
                   1774:                        goto done;
                   1775:                }
                   1776: 
                   1777:                /* Find session with 'reverse lookup' using peer's session ID */
                   1778:                ghash_walk_init(ctrl->sessions, &walk);
                   1779:                while ((sess = ghash_walk_next(ctrl->sessions, &walk)) != NULL
                   1780:                    && sess->peer_id != key.config.session_id);
                   1781:                if (sess == NULL)
                   1782:                        goto done;
                   1783:        } else if ((sess = ghash_get(ctrl->sessions, &key)) == NULL) {
                   1784:                CLOG(LOG_NOTICE, "rec'd %s for unknown session 0x%04x",
                   1785:                    msg_info->name, key.config.session_id);
                   1786:                goto done;
                   1787:        }
                   1788: 
                   1789:        /* Check for valid session state, origination, and side */
                   1790:        for (i = 0; msg_info->valid_states[i] != -1
                   1791:            && msg_info->valid_states[i] != sess->state; i++);
                   1792:        if (msg_info->valid_states[i] == -1) {
                   1793:                snprintf(ebuf, sizeof(ebuf), "rec'd %s in state %s",
                   1794:                    msg_info->name, ppp_l2tp_sess_state_str(sess->state));
                   1795:                SLOG(LOG_WARNING, "%s", ebuf);
                   1796:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_FSM, 0, ebuf);
                   1797:                goto done;
                   1798:        }
                   1799:        for (i = 0; msg_info->valid_orig[i] != -1
                   1800:            && msg_info->valid_orig[i] != sess->orig; i++);
                   1801:        if (msg_info->valid_orig[i] == -1) {
                   1802:                snprintf(ebuf, sizeof(ebuf), "rec'd %s in state %s,"
                   1803:                    " but session originated %sly", msg_info->name,
                   1804:                    ppp_l2tp_sess_state_str(sess->state),
                   1805:                    ppp_l2tp_sess_orig_str(sess->orig));
                   1806:                SLOG(LOG_WARNING, "%s", ebuf);
                   1807:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_FSM, 0, ebuf);
                   1808:                goto done;
                   1809:        }
                   1810:        for (i = 0; msg_info->valid_side[i] != -1
                   1811:            && msg_info->valid_side[i] != sess->side; i++);
                   1812:        if (msg_info->valid_side[i] == -1) {
                   1813:                snprintf(ebuf, sizeof(ebuf), "rec'd %s in state %s,"
                   1814:                    " but we are %s for this session", msg_info->name,
                   1815:                    ppp_l2tp_sess_state_str(sess->state),
                   1816:                    ppp_l2tp_sess_side_str(sess->side));
                   1817:                SLOG(LOG_WARNING, "%s", ebuf);
                   1818:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_FSM, 0, ebuf);
                   1819:                goto done;
                   1820:        }
                   1821: 
                   1822:        /* Cancel reply timer and invoke handler */
                   1823:        SLOG(LOG_INFO, "rec'd %s in state %s",
                   1824:            msg_info->name, ppp_l2tp_sess_state_str(sess->state));
                   1825:        pevent_unregister(&sess->reply_timer);
                   1826:        if ((*msg_info->sess_handler)(sess, avps, ptrs) == -1)
                   1827:                goto fail_errno;
                   1828: 
                   1829:        /* If we're now expecting a reply, start expecting it */
                   1830:        ppp_l2tp_sess_check_reply(sess);
                   1831:        goto done;
                   1832: 
                   1833: fail_invalid:
                   1834:        /* Fail because of a bogus message */
                   1835:        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1836:            L2TP_ERROR_BAD_VALUE, "improperly formatted control message");
                   1837:        goto done;
                   1838: 
                   1839: fail_errno:
                   1840:        /* Fail because of a system error */
                   1841:        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1842:            L2TP_ERROR_GENERIC, strerror(errno));
                   1843: 
                   1844: done:
                   1845:        /* Clean up */
                   1846:        ppp_l2tp_avp_list_destroy(&avps);
                   1847:        ppp_l2tp_avp_ptrs_destroy(&ptrs);
                   1848: }
                   1849: 
                   1850: /*
                   1851:  * Read from netgraph control socket. This is where incoming
                   1852:  * netgraph control messages appear.
                   1853:  */
                   1854: static void
                   1855: ppp_l2tp_ctrl_event(void *arg)
                   1856: {
                   1857:        struct ppp_l2tp_ctrl *const ctrl = arg;
                   1858:        union {
                   1859:            u_char buf[128];
                   1860:            struct ng_mesg msg;
                   1861:        } buf;
                   1862:        struct ng_mesg *const msg = &buf.msg;
                   1863:        char raddr[NG_PATHSIZ];
                   1864:        int len;
                   1865: 
                   1866:        /* Read netgraph control message */
                   1867:        if ((len = NgRecvMsg(ctrl->csock, msg, sizeof(buf), raddr)) < 0) {
                   1868:                CLOG(LOG_ERR, "error reading control message: %m");
                   1869:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   1870:                    L2TP_ERROR_GENERIC, strerror(errno));
                   1871:                return;
                   1872:        }
                   1873: 
                   1874:        /* Examine message */
                   1875:        switch (msg->header.typecookie) {
                   1876:        case NGM_L2TP_COOKIE:
                   1877:                switch (msg->header.cmd) {
                   1878:                case NGM_L2TP_ACK_FAILURE:
                   1879:                        if (ctrl->state != CS_DYING) {
                   1880:                                CLOG(LOG_WARNING,
                   1881:                                    "L2TP acknowledgement timeout");
                   1882:                                ppp_l2tp_ctrl_close(ctrl,
                   1883:                                    L2TP_RESULT_CLEARED, 0, NULL);
                   1884:                        }
                   1885:                        break;
                   1886:                default:
                   1887:                        break;
                   1888:                }
                   1889:                break;
                   1890:        default:
                   1891:                break;
                   1892:        }
                   1893: }
                   1894: 
                   1895: /************************************************************************
                   1896:                    INCOMING CONTROL MESSAGE HANDLERS
                   1897: ************************************************************************/
                   1898: 
                   1899: static int
                   1900: ppp_l2tp_handle_SCCRQ(struct ppp_l2tp_ctrl *ctrl,
                   1901:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   1902: {
                   1903:        struct ppp_l2tp_ctrl *ctrl2;
                   1904:        const u_char *tiebreaker;
                   1905:        struct ghash_walk walk;
                   1906:        int diff;
                   1907:        int i;
                   1908: 
                   1909:        /* See if there is an outstanding SCCRQ to this peer */
                   1910:        ghash_walk_init(ppp_l2tp_ctrls, &walk);
                   1911:        while ((ctrl2 = ghash_walk_next(ppp_l2tp_ctrls, &walk)) != NULL) {
                   1912:                if (ctrl2 != ctrl
                   1913:                    && ctrl2->peer_id == ctrl->peer_id
                   1914:                    && ctrl2->state == CS_WAIT_CTL_REPLY)
                   1915:                        break;
                   1916:        }
                   1917:        if (ctrl2 == NULL)
                   1918:                goto ok;
                   1919: 
                   1920:        /* Determine if we used a tie-breaker in our SCCRQ */
                   1921:        for (tiebreaker = NULL, i = 0; i < ctrl2->avps->length; i++) {
                   1922:                struct ppp_l2tp_avp *const avp = &ctrl2->avps->avps[i];
                   1923: 
                   1924:                if (avp->vendor == 0 && avp->type == AVP_TIE_BREAKER) {
                   1925:                        tiebreaker = avp->value;
                   1926:                        break;
                   1927:                }
                   1928:        }
                   1929: 
                   1930:        /* If neither side used a tie-breaker, allow this connection */
                   1931:        if (tiebreaker == NULL && ptrs->tiebreaker == NULL)
                   1932:                goto ok;
                   1933: 
                   1934:        /* Compare tie-breaker values to see who wins */
                   1935:        if (tiebreaker == NULL)                         /* peer wins */
                   1936:                diff = 1;
                   1937:        else if (ptrs->tiebreaker == NULL)              /* i win */
                   1938:                diff = -1;
                   1939:        else                                            /* compare values */
                   1940:                diff = memcmp(tiebreaker, &ptrs->tiebreaker->value, 8);
                   1941:        if (diff == 0) {                                /* we both lose */
                   1942:                CLOG(LOG_NOTICE, "SCCRQ tie: we both lose");
                   1943:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_DUP_CTRL, 0, NULL);
                   1944:                ppp_l2tp_ctrl_close(ctrl2, L2TP_RESULT_DUP_CTRL, 0, NULL);
                   1945:                return (0);
                   1946:        }
                   1947:        if (diff > 0) {                                 /* i win */
                   1948:                CLOG(LOG_NOTICE, "SCCRQ tie: peer loses");
                   1949:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_DUP_CTRL, 0, NULL);
                   1950:                return (0);
                   1951:        }
                   1952:        CLOG(LOG_NOTICE, "SCCRQ tie: peer wins");
                   1953:        ppp_l2tp_ctrl_close(ctrl2, L2TP_RESULT_DUP_CTRL, 0, NULL);
                   1954: 
                   1955: ok:
                   1956:        /* Do control connection setup */
                   1957:        if (ppp_l2tp_ctrl_setup_1(ctrl, ptrs) == -1)
                   1958:                return (-1);
                   1959: 
                   1960:        /* Send response and update state */
                   1961:        ppp_l2tp_ctrl_send(ctrl, 0, SCCRP, ctrl->avps);
                   1962:        ctrl->state = CS_WAIT_CTL_CONNECT;
                   1963:        return (0);
                   1964: }
                   1965: 
                   1966: static int
                   1967: ppp_l2tp_handle_SCCRP(struct ppp_l2tp_ctrl *ctrl,
                   1968:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   1969: {
                   1970:        /* Do control connection setup */
                   1971:        if (ppp_l2tp_ctrl_setup_1(ctrl, ptrs) == -1)
                   1972:                return (-1);
                   1973:        if (ppp_l2tp_ctrl_setup_2(ctrl, ptrs) == -1)
                   1974:                return (-1);
                   1975: 
                   1976:        /* Send response and update state */
                   1977:        ppp_l2tp_ctrl_send(ctrl, 0, SCCCN, ctrl->avps);
                   1978:        ctrl->state = CS_WAIT_CTL_CONNECT;
                   1979:        return (0);
                   1980: }
                   1981: 
                   1982: static int
                   1983: ppp_l2tp_handle_SCCCN(struct ppp_l2tp_ctrl *ctrl,
                   1984:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   1985: {
                   1986:        /* Do control connection setup */
                   1987:        if (ppp_l2tp_ctrl_setup_2(ctrl, ptrs) == -1)
                   1988:                return (-1);
                   1989: 
                   1990:        /* Update state */
                   1991:        ctrl->state = CS_ESTABLISHED;
                   1992:        return (0);
                   1993: }
                   1994: 
                   1995: static int
                   1996: ppp_l2tp_handle_StopCCN(struct ppp_l2tp_ctrl *ctrl,
                   1997:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   1998: {
                   1999:        struct ppp_l2tp_sess *sess;
                   2000:        struct ghash_walk walk;
                   2001: 
                   2002:        /* StopCCN implies closing all sessions */
                   2003:        ctrl->peer_notified = 1;
                   2004:        ghash_walk_init(ctrl->sessions, &walk);
                   2005:        while ((sess = ghash_walk_next(ctrl->sessions, &walk)) != NULL)
                   2006:                sess->peer_notified = 1;
                   2007: 
                   2008:        /* Close control connection */
                   2009:        ppp_l2tp_ctrl_close(ctrl, ptrs->errresultcode->result,
                   2010:            ptrs->errresultcode->error, ptrs->errresultcode->errmsg);
                   2011:        return (0);
                   2012: }
                   2013: 
                   2014: static int
                   2015: ppp_l2tp_handle_HELLO(struct ppp_l2tp_ctrl *ctrl,
                   2016:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2017: {
                   2018:        return (0);
                   2019: }
                   2020: 
                   2021: static int
                   2022: ppp_l2tp_handle_OCRQ(struct ppp_l2tp_ctrl *ctrl,
                   2023:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2024: {
                   2025:        struct ppp_l2tp_sess *sess;
                   2026: 
                   2027:        /* Create new session */
                   2028:        if ((sess = ppp_l2tp_sess_create(ctrl, ORIG_REMOTE, SIDE_LAC)) == NULL)
                   2029:                return (-1);
                   2030:        sess->peer_id = ptrs->sessionid->id;
                   2031: 
                   2032:        /* Send response */
                   2033:        ppp_l2tp_ctrl_send(ctrl, sess->peer_id, OCRP, sess->my_avps);
                   2034: 
                   2035:        /* Notify link side */
                   2036:        (*ctrl->cb->initiated)(ctrl, sess, 1, avps);
                   2037: 
                   2038:        /* Clean up */
                   2039:        return (0);
                   2040: }
                   2041: 
                   2042: static int
                   2043: ppp_l2tp_handle_ICRQ(struct ppp_l2tp_ctrl *ctrl,
                   2044:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2045: {
                   2046:        struct ppp_l2tp_sess *sess;
                   2047: 
                   2048:        /* Create new session */
                   2049:        if ((sess = ppp_l2tp_sess_create(ctrl, ORIG_REMOTE, SIDE_LNS)) == NULL)
                   2050:                return (-1);
                   2051:        sess->peer_id = ptrs->sessionid->id;
                   2052: 
                   2053:        /* Send response */
                   2054:        ppp_l2tp_ctrl_send(ctrl, sess->peer_id, ICRP, sess->my_avps);
                   2055:        ppp_l2tp_sess_check_reply(sess);
                   2056: 
                   2057:        /* Notify link side */
                   2058:        (*ctrl->cb->initiated)(ctrl, sess, 0, avps);
                   2059: 
                   2060:        /* Clean up */
                   2061:        return (0);
                   2062: }
                   2063: 
                   2064: static int
                   2065: ppp_l2tp_handle_OCRP(struct ppp_l2tp_sess *sess,
                   2066:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2067: {
                   2068:        sess->peer_id = ptrs->sessionid->id;
                   2069:        sess->state = SS_WAIT_CONNECT;
                   2070:        return (0);
                   2071: }
                   2072: 
                   2073: static int
                   2074: ppp_l2tp_handle_xCCN(struct ppp_l2tp_sess *sess,
                   2075:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2076: {
                   2077:        /* Save peer's AVP's for this session */
                   2078:        ppp_l2tp_avp_list_destroy(&sess->peer_avps);
                   2079:        if ((sess->peer_avps = ppp_l2tp_avp_list_copy(avps)) == NULL)
                   2080:                return (-1);
                   2081: 
                   2082:        /* Set up session */
                   2083:        sess->dseq_required = (ptrs->seqrequired != NULL);
                   2084:        if (ppp_l2tp_sess_setup(sess) == -1)
                   2085:                return (-1);
                   2086: 
                   2087:        /* Done */
                   2088:        return (0);
                   2089: }
                   2090: 
                   2091: static int
                   2092: ppp_l2tp_handle_ICRP(struct ppp_l2tp_sess *sess,
                   2093:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2094: {
                   2095:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   2096:        char buf[64];
                   2097: 
                   2098:        /* Save peer ID */
                   2099:        sess->peer_id = ptrs->sessionid->id;
                   2100: 
                   2101:        /* Detect duplicate ICRP's */
                   2102:        if (sess->peer_responded) {
                   2103:                snprintf(buf, sizeof(buf), "rec'd duplicate %s in state %s",
                   2104:                    "ICRP", ppp_l2tp_sess_state_str(sess->state));
                   2105:                SLOG(LOG_WARNING, "%s", buf);
                   2106:                ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_FSM, 0, buf);
                   2107:                return (0);
                   2108:        }
                   2109: 
                   2110:        /* Check status for locally initiated incoming call */
                   2111:        sess->peer_responded = 1;
                   2112:        if (ppp_l2tp_sess_check_liic(sess) == -1)
                   2113:                return (-1);
                   2114: 
                   2115:        /* Done */
                   2116:        return (0);
                   2117: }
                   2118: 
                   2119: static int
                   2120: ppp_l2tp_handle_CDN(struct ppp_l2tp_sess *sess,
                   2121:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2122: {
                   2123:        sess->peer_notified = 1;
                   2124:        ppp_l2tp_sess_close(sess, ptrs->errresultcode->result,
                   2125:            ptrs->errresultcode->error, ptrs->errresultcode->errmsg);
                   2126:        return (0);
                   2127: }
                   2128: 
                   2129: static int
                   2130: ppp_l2tp_handle_SLI(struct ppp_l2tp_sess *sess,
                   2131:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2132: {
                   2133:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   2134: 
                   2135:        if (ctrl->cb->set_link_info == NULL)
                   2136:                return (0);
                   2137:        (*ctrl->cb->set_link_info)(sess, ptrs->accm->xmit, ptrs->accm->xmit);
                   2138:        return (0);
                   2139: }
                   2140: 
                   2141: static int
                   2142: ppp_l2tp_handle_WEN(struct ppp_l2tp_sess *sess,
                   2143:        const struct ppp_l2tp_avp_list *avps, struct ppp_l2tp_avp_ptrs *ptrs)
                   2144: {
                   2145:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   2146: 
                   2147:        if (ctrl->cb->wan_error_notify == NULL)
                   2148:                return (0);
                   2149:        (*ctrl->cb->wan_error_notify)(sess, ptrs->callerror->crc,
                   2150:            ptrs->callerror->frame, ptrs->callerror->overrun,
                   2151:            ptrs->callerror->buffer, ptrs->callerror->timeout,
                   2152:            ptrs->callerror->alignment);
                   2153:        return (0);
                   2154: }
                   2155: 
                   2156: /************************************************************************
                   2157:                        REPLY EXPECTORS
                   2158: ************************************************************************/
                   2159: 
                   2160: static pevent_handler_t        ppp_l2tp_ctrl_reply_timeout;
                   2161: static pevent_handler_t        ppp_l2tp_sess_reply_timeout;
                   2162: 
                   2163: static void
                   2164: ppp_l2tp_ctrl_check_reply(struct ppp_l2tp_ctrl *ctrl)
                   2165: {
                   2166:        pevent_unregister(&ctrl->reply_timer);
                   2167:        switch (ctrl->state) {
                   2168:        case CS_IDLE:
                   2169:        case CS_WAIT_CTL_REPLY:
                   2170:        case CS_WAIT_CTL_CONNECT:
                   2171:                if (pevent_register(ctrl->ctx, &ctrl->reply_timer, 0,
                   2172:                    ctrl->mutex, ppp_l2tp_ctrl_reply_timeout, ctrl, PEVENT_TIME,
                   2173:                    L2TP_REPLY_TIMEOUT * 1000) == -1)
                   2174:                        CLOG(LOG_ERR, "error starting reply timer: %m");
                   2175:                break;
                   2176:        default:
                   2177:                break;
                   2178:        }
                   2179: }
                   2180: 
                   2181: static void
                   2182: ppp_l2tp_sess_check_reply(struct ppp_l2tp_sess *sess)
                   2183: {
                   2184:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   2185: 
                   2186:        pevent_unregister(&sess->reply_timer);
                   2187:        switch (sess->state) {
                   2188:        case SS_WAIT_REPLY:
                   2189:        case SS_WAIT_CONNECT:
                   2190:                if (pevent_register(ctrl->ctx, &sess->reply_timer, 0,
                   2191:                    ctrl->mutex, ppp_l2tp_sess_reply_timeout, sess, PEVENT_TIME,
                   2192:                    L2TP_REPLY_TIMEOUT * 1000) == -1)
                   2193:                        SLOG(LOG_ERR, "error starting reply timer: %m");
                   2194:                break;
                   2195:        default:
                   2196:                break;
                   2197:        }
                   2198: }
                   2199: 
                   2200: static void
                   2201: ppp_l2tp_ctrl_reply_timeout(void *arg)
                   2202: {
                   2203:        struct ppp_l2tp_ctrl *const ctrl = arg;
                   2204: 
                   2205:        pevent_unregister(&ctrl->reply_timer);
                   2206:        CLOG(LOG_NOTICE, "reply timeout in state %s",
                   2207:            ppp_l2tp_ctrl_state_str(ctrl->state));
                   2208:        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   2209:            L2TP_ERROR_GENERIC, "expecting reply; none received");
                   2210: }
                   2211: 
                   2212: static void
                   2213: ppp_l2tp_sess_reply_timeout(void *arg)
                   2214: {
                   2215:        struct ppp_l2tp_sess *const sess = arg;
                   2216:        struct ppp_l2tp_ctrl *const ctrl = sess->ctrl;
                   2217: 
                   2218:        pevent_unregister(&sess->reply_timer);
                   2219:        SLOG(LOG_NOTICE, "reply timeout in state %s",
                   2220:            ppp_l2tp_sess_state_str(sess->state));
                   2221:        ppp_l2tp_ctrl_close(ctrl, L2TP_RESULT_ERROR,
                   2222:            L2TP_ERROR_GENERIC, "expecting reply; none received");
                   2223: }
                   2224: 
                   2225: /************************************************************************
                   2226:                CONTROL AND SESSION OBJECT DESTRUCTORS
                   2227: ************************************************************************/
                   2228: 
                   2229: /*
                   2230:  * Immediately destroy a control connection and all associated sessions.
                   2231:  */
                   2232: void
                   2233: ppp_l2tp_ctrl_destroy(struct ppp_l2tp_ctrl **ctrlp)
                   2234: {
                   2235:        struct ppp_l2tp_ctrl *const ctrl = *ctrlp;
                   2236: 
                   2237:        /* Sanity */
                   2238:        if (ctrl == NULL)
                   2239:                return;
                   2240:        *ctrlp = NULL;
                   2241: 
                   2242:        /* Destroy all sessions */
                   2243:        while (ghash_size(ctrl->sessions) > 0) {
                   2244:                struct ppp_l2tp_sess *sess;
                   2245:                struct ghash_walk walk;
                   2246: 
                   2247:                ghash_walk_init(ctrl->sessions, &walk);
                   2248:                sess = ghash_walk_next(ctrl->sessions, &walk);
                   2249:                ppp_l2tp_sess_destroy(&sess);
                   2250:        }
                   2251: 
                   2252:        /* Destroy netgraph node */
                   2253:        (void)NgSendMsg(ctrl->csock, NG_L2TP_HOOK_CTRL,
                   2254:            NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0);
                   2255: 
                   2256:        /* Destroy control connection */
                   2257:        ghash_remove(ppp_l2tp_ctrls, ctrl);
                   2258:        if (ghash_size(ppp_l2tp_ctrls) == 0)
                   2259:                ghash_destroy(&ppp_l2tp_ctrls);
                   2260:        (void)close(ctrl->csock);
                   2261:        (void)close(ctrl->dsock);
                   2262:        ppp_log_close(&ctrl->log);
                   2263:        pevent_unregister(&ctrl->reply_timer);
                   2264:        pevent_unregister(&ctrl->close_timer);
                   2265:        pevent_unregister(&ctrl->death_timer);
                   2266:        pevent_unregister(&ctrl->idle_timer);
                   2267:        pevent_unregister(&ctrl->ctrl_event);
                   2268:        pevent_unregister(&ctrl->data_event);
                   2269:        ppp_l2tp_avp_list_destroy(&ctrl->avps);
                   2270:        ghash_destroy(&ctrl->sessions);
                   2271:        FREE(CTRL_MEM_TYPE, ctrl->secret);
                   2272:        FREE(CTRL_MEM_TYPE, ctrl->errmsg);
                   2273:        memset(ctrl, 0, sizeof(*ctrl));
                   2274:        FREE(CTRL_MEM_TYPE, ctrl);
                   2275: }
                   2276: 
                   2277: /*
                   2278:  * Immediately destroy a session.
                   2279:  */
                   2280: static void
                   2281: ppp_l2tp_sess_destroy(struct ppp_l2tp_sess **sessp)
                   2282: {
                   2283:        struct ppp_l2tp_sess *const sess = *sessp;
                   2284:        struct ppp_l2tp_ctrl *ctrl;
                   2285:        char path[32];
                   2286: 
                   2287:        /* Sanity */
                   2288:        if (sess == NULL)
                   2289:                return;
                   2290:        *sessp = NULL;
                   2291: 
                   2292:        /* Destroy session */
                   2293:        ctrl = sess->ctrl;
                   2294:        if (sess->state != SS_DYING)
                   2295:                ctrl->active_sessions--;
                   2296:        ghash_remove(ctrl->sessions, sess);
                   2297:        snprintf(path, sizeof(path), "[%lx]:", (u_long)sess->node_id);
                   2298:        (void)NgSendMsg(ctrl->csock, path,
                   2299:            NGM_GENERIC_COOKIE, NGM_SHUTDOWN, NULL, 0);
                   2300:        ppp_log_close(&sess->log);
                   2301:        ppp_l2tp_avp_list_destroy(&sess->my_avps);
                   2302:        ppp_l2tp_avp_list_destroy(&sess->peer_avps);
                   2303:        pevent_unregister(&sess->notify_timer);
                   2304:        pevent_unregister(&sess->reply_timer);
                   2305:        pevent_unregister(&sess->close_timer);
                   2306:        pevent_unregister(&sess->death_timer);
                   2307:        FREE(SESS_MEM_TYPE, sess->errmsg);
                   2308:        memset(sess, 0, sizeof(*sess));
                   2309:        FREE(SESS_MEM_TYPE, sess);
                   2310: }
                   2311: 
                   2312: /************************************************************************
                   2313:                        HASH TABLE FUNCTIONS
                   2314: ************************************************************************/
                   2315: 
                   2316: static int
                   2317: ppp_l2tp_ctrl_equal(struct ghash *g, const void *item1, const void *item2)
                   2318: {
                   2319:        const struct ppp_l2tp_ctrl *const ctrl1 = item1;
                   2320:        const struct ppp_l2tp_ctrl *const ctrl2 = item2;
                   2321: 
                   2322:        return (ctrl1->config.tunnel_id == ctrl2->config.tunnel_id);
                   2323: }
                   2324: 
                   2325: static u_int32_t
                   2326: ppp_l2tp_ctrl_hash(struct ghash *g, const void *item)
                   2327: {
                   2328:        const struct ppp_l2tp_ctrl *const ctrl = item;
                   2329: 
                   2330:        return ((u_int32_t)ctrl->config.tunnel_id);
                   2331: }
                   2332: 
                   2333: static int
                   2334: ppp_l2tp_sess_equal(struct ghash *g, const void *item1, const void *item2)
                   2335: {
                   2336:        const struct ppp_l2tp_sess *const sess1 = item1;
                   2337:        const struct ppp_l2tp_sess *const sess2 = item2;
                   2338: 
                   2339:        return (sess1->config.session_id == sess2->config.session_id);
                   2340: }
                   2341: 
                   2342: static u_int32_t
                   2343: ppp_l2tp_sess_hash(struct ghash *g, const void *item)
                   2344: {
                   2345:        const struct ppp_l2tp_sess *const sess = item;
                   2346: 
                   2347:        return ((u_int32_t)sess->config.session_id);
                   2348: }
                   2349: 
                   2350: /************************************************************************
                   2351:                        STRING CONVERTERS
                   2352: ************************************************************************/
                   2353: 
                   2354: /*
                   2355:  * Dump an AVP list.
                   2356:  */
                   2357: static void
                   2358: ppp_l2tp_ctrl_dump(struct ppp_l2tp_ctrl *ctrl,
                   2359:        struct ppp_l2tp_avp_list *avps, const char *fmt, ...)
                   2360: {
                   2361:        char buf[1024];
                   2362:        va_list args;
                   2363:        int i;
                   2364: 
                   2365:        va_start(args, fmt);
                   2366:        vsnprintf(buf, sizeof(buf), fmt, args);
                   2367:        va_end(args);
                   2368:        for (i = 0; i < avps->length; i++) {
                   2369:                struct ppp_l2tp_avp *const avp = &avps->avps[i];
                   2370:                const struct ppp_l2tp_avp_info *info;
                   2371:                int j;
                   2372: 
                   2373:                strlcat(buf, i > 0 ? " [" : "[", sizeof(buf));
                   2374:                for (j = 0; (info = &ppp_l2tp_avp_info_list[j])->name != NULL
                   2375:                    && (info->vendor != avp->vendor
                   2376:                      || info->type != avp->type); j++);
                   2377:                if (info->name != NULL) {
                   2378:                        strlcat(buf, info->name, sizeof(buf));
                   2379:                        strlcat(buf, " ", sizeof(buf));
                   2380:                        (*info->decode)(info, avp,
                   2381:                            buf + strlen(buf), sizeof(buf) - strlen(buf));
                   2382:                } else {
                   2383:                        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                   2384:                            "%u:%u vlen=%u", avp->vendor, avp->type, avp->vlen);
                   2385:                }
                   2386:                strlcat(buf, "]", sizeof(buf));
                   2387:        }
                   2388:        CLOG(LOG_DEBUG, "%s", buf);
                   2389: }
                   2390: 
                   2391: static const char *
                   2392: ppp_l2tp_ctrl_state_str(enum l2tp_ctrl_state state)
                   2393: {
                   2394:        static char buf[32];
                   2395: 
                   2396:        switch (state) {
                   2397:        case CS_IDLE:
                   2398:                return ("idle");
                   2399:        case CS_WAIT_CTL_REPLY:
                   2400:                return ("wait-ctl-reply");
                   2401:        case CS_WAIT_CTL_CONNECT:
                   2402:                return ("wait-ctl-conn");
                   2403:        case CS_ESTABLISHED:
                   2404:                return ("established");
                   2405:        case CS_DYING:
                   2406:                return ("dying");
                   2407:        default:
                   2408:                snprintf(buf, sizeof(buf), "?%u?", state);
                   2409:                return (buf);
                   2410:        }
                   2411: }
                   2412: 
                   2413: static const char *
                   2414: ppp_l2tp_sess_state_str(enum l2tp_ctrl_state state)
                   2415: {
                   2416:        static char buf[32];
                   2417: 
                   2418:        switch (state) {
                   2419:        case SS_WAIT_REPLY:
                   2420:                return ("wait-cs-reply");
                   2421:        case SS_WAIT_CONNECT:
                   2422:                return ("wait-connect");
                   2423:        case SS_WAIT_ANSWER:
                   2424:                return ("wait-answer");
                   2425:        case SS_ESTABLISHED:
                   2426:                return ("established");
                   2427:        case SS_DYING:
                   2428:                return ("dying");
                   2429:        default:
                   2430:                snprintf(buf, sizeof(buf), "?%u?", state);
                   2431:                return (buf);
                   2432:        }
                   2433: }
                   2434: 
                   2435: static const char *
                   2436: ppp_l2tp_sess_orig_str(enum l2tp_sess_orig orig)
                   2437: {
                   2438:        return (orig == ORIG_LOCAL ? "local" : "remote");
                   2439: }
                   2440: 
                   2441: static const char *
                   2442: ppp_l2tp_sess_side_str(enum l2tp_sess_side side)
                   2443: {
                   2444:        return (side == SIDE_LNS ? "LNS" : "LAC");
                   2445: }
                   2446: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>