Annotation of embedaddon/mpd/src/pptp_ctrl.c, revision 1.1.1.2

1.1       misho       1: 
                      2: /*
                      3:  * pptp_ctrl.c
                      4:  *
                      5:  * Written by Archie Cobbs <archie@freebsd.org>
                      6:  * Copyright (c) 1998-1999 Whistle Communications, Inc. All rights reserved.
                      7:  * See ``COPYRIGHT.whistle''
                      8:  */
                      9: 
                     10: #include "ppp.h"
                     11: #include "log.h"
                     12: #include "pptp_ctrl.h"
                     13: #include "util.h"
                     14: 
                     15: #include <netinet/tcp.h>
                     16: 
                     17: /*
                     18:  * DEFINITIONS
                     19:  */
                     20: 
                     21:   #define PPTP_FIRMWARE_REV            0x0101
                     22: 
                     23:   #define PPTP_STR_INTERNAL_CALLING    "Internally originated VPN call"
                     24: 
                     25:   /* Limits on how long we wait for replies to things */
                     26:   #define PPTP_DFL_REPLY_TIME          PPTP_IDLE_TIMEOUT
                     27:   #define PPTP_OUTCALLREQ_REPLY_TIME   90
                     28:   #define PPTP_INCALLREP_REPLY_TIME    90
                     29:   #define PPTP_STOPCCR_REPLY_TIME      3
                     30: 
                     31:   /* Retry for binding to listen socket */
                     32:   #define PPTP_LISTEN_RETRY            10
                     33: 
                     34:   /* This describes how/if a reply is required */
                     35:   struct pptpreqrep {
                     36:     u_char     reply;                  /* required reply (or zero) */
                     37:     u_char     killCtrl;               /* fatal to ctrl or just to channel */
                     38:     u_short    timeout;                /* max time to wait for reply */
                     39:   };
                     40:   typedef struct pptpreqrep    *PptpReqRep;
                     41: 
                     42:   /* This represents a pending reply we're waiting for */
                     43:   struct pptppendrep {
                     44:     const struct pptpmsginfo   *request;       /* original message info */
                     45:     struct pptpctrl            *ctrl;          /* control channel */
                     46:     struct pptpchan            *chan;          /* channel (NULL if none) */
                     47:     struct pppTimer            timer;          /* reply timeout timer */
                     48:     struct pptppendrep         *next;          /* next in list */
                     49:   };
                     50:   typedef struct pptppendrep   *PptpPendRep;
                     51: 
                     52:   /* This describes how to match a message to the corresponding channel */
                     53:   struct pptpchanid {
                     54:     u_char             findIn;         /* how to find channel (incoming) */
                     55:     u_char             findOut;        /* how to find channel (outgoing) */
                     56:     const char         *inField;       /* field used to find channel (in) */
                     57:     const char         *outField;      /* field used to find channel (out) */
                     58:   };
                     59:   typedef struct pptpchanid    *PptpChanId;
                     60: 
                     61:   #define PPTP_FIND_CHAN_MY_CID                1       /* match field vs. my cid */
                     62:   #define PPTP_FIND_CHAN_PEER_CID      2       /* match field vs. peer cid */
                     63:   #define PPTP_FIND_CHAN_PNS_CID       3       /* match field vs. PNS cid */
                     64:   #define PPTP_FIND_CHAN_PAC_CID       4       /* match field vs. PAC cid */
                     65: 
                     66:   /* Total info about a message type (except field layout) */
                     67:   struct pptpmsginfo {
                     68:     const char         *name;          /* name for this message type */
                     69:     void               (*handler)();   /* message handler function */
                     70:     u_char             isReply;        /* this is always a reply message */
                     71:     u_char             length;         /* length of message (sans header) */
                     72:     u_short            states;         /* states which admit this message */
                     73:     struct pptpchanid  match;          /* how to find corresponding channel */
                     74:     struct pptpreqrep  reqrep;         /* what kind of reply we expect */
                     75:   };
                     76:   typedef const struct pptpmsginfo     *PptpMsgInfo;
                     77: 
                     78:   /* Receive window size XXX */
                     79:   #define PPTP_RECV_WIN                        16
                     80: 
                     81:   /* Packet processing delay XXX */
                     82:   #define PPTP_PPD                     1
                     83: 
                     84:   /* Channel state */
                     85:   struct pptpchan {
                     86:     uint16_t           id;             /* channel index */
                     87:     u_char             state;          /* channel state */
                     88:     u_char             orig;           /* call originated from us */
                     89:     u_char             incoming;       /* call is incoming, not outgoing */
                     90:     u_int16_t          cid;            /* my call id */
                     91:     u_int16_t          serno;          /* call serial number */
                     92:     u_int16_t          peerCid;        /* peer call id */
                     93:     u_int16_t          peerPpd;        /* peer's packet processing delay */
                     94:     u_int16_t          recvWin;        /* peer's recv window size */
                     95:     u_int32_t          bearType;       /* call bearer type */
                     96:     u_int32_t          frameType;      /* call framing type */
                     97:     u_int32_t          minBps;         /* minimum acceptable speed */
                     98:     u_int32_t          maxBps;         /* maximum acceptable speed */
                     99:     struct pptplinkinfo        linfo;          /* info about corresponding link */
                    100:     struct pptpctrl    *ctrl;          /* my control channel */
                    101:     char               callingNum[PPTP_PHONE_LEN + 1]; /* calling number */
                    102:     char               calledNum[PPTP_PHONE_LEN + 1];  /* called number */
                    103:     char               subAddress[PPTP_SUBADDR_LEN + 1];/* sub-address */
                    104:     struct pppTimer    killTimer;      /* kill timer */
                    105:   };
                    106:   typedef struct pptpchan      *PptpChan;
                    107: 
                    108:   #define PPTP_CHAN_IS_PNS(ch)         (!(ch)->orig ^ !(ch)->incoming)
                    109: 
                    110:   /* Control channel state */
                    111:   struct pptpctrl {
                    112:     u_int32_t          id;             /* channel index */
                    113:     u_char             state;          /* state */
                    114:     u_char             orig;           /* we originated connection */
                    115:     union {
                    116:        u_char                  buf[PPTP_CTRL_MAX_FRAME];
                    117:        struct pptpMsgHead      hdr;
                    118:     }                  frame;
                    119:     u_int16_t          flen;           /* length of partial frame */
                    120:     int                        csock;          /* peer control messages */
                    121:     struct u_addr      self_addr;      /* local IP address */
                    122:     struct u_addr      peer_addr;      /* peer we're talking to */
                    123:     in_port_t          self_port;
                    124:     in_port_t          peer_port;
                    125:     EventRef           connEvent;      /* connection event */
                    126:     EventRef           ctrlEvent;      /* control connection input */
                    127:     struct pppTimer    idleTimer;      /* idle timer */
                    128:     struct pppTimer    killTimer;      /* kill timer */
                    129:     u_int32_t          echoId;         /* last echo id # sent */
                    130:     PptpPendRep                reps;           /* pending replies to msgs */
                    131:     PptpChan           *channels;      /* array of channels */
                    132:     int                        numChannels;    /* length of channels array */
                    133:     u_int              active_sessions;        /* # non-dying sessns */
                    134:     char               self_name[MAXHOSTNAMELEN]; /* local hostname */
                    135:     char               peer_name[MAXHOSTNAMELEN]; /* remote hostname */
                    136:   };
                    137:   typedef struct pptpctrl      *PptpCtrl;
                    138: 
                    139:   struct pptplis {
                    140:     struct u_addr      self_addr;      /* local IP address */
                    141:     in_port_t          self_port;
                    142:     int                        ref;
                    143:     int                        sock;
                    144:     EventRef           retry;
                    145:     EventRef           event;
                    146:   };
                    147:   typedef struct pptplis       *PptpLis;
                    148: 
                    149:   /* Our physical channel ID */
                    150:   #define PHYS_CHAN(ch)                (((ch)->ctrl->id << 16) | (ch)->id)
                    151: 
                    152:   int  PptpsStat(Context ctx, int ac, char *av[], void *arg);
                    153: 
                    154: /*
                    155:  * INTERNAL FUNCTIONS
                    156:  */
                    157: 
                    158:   /* Methods for each control message type */
                    159:   static void  PptpStartCtrlConnRequest(PptpCtrl c,
                    160:                        struct pptpStartCtrlConnRequest *m);
                    161:   static void  PptpStartCtrlConnReply(PptpCtrl c,
                    162:                        struct pptpStartCtrlConnReply *m);
                    163:   static void  PptpStopCtrlConnRequest(PptpCtrl c,
                    164:                        struct pptpStopCtrlConnRequest *m);
                    165:   static void  PptpStopCtrlConnReply(PptpCtrl c,
                    166:                        struct pptpStopCtrlConnReply *m);
                    167:   static void  PptpEchoRequest(PptpCtrl c, struct pptpEchoRequest *m);
                    168:   static void  PptpEchoReply(PptpCtrl c, struct pptpEchoReply *m);
                    169:   static void  PptpOutCallRequest(PptpCtrl c, struct pptpOutCallRequest *m);
                    170:   static void  PptpOutCallReply(PptpChan ch, struct pptpOutCallReply *m);
                    171:   static void  PptpInCallRequest(PptpCtrl c, struct pptpInCallRequest *m);
                    172:   static void  PptpInCallReply(PptpChan ch, struct pptpInCallReply *m);
                    173:   static void  PptpInCallConn(PptpChan ch, struct pptpInCallConn *m);
                    174:   static void  PptpCallClearRequest(PptpChan ch,
                    175:                        struct pptpCallClearRequest *m);
                    176:   static void  PptpCallDiscNotify(PptpChan ch, struct pptpCallDiscNotify *m);
                    177:   static void  PptpWanErrorNotify(PptpChan ch, struct pptpWanErrorNotify *m);
                    178:   static void  PptpSetLinkInfo(PptpChan ch, struct pptpSetLinkInfo *m);
                    179: 
                    180:   /* Link layer callbacks */
                    181:   static void  PptpCtrlCloseChan(PptpChan ch,
                    182:                  int result, int error, int cause);
                    183:   static void  PptpCtrlKillChan(PptpChan ch, const char *errmsg);
                    184:   static void  PptpCtrlFreeChan(PptpChan ch);
                    185:   static void  PptpCtrlDialResult(void *cookie,
                    186:                  int result, int error, int cause, int speed);
                    187:   static void  PptpCtrlConected(void *cookie, int speed);
                    188:   static void  PptpCtrlSetLinkInfo(void *cookie, u_int32_t sa, u_int32_t ra);
                    189: 
                    190:   /* Internal event handlers */
                    191:   static void  PptpCtrlListenEvent(int type, void *cookie);
                    192:   static void  PptpCtrlListenRetry(int type, void *cookie);
                    193:   static void  PptpCtrlConnEvent(int type, void *cookie);
                    194:   static void  PptpCtrlReadCtrl(int type, void *cookie);
                    195: 
                    196:   /* Shutdown routines */
                    197:   static void  PptpCtrlCloseCtrl(PptpCtrl c);
                    198:   static void  PptpCtrlKillCtrl(PptpCtrl c);
                    199:   static void  PptpCtrlFreeCtrl(PptpCtrl c);
                    200: 
                    201:   /* Timer routines */
                    202:   static void  PptpCtrlResetIdleTimer(PptpCtrl c);
                    203:   static void  PptpCtrlIdleTimeout(void *arg);
                    204:   static void  PptpCtrlReplyTimeout(void *arg);
                    205: 
                    206:   /* Misc routines */
                    207:   static void  PptpCtrlInitCtrl(PptpCtrl c, int orig);
                    208:   static void  PptpCtrlMsg(PptpCtrl c, int type, void *msg);
                    209:   static int   PptpCtrlWriteMsg(PptpCtrl c, int type, void *msg);
                    210: 
                    211:   static void  PptpCtrlSwap(int type, void *buf);
                    212:   static void  PptpCtrlDump(int level, int type, void *msg);
                    213:   static int   PptpCtrlFindField(int type, const char *name, u_int *offset);
                    214:   static void  PptpCtrlInitCinfo(PptpChan ch, PptpCtrlInfo ci);
                    215: 
                    216:   static void  PptpCtrlNewCtrlState(PptpCtrl c, int new);
                    217:   static void  PptpCtrlNewChanState(PptpChan ch, int new);
                    218: 
                    219:   static void          PptpCtrlOrigCall(int incoming, struct pptpctrlinfo *cinfo,
                    220:                          struct pptplinkinfo *linfo, struct u_addr *locip,
                    221:                          struct u_addr *ip, in_port_t port, int bearType,
                    222:                          int frameType, int minBps, int maxBps,
                    223:                          const char *callingNum, const char *calledNum,
                    224:                          const char *subAddress);
                    225: 
                    226:   static PptpCtrl      PptpCtrlGetCtrl(int orig, struct u_addr *self_addr,
                    227:                          struct u_addr *peer_addr, in_port_t peer_port,
                    228:                          char *buf, size_t bsiz);
                    229:   static PptpChan      PptpCtrlGetChan(PptpCtrl c, int chanState, int orig,
                    230:                          int incoming, int bearType, int frameType, int minBps,
                    231:                          int maxBps, const char *callingNum,
                    232:                          const char *calledNum, const char *subAddress);
                    233:   static PptpChan      PptpCtrlFindChan(PptpCtrl c, int type,
                    234:                          void *msg, int incoming);
                    235:   static void          PptpCtrlCheckConn(PptpCtrl c);
                    236: 
                    237: /*
                    238:  * INTERNAL VARIABLES
                    239:  */
                    240: 
                    241:   static u_char                        gInitialized = 0;
                    242:   static u_int16_t             gLastCallId;
                    243:   static u_char                        gCallIds[65536];
                    244:   static PptpGetInLink_t       gGetInLink;
                    245:   static PptpGetOutLink_t      gGetOutLink;
                    246: 
                    247:   static PptpCtrl              *gPptpCtrl;     /* array of control channels */
                    248:   static int                   gNumPptpCtrl;   /* length of gPptpCtrl array */
                    249: 
                    250:   static PptpLis               *gPptpLis;      /* array of listeners */
                    251:   static int                   gNumPptpLis;    /* length of gPptpLis array */
                    252: 
                    253:   /* Control message field layout */
                    254:   static struct pptpfield
                    255:     gPptpMsgLayout[PPTP_MAX_CTRL_TYPE][PPTP_CTRL_MAX_FIELDS] =
                    256:   {
                    257: #define _WANT_PPTP_FIELDS
                    258: #include "pptp_ctrl.h"
                    259: #undef _WANT_PPTP_FIELDS
                    260:   };
                    261: 
                    262:   /* Control channel and call state names */
                    263:   static const char            *gPptpCtrlStates[] = {
                    264: #define PPTP_CTRL_ST_FREE              0
                    265:                    "FREE",
                    266: #define PPTP_CTRL_ST_IDLE              1
                    267:                    "IDLE",
                    268: #define PPTP_CTRL_ST_WAIT_CTL_REPLY    2
                    269:                    "WAIT_CTL_REPLY",
                    270: #define PPTP_CTRL_ST_WAIT_STOP_REPLY   3
                    271:                    "WAIT_STOP_REPLY",
                    272: #define PPTP_CTRL_ST_ESTABLISHED       4
                    273:                    "ESTABLISHED",
                    274: #define PPTP_CTRL_ST_DYING             5
                    275:                    "DYING",
                    276:   };
                    277: 
                    278:   static const char            *gPptpChanStates[] = {
                    279: #define PPTP_CHAN_ST_FREE              0
                    280:                    "FREE",
                    281: #define PPTP_CHAN_ST_WAIT_IN_REPLY     1
                    282:                    "WAIT_IN_REPLY",
                    283: #define PPTP_CHAN_ST_WAIT_OUT_REPLY    2
                    284:                    "WAIT_OUT_REPLY",
                    285: #define PPTP_CHAN_ST_WAIT_CONNECT      3
                    286:                    "WAIT_CONNECT",
                    287: #define PPTP_CHAN_ST_WAIT_DISCONNECT   4
                    288:                    "WAIT_DISCONNECT",
                    289: #define PPTP_CHAN_ST_WAIT_ANSWER       5
                    290:                    "WAIT_ANSWER",
                    291: #define PPTP_CHAN_ST_ESTABLISHED       6
                    292:                    "ESTABLISHED",
                    293: #define PPTP_CHAN_ST_WAIT_CTRL         7
                    294:                    "WAIT_CTRL",
                    295: #define PPTP_CHAN_ST_DYING             8
                    296:                    "DYING",
                    297:   };
                    298: 
                    299:   /* Control message descriptors */
                    300: #define CL(s)  (1 << (PPTP_CTRL_ST_ ## s))
                    301: #define CH(s)  ((1 << (PPTP_CHAN_ST_ ## s)) | 0x8000)
                    302: 
                    303:   static const struct pptpmsginfo      gPptpMsgInfo[PPTP_MAX_CTRL_TYPE] = {
                    304:     { "PptpMsgHead", NULL,                     /* placeholder */
                    305:       FALSE, sizeof(struct pptpMsgHead),
                    306:     },
                    307:     { "StartCtrlConnRequest", PptpStartCtrlConnRequest,
                    308:       FALSE, sizeof(struct pptpStartCtrlConnRequest),
                    309:       CL(IDLE),
                    310:       { 0, 0 },                                        /* no associated channel */
                    311:       { PPTP_StartCtrlConnReply, TRUE, PPTP_DFL_REPLY_TIME },
                    312:     },
                    313:     { "StartCtrlConnReply", PptpStartCtrlConnReply,
                    314:       TRUE, sizeof(struct pptpStartCtrlConnReply),
                    315:       CL(WAIT_CTL_REPLY),
                    316:       { 0, 0 },                                        /* no associated channel */
                    317:       { 0 },                                   /* no reply expected */
                    318:     },
                    319:     { "StopCtrlConnRequest", PptpStopCtrlConnRequest,
                    320:       FALSE, sizeof(struct pptpStopCtrlConnRequest),
                    321:       CL(WAIT_CTL_REPLY)|CL(WAIT_STOP_REPLY)|CL(ESTABLISHED),
                    322:       { 0, 0 },                                        /* no associated channel */
                    323:       { PPTP_StopCtrlConnReply, TRUE, PPTP_STOPCCR_REPLY_TIME },
                    324:     },
                    325:     { "StopCtrlConnReply", PptpStopCtrlConnReply,
                    326:       TRUE, sizeof(struct pptpStopCtrlConnReply),
                    327:       CL(WAIT_STOP_REPLY),
                    328:       { 0, 0 },                                        /* no associated channel */
                    329:       { 0 },                                   /* no reply expected */
                    330:     },
                    331:     { "EchoRequest", PptpEchoRequest,
                    332:       FALSE, sizeof(struct pptpEchoRequest),
                    333:       CL(ESTABLISHED),
                    334:       { 0, 0 },                                        /* no associated channel */
                    335:       { PPTP_EchoReply, TRUE, PPTP_DFL_REPLY_TIME },
                    336:     },
                    337:     { "EchoReply", PptpEchoReply,
                    338:       TRUE, sizeof(struct pptpEchoReply),
                    339:       CL(ESTABLISHED),
                    340:       { 0, 0 },                                        /* no associated channel */
                    341:       { 0 },                                   /* no reply expected */
                    342:     },
                    343:     { "OutCallRequest", PptpOutCallRequest,
                    344:       FALSE, sizeof(struct pptpOutCallRequest),
                    345:       CL(ESTABLISHED),
                    346:       { 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" },
                    347:       { PPTP_OutCallReply, TRUE, PPTP_OUTCALLREQ_REPLY_TIME },
                    348:     },
                    349:     { "OutCallReply", PptpOutCallReply,
                    350:       TRUE, sizeof(struct pptpOutCallReply),
                    351:       CH(WAIT_OUT_REPLY),
                    352:       { PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" },
                    353:       { 0 },                                   /* no reply expected */
                    354:     },
                    355:     { "InCallRequest", PptpInCallRequest,
                    356:       FALSE, sizeof(struct pptpInCallRequest),
                    357:       CL(ESTABLISHED),
                    358:       { 0, PPTP_FIND_CHAN_MY_CID, NULL, "cid" },
                    359:       { PPTP_InCallReply, FALSE, PPTP_DFL_REPLY_TIME },
                    360:     },
                    361:     { "InCallReply", PptpInCallReply,
                    362:       TRUE, sizeof(struct pptpInCallReply),
                    363:       CH(WAIT_IN_REPLY),
                    364:       { PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_MY_CID, "peerCid", "cid" },
                    365:       { PPTP_InCallConn, FALSE, PPTP_INCALLREP_REPLY_TIME },
                    366:     },
                    367:     { "InCallConn", PptpInCallConn,
                    368:       TRUE, sizeof(struct pptpInCallConn),
                    369:       CH(WAIT_CONNECT),
                    370:       { PPTP_FIND_CHAN_MY_CID, PPTP_FIND_CHAN_PEER_CID, "peerCid", "peerCid" },
                    371:       { 0 },                                   /* no reply expected */
                    372:     },
                    373:     { "CallClearRequest", PptpCallClearRequest,
                    374:       FALSE, sizeof(struct pptpCallClearRequest),
                    375:       CH(WAIT_IN_REPLY)|CH(WAIT_ANSWER)|CH(ESTABLISHED),
                    376:       { PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" },
                    377:       { PPTP_CallDiscNotify, TRUE, PPTP_DFL_REPLY_TIME },
                    378:     },
                    379:     { "CallDiscNotify", PptpCallDiscNotify,
                    380:       FALSE, sizeof(struct pptpCallDiscNotify),
                    381:       CH(WAIT_OUT_REPLY)|CH(WAIT_CONNECT)|CH(WAIT_DISCONNECT)|CH(ESTABLISHED),
                    382:       { PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" },
                    383:       { 0 },                                   /* no reply expected */
                    384:     },
                    385:     { "WanErrorNotify", PptpWanErrorNotify,
                    386:       FALSE, sizeof(struct pptpWanErrorNotify),
                    387:       CH(ESTABLISHED),
                    388:       { PPTP_FIND_CHAN_PNS_CID, PPTP_FIND_CHAN_PNS_CID, "cid", "cid" },
                    389:       { 0 },                                   /* no reply expected */
                    390:     },
                    391:     { "SetLinkInfo", PptpSetLinkInfo,
                    392:       FALSE, sizeof(struct pptpSetLinkInfo),
                    393:       CH(ESTABLISHED),
                    394:       { PPTP_FIND_CHAN_PAC_CID, PPTP_FIND_CHAN_PAC_CID, "cid", "cid" },
                    395:       { 0 },                                   /* no reply expected */
                    396:     },
                    397:   };
                    398: 
                    399: #undef CL
                    400: #undef CH
                    401: 
                    402:   /* Error code to string converters */
                    403:   #define DECODE(a, n) ((u_int)(n) < (sizeof(a) / sizeof(*(a))) ? \
                    404:                            (a)[(u_int)(n)] : "[out of range]")
                    405: 
                    406:   static const char    *const gPptpErrorCodes[] = {
                    407:     "none",
                    408:     "not connected",
                    409:     "bad format",
                    410:     "bad value",
                    411:     "no resource",
                    412:     "bad call ID",
                    413:     "pac error",
                    414:   };
                    415:   #define PPTP_ERROR_CODE(n)           DECODE(gPptpErrorCodes, (n))
                    416: 
                    417:   static const char    *const gPptpSccrReslCodes[] = {
                    418:     "zero?",
                    419:     "OK",
                    420:     "general error",
                    421:     "channel exists",
                    422:     "not authorized",
                    423:     "bad protocol version",
                    424:   };
                    425:   #define PPTP_SCCR_RESL_CODE(n)       DECODE(gPptpSccrReslCodes, (n))
                    426: 
                    427:   static const char    *const gPptpSccrReasCodes[] = {
                    428:     "zero?",
                    429:     "none",
                    430:     "bad protocol version",
                    431:     "local shutdown",
                    432:   };
                    433:   #define PPTP_SCCR_REAS_CODE(n)       DECODE(gPptpSccrReasCodes, (n))
                    434: 
                    435:   static const char    *const gPptpEchoReslCodes[] = {
                    436:     "zero?",
                    437:     "OK",
                    438:     "general error",
                    439:   };
                    440:   #define PPTP_ECHO_RESL_CODE(n)       DECODE(gPptpEchoReslCodes, (n))
                    441: 
                    442:   static const char    *const gPptpOcrReslCodes[] = {
                    443:     "zero?",
                    444:     "OK",
                    445:     "general error",
                    446:     "no carrier",
                    447:     "busy",
                    448:     "no dialtone",
                    449:     "timed out",
                    450:     "admin prohib",
                    451:   };
                    452:   #define PPTP_OCR_RESL_CODE(n)                DECODE(gPptpOcrReslCodes, (n))
                    453: 
                    454:   static const char    *const gPptpIcrReslCodes[] = {
                    455:     "zero?",
                    456:     "OK",
                    457:     "general error",
                    458:     "not accepted",
                    459:   };
                    460:   #define PPTP_ICR_RESL_CODE(n)                DECODE(gPptpIcrReslCodes, (n))
                    461: 
                    462:   static const char    *const gPptpCdnReslCodes[] = {
                    463:     "zero?",
                    464:     "lost carrier",
                    465:     "general error",
                    466:     "admin action",
                    467:     "disconnect request",
                    468:   };
                    469:   #define PPTP_CDN_RESL_CODE(n)                DECODE(gPptpCdnReslCodes, (n))
                    470: 
                    471: /*************************************************************************
                    472:                        EXPORTED FUNCTIONS
                    473: *************************************************************************/
                    474: 
                    475: /*
                    476:  * PptpCtrlInit()
                    477:  *
                    478:  * Initialize PPTP state and set up callbacks. This must be called
                    479:  * first, and any calls after the first will ignore the ip parameter.
                    480:  * Returns 0 if successful, -1 otherwise.
                    481:  *
                    482:  * Parameters:
                    483:  *   getInLink Function to call when a peer has requested to establish
                    484:  *             an incoming call. If returned cookie is NULL, call failed.
                    485:  *             This pointer may be NULL to deny all incoming calls.
                    486:  *   getOutLink        Function to call when a peer has requested to establish
                    487:  *             an outgoming call. If returned cookie is NULL, call failed.
                    488:  *             This pointer may be NULL to deny all outgoing calls.
                    489:  *   ip                The IP address for my server to use (cannot be zero).
                    490:  */
                    491: 
                    492: int
                    493: PptpCtrlInit(PptpGetInLink_t getInLink, PptpGetOutLink_t getOutLink)
                    494: {
                    495:     int        type;
                    496: 
                    497:     /* Save callbacks */
                    498:     gGetInLink = getInLink;
                    499:     gGetOutLink = getOutLink;
                    500:     if (gInitialized)
                    501:        return(0);
                    502: 
                    503:     /* Generate semi-random call ID */
                    504: #ifdef RANDOMIZE_CID
                    505:     gLastCallId = (u_short) (time(NULL) ^ (gPid << 5));
                    506: #endif
                    507:     bzero(gCallIds, sizeof(gCallIds));
                    508: 
                    509:     /* Sanity check structure lengths and valid state bits */
                    510:     for (type = 0; type < PPTP_MAX_CTRL_TYPE; type++) {
                    511:        PptpMsgInfo     const mi = &gPptpMsgInfo[type];
                    512:        PptpField       field = gPptpMsgLayout[type];
                    513:        int             total;
                    514: 
                    515:        assert((mi->match.inField != NULL) ^ !(mi->states & 0x8000));
                    516:        for (total = 0; field->name; field++)
                    517:            total += field->length;
                    518:        assert(total == gPptpMsgInfo[type].length);
                    519:     }
                    520: 
                    521:     /* Done */
                    522:     gInitialized = TRUE;
                    523:     return(0);
                    524: }
                    525: 
                    526: /*
                    527:  * PptpCtrlListen()
                    528:  *
                    529:  * Enable incoming PPTP TCP connections.
                    530:  * Returns not-NULL if successful, NULL otherwise.
                    531:  */
                    532: 
                    533: void *
                    534: PptpCtrlListen(struct u_addr *ip, in_port_t port)
                    535: {
                    536:     char       buf[48];
                    537:     PptpLis    l;
                    538:     int                k;
                    539: 
                    540:     assert(gInitialized);
                    541:     port = port ? port : PPTP_PORT;
                    542:     
                    543:     /* See if we're already have a listener matching this address and port */
                    544:     for (k = 0; k < gNumPptpLis; k++) {
                    545:        PptpLis const l = gPptpLis[k];
                    546: 
                    547:        if (l != NULL
                    548:            && (!u_addrcompare (&l->self_addr, ip))
                    549:            && l->self_port == port) {
                    550:                l->ref++;
                    551:                return(l);
                    552:         }
                    553:     }
                    554: 
                    555:     /* Find/create a free one */
                    556:     for (k = 0; k < gNumPptpLis && gPptpLis[k] != NULL; k++);
                    557:     if (k == gNumPptpLis)
                    558:        LengthenArray(&gPptpLis, sizeof(*gPptpLis), &gNumPptpLis, MB_PPTP);
                    559: 
                    560:     l = Malloc(MB_PPTP, sizeof(*l));
                    561:     l->ref = 1;
                    562:     l->self_addr = *ip;
                    563:     l->self_port = port;
                    564:     if ((l->sock = TcpGetListenPort(ip, port, FALSE)) < 0) {
                    565:         if (errno == EADDRINUSE || errno == EADDRNOTAVAIL) {
                    566:            EventRegister(&l->retry, EVENT_TIMEOUT, PPTP_LISTEN_RETRY * 1000,
                    567:                0, PptpCtrlListenRetry, l);
                    568:         } else {
                    569:            Freee(l);
                    570:            Log(LG_ERR, ("PPTP: can't get listening socket"));
                    571:            return(NULL);
                    572:        }
                    573:     } else {
                    574:        EventRegister(&l->event, EVENT_READ,
                    575:            l->sock, EVENT_RECURRING, PptpCtrlListenEvent, l);
                    576:     }
                    577:     gPptpLis[k] = l;
                    578:     Log(LG_PHYS, ("PPTP: waiting for connection on %s %u",
                    579:        u_addrtoa(&l->self_addr, buf, sizeof(buf)), l->self_port));
                    580:     return(l);
                    581: }
                    582: 
                    583: /*
                    584:  * PptpCtrlUnListen()
                    585:  *
                    586:  * Disable incoming PPTP TCP connections.
                    587:  */
                    588: 
                    589: void
                    590: PptpCtrlUnListen(void *listener)
                    591: {
                    592:     PptpLis    l = (PptpLis)listener;
                    593:     char       buf[48];
                    594:     int                k;
                    595: 
                    596:     assert(l);
                    597:     
                    598:     l->ref--;
                    599:     if (l->ref > 0)
                    600:        return;
                    601: 
                    602:     Log(LG_PHYS, ("PPTP: stop waiting for connection on %s %u",
                    603:        u_addrtoa(&l->self_addr, buf, sizeof(buf)), l->self_port));
                    604: 
                    605:     for (k = 0; k < gNumPptpLis && gPptpLis[k] != l; k++);
                    606:     assert(k != gNumPptpLis);
                    607:     
                    608:     gPptpLis[k] = NULL;
                    609:     EventUnRegister(&l->retry);
                    610:     EventUnRegister(&l->event);
                    611:     close(l->sock);
                    612:     Freee(l);
                    613: }
                    614: 
                    615: /*
                    616:  * PptpCtrlListenRetry()
                    617:  *
                    618:  * Socket address was temporarily unavailable; try again.
                    619:  */
                    620: 
                    621: static void
                    622: PptpCtrlListenRetry(int type, void *cookie)
                    623: {
                    624:     PptpLis const      l = (PptpLis)cookie;
                    625: 
                    626:     if ((l->sock = TcpGetListenPort(&l->self_addr, l->self_port, FALSE)) < 0) {
                    627:        EventRegister(&l->retry, EVENT_TIMEOUT, PPTP_LISTEN_RETRY * 1000,
                    628:            0, PptpCtrlListenRetry, l);
                    629:     } else {
                    630:        EventRegister(&l->event, EVENT_READ,
                    631:            l->sock, EVENT_RECURRING, PptpCtrlListenEvent, l);
                    632:     }
                    633: }
                    634: 
                    635: /*
                    636:  * PptpCtrlInCall()
                    637:  *
                    638:  * Initiate an incoming call
                    639:  */
                    640: 
                    641: void
                    642: PptpCtrlInCall(struct pptpctrlinfo *cinfo, struct pptplinkinfo *linfo,
                    643:        struct u_addr *locip, struct u_addr *ip, in_port_t port,
                    644:        int bearType, int frameType, int minBps, int maxBps, const char *callingNum,
                    645:        const char *calledNum, const char *subAddress)
                    646: {
                    647:     PptpCtrlOrigCall(TRUE, cinfo, linfo, locip, ip, port,
                    648:        bearType, frameType, minBps, maxBps,
                    649:        callingNum, calledNum, subAddress);
                    650: }
                    651: 
                    652: /*
                    653:  * PptpCtrlOutCall()
                    654:  *
                    655:  * Initiate an outgoing call
                    656:  */
                    657: 
                    658: void
                    659: PptpCtrlOutCall(struct pptpctrlinfo *cinfo, struct pptplinkinfo *linfo,
                    660:        struct u_addr *locip, struct u_addr *ip, in_port_t port, int bearType,
                    661:        int frameType, int minBps, int maxBps,
                    662:        const char *calledNum, const char *subAddress)
                    663: {
                    664:     PptpCtrlOrigCall(FALSE, cinfo, linfo, locip, ip, port,
                    665:        bearType, frameType, minBps, maxBps,
                    666:         PPTP_STR_INTERNAL_CALLING, calledNum, subAddress);
                    667: }
                    668: 
                    669: /*
                    670:  * PptpCtrlOrigCall()
                    671:  *
                    672:  * Request from the PPTP peer at ip:port the establishment of an
                    673:  * incoming or outgoing call (as viewed by the peer). The "result"
                    674:  * callback will be called when the connection has been established
                    675:  * or failed to do so. This initiates a TCP control connection if
                    676:  * needed; otherwise it uses the existing connection. If port is
                    677:  * zero, then use the normal PPTP port.
                    678:  */
                    679: 
                    680: static void
                    681: PptpCtrlOrigCall(int incoming, struct pptpctrlinfo *cinfo, struct pptplinkinfo *linfo,
                    682:        struct u_addr *locip, struct u_addr *ip, in_port_t port, int bearType,
                    683:        int frameType, int minBps, int maxBps, const char *callingNum,
                    684:        const char *calledNum, const char *subAddress)
                    685: {
                    686:   PptpCtrl             c;
                    687:   PptpChan             ch;
                    688:   char                 ebuf[64];
                    689: 
                    690:   /* Init */
                    691:   assert(gInitialized);
                    692:   port = port ? port : PPTP_PORT;
1.1.1.2 ! misho     693:   memset(cinfo, 0, sizeof(*cinfo));
1.1       misho     694: 
                    695:   /* Find/create control block */
                    696:   if ((c = PptpCtrlGetCtrl(TRUE, locip, ip, port,
                    697:       ebuf, sizeof(ebuf))) == NULL) {
                    698:     Log(LG_PHYS2, ("%s", ebuf));
                    699:     return;
                    700:   }
                    701: 
                    702:   /* Get new channel */
                    703:   if ((ch = PptpCtrlGetChan(c, PPTP_CHAN_ST_WAIT_CTRL, TRUE, incoming,
                    704:       bearType, frameType, minBps, maxBps,
                    705:       callingNum, calledNum, subAddress)) == NULL) {
                    706:     PptpCtrlKillCtrl(c);
                    707:     return;
                    708:   }
                    709:   ch->linfo = *linfo;
                    710: 
                    711:   /* Control channel may be ready already; start channel if so */
                    712:   PptpCtrlCheckConn(c);
                    713: 
                    714:   /* Return OK */
                    715:   PptpCtrlInitCinfo(ch, cinfo);
                    716: }
                    717: 
                    718: /*
                    719:  * PptpCtrlGetSessionInfo()
                    720:  *
                    721:  * Returns information associated with a call.
                    722:  */
                    723: 
                    724: int
                    725: PptpCtrlGetSessionInfo(struct pptpctrlinfo *cp,
                    726:        struct u_addr *selfAddr, struct u_addr *peerAddr,
                    727:        u_int16_t *selfCid, u_int16_t *peerCid,
                    728:        u_int16_t *peerWin, u_int16_t *peerPpd)
                    729: {
                    730:   PptpChan     const ch = (PptpChan)cp->cookie;
                    731: 
                    732:   switch (ch->state) {
                    733:     case PPTP_CHAN_ST_WAIT_IN_REPLY:
                    734:     case PPTP_CHAN_ST_WAIT_OUT_REPLY:
                    735:     case PPTP_CHAN_ST_WAIT_CONNECT:
                    736:     case PPTP_CHAN_ST_WAIT_DISCONNECT:
                    737:     case PPTP_CHAN_ST_WAIT_ANSWER:
                    738:     case PPTP_CHAN_ST_ESTABLISHED:
                    739:     case PPTP_CHAN_ST_WAIT_CTRL:
                    740:       {
                    741:        PptpCtrl        const c = ch->ctrl;
                    742: 
                    743:        if (selfAddr != NULL)
                    744:          *selfAddr = c->self_addr;
                    745:        if (peerAddr != NULL)
                    746:          *peerAddr = c->peer_addr;
                    747:        if (selfCid != NULL)
                    748:          *selfCid = ch->cid;
                    749:        if (peerCid != NULL)
                    750:          *peerCid = ch->peerCid;
                    751:        if (peerWin != NULL)
                    752:          *peerWin = ch->recvWin;
                    753:        if (peerPpd != NULL)
                    754:          *peerPpd = ch->peerPpd;
                    755:        return(0);
                    756:      }
                    757:     case PPTP_CHAN_ST_FREE:
                    758:     case PPTP_CHAN_ST_DYING:
                    759:       return(-1);
                    760:       break;
                    761:     default:
                    762:       assert(0);
                    763:   }
                    764:   return(-1);  /* NOTREACHED */
                    765: }
                    766: 
                    767: int
                    768: PptpCtrlGetSelfName(struct pptpctrlinfo *cp, void *buf, size_t buf_len) {
                    769:     PptpChan   const ch = (PptpChan)cp->cookie;
                    770:     PptpCtrl   const c = ch->ctrl;
                    771:     
                    772:     strlcpy(buf, c->self_name, buf_len);
                    773:     return (0);
                    774: };
                    775: 
                    776: int
                    777: PptpCtrlGetPeerName(struct pptpctrlinfo *cp, void *buf, size_t buf_len) {
                    778:     PptpChan   const ch = (PptpChan)cp->cookie;
                    779:     PptpCtrl   const c = ch->ctrl;
                    780:     
                    781:     strlcpy(buf, c->peer_name, buf_len);
                    782:     return (0);
                    783: };
                    784: 
                    785: /*************************************************************************
                    786:                        CONTROL CONNECTION SETUP
                    787: *************************************************************************/
                    788: 
                    789: /*
                    790:  * PptpCtrlListenEvent()
                    791:  *
                    792:  * Someone has connected to our TCP socket on which we were listening.
                    793:  */
                    794: 
                    795: static void
                    796: PptpCtrlListenEvent(int type, void *cookie)
                    797: {
                    798:     PptpLis const              l = (PptpLis)cookie;
                    799:   struct sockaddr_storage      peerst, selfst;
                    800:   struct u_addr                        peer_addr, self_addr;
                    801:   in_port_t                    peer_port, self_port;
                    802:   char                         ebuf[64];
                    803:   PptpCtrl                     c;
                    804:   int                          sock;
                    805:   char                         buf[48], buf2[48];
                    806:   socklen_t                    addrLen;
                    807:   
                    808:     /* Accept connection */
                    809:     if ((sock = TcpAcceptConnection(l->sock, &peerst, FALSE)) < 0)
                    810:        return;
                    811:     sockaddrtou_addr(&peerst,&peer_addr,&peer_port);
                    812: 
                    813:     /* Get local IP address */
                    814:     addrLen = sizeof(selfst);
                    815:     if (getsockname(sock, (struct sockaddr *) &selfst, &addrLen) < 0) {
                    816:        Perror("PPTP: %s getsockname()", __func__);
                    817:        u_addrclear(&self_addr);
                    818:        self_port = 0;
                    819:     } else {
                    820:        sockaddrtou_addr(&selfst, &self_addr, &self_port);
                    821:     }
                    822:     Log(LG_PHYS2, ("PPTP: Incoming control connection from %s %u to %s %u",
                    823:        u_addrtoa(&peer_addr, buf, sizeof(buf)), peer_port,
                    824:        u_addrtoa(&self_addr, buf2, sizeof(buf2)), self_port));
                    825: 
                    826:     /* Initialize a new control block */
                    827:     if ((c = PptpCtrlGetCtrl(FALSE, &self_addr, &peer_addr, peer_port,
                    828:            ebuf, sizeof(ebuf))) == NULL) {
                    829:        Log(LG_PHYS2, ("PPTP: Control connection failed: %s", ebuf));
                    830:        close(sock);
                    831:        return;
                    832:     }
                    833:     c->csock = sock;
                    834: 
                    835:     /* Initialize the session */
                    836:     PptpCtrlInitCtrl(c, FALSE);
                    837: }
                    838: 
                    839: /*
                    840:  * PptpCtrlConnEvent()
                    841:  *
                    842:  * We are trying to make a TCP connection to the peer. When this
                    843:  * either succeeds or fails, we jump to here.
                    844:  */
                    845: 
                    846: static void
                    847: PptpCtrlConnEvent(int type, void *cookie)
                    848: {
                    849:   PptpCtrl             const c = (PptpCtrl) cookie;
                    850:   struct sockaddr_storage      addr;
                    851:   socklen_t            addrLen = sizeof(addr);
                    852:   char                 buf[48];
                    853: 
                    854:   /* Get event */
                    855:   assert(c->state == PPTP_CTRL_ST_IDLE);
                    856: 
                    857:   /* Check whether the connection was successful or not */
                    858:   if (getpeername(c->csock, (struct sockaddr *) &addr, &addrLen) < 0) {
                    859:     Log(LG_PHYS2, ("pptp%d: connection to %s %d failed",
                    860:       c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
                    861:     PptpCtrlKillCtrl(c);
                    862:     return;
                    863:   }
                    864: 
                    865:   /* Initialize the session */
                    866:   Log(LG_PHYS2, ("pptp%d: connected to %s %u",
                    867:     c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
                    868:   PptpCtrlInitCtrl(c, TRUE);
                    869: }
                    870: 
                    871: /*
                    872:  * PptpCtrlInitCtrl()
                    873:  *
                    874:  * A TCP connection has just been established. Initialize the
                    875:  * control block for this connection and initiate the session.
                    876:  */
                    877: 
                    878: static void
                    879: PptpCtrlInitCtrl(PptpCtrl c, int orig)
                    880: {
                    881:   struct sockaddr_storage      self, peer;
                    882:   static const int     one = 1;
                    883:   int                  k;
                    884:   socklen_t            addrLen;
                    885:   char                 buf[48];
                    886: 
                    887:   /* Good time for a sanity check */
                    888:   assert(c->state == PPTP_CTRL_ST_IDLE);
                    889:   assert(!c->reps);
                    890:   for (k = 0; k < c->numChannels; k++) {
                    891:     PptpChan   const ch = c->channels[k];
                    892: 
                    893:     assert(ch == NULL || ch->state == PPTP_CHAN_ST_WAIT_CTRL);
                    894:   }
                    895: 
                    896:   /* Initialize control state */
                    897:   c->orig = orig;
                    898:   c->echoId = 0;
                    899:   c->flen = 0;
                    900: 
                    901:   /* Get local IP address */
                    902:   addrLen = sizeof(self);
                    903:   if (getsockname(c->csock, (struct sockaddr *) &self, &addrLen) < 0) {
                    904:     Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "getsockname", strerror(errno)));
                    905: abort:
                    906:     PptpCtrlKillCtrl(c);
                    907:     return;
                    908:   }
                    909:   sockaddrtou_addr(&self, &c->self_addr, &c->self_port);
                    910: 
                    911:   /* Get remote IP address */
                    912:   addrLen = sizeof(peer);
                    913:   if (getpeername(c->csock, (struct sockaddr *) &peer, &addrLen) < 0) {
                    914:     Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "getpeername", strerror(errno)));
                    915:     goto abort;
                    916:   }
                    917:   sockaddrtou_addr(&peer, &c->peer_addr, &c->peer_port);
                    918: 
                    919:   /* Log which control block */
                    920:   Log(LG_PHYS2, ("pptp%d: attached to connection with %s %u",
                    921:     c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
                    922: 
                    923:   /* Turn of Nagle algorithm on the TCP socket, since we are going to
                    924:      be writing complete control frames one at a time */
                    925:   if (setsockopt(c->csock, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0)
                    926:     Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "setsockopt", strerror(errno)));
                    927: 
                    928:   /* Register for events on control and data sockets */
                    929:   EventRegister(&c->ctrlEvent, EVENT_READ,
                    930:     c->csock, EVENT_RECURRING, PptpCtrlReadCtrl, c);
                    931: 
                    932:   /* Start echo keep-alive timer */
                    933:   PptpCtrlResetIdleTimer(c);
                    934: 
                    935:   /* If we originated the call, we start the conversation */
                    936:   if (c->orig) {
                    937:     struct pptpStartCtrlConnRequest    msg;
                    938: 
                    939:     memset(&msg, 0, sizeof(msg));
                    940:     msg.vers = PPTP_PROTO_VERS;
                    941:     msg.frameCap = PPTP_FRAMECAP_ANY;
                    942:     msg.bearCap = PPTP_BEARCAP_ANY;
                    943:     msg.firmware = PPTP_FIRMWARE_REV;
                    944:     gethostname(c->self_name, sizeof(c->self_name) - 1);
                    945:     c->self_name[sizeof(c->self_name) - 1] = '\0';
                    946:     strlcpy(msg.host, c->self_name, sizeof(msg.host));
                    947:     strncpy(msg.vendor, MPD_VENDOR, sizeof(msg.vendor));
                    948:     PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_WAIT_CTL_REPLY);
                    949:     PptpCtrlWriteMsg(c, PPTP_StartCtrlConnRequest, &msg);
                    950:   }
                    951: }
                    952: 
                    953: /*************************************************************************
                    954:                CONTROL CONNECTION MESSAGE HANDLING
                    955: *************************************************************************/
                    956: 
                    957: /*
                    958:  * PptpCtrlReadCtrl()
                    959:  */
                    960: 
                    961: static void
                    962: PptpCtrlReadCtrl(int type, void *cookie)
                    963: {
                    964:   PptpCtrl     const c = (PptpCtrl) cookie;
                    965:   PptpMsgHead  const hdr = &c->frame.hdr;
                    966:   int          nread;
                    967: 
                    968:   /* Figure how much to read and read it */
                    969:   nread = (c->flen < sizeof(*hdr) ? sizeof(*hdr) : hdr->length) - c->flen;
                    970:   if ((nread = read(c->csock, c->frame.buf + c->flen, nread)) <= 0) {
                    971:     if (nread < 0) {
                    972:       if (errno == EAGAIN)
                    973:        return;
                    974:       Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "read", strerror(errno)));
                    975:     } else
                    976:       Log(LG_PHYS2, ("pptp%d: ctrl connection closed by peer", c->id));
                    977:     goto abort;
                    978:   }
                    979:   LogDumpBuf(LG_FRAME, c->frame.buf + c->flen, nread,
                    980:     "pptp%d: read %d bytes ctrl data", c->id, nread);
                    981:   c->flen += nread;
                    982: 
                    983:   /* Do whatever with what we got */
                    984:   if (c->flen < sizeof(*hdr))                  /* incomplete header */
                    985:     return;
                    986:   if (c->flen == sizeof(*hdr)) {               /* complete header */
                    987:     PptpCtrlSwap(0, hdr);              /* byte swap header */
                    988:     Log(LG_FRAME, ("pptp%d: got hdr", c->id));
                    989:     PptpCtrlDump(LG_FRAME, 0, hdr);
                    990:     if (hdr->msgType != PPTP_CTRL_MSG_TYPE) {
                    991:       Log(LG_PHYS2, ("pptp%d: invalid msg type %d", c->id, hdr->msgType));
                    992:       goto abort;
                    993:     }
                    994:     if (hdr->magic != PPTP_MAGIC) {
                    995:       Log(LG_PHYS2, ("pptp%d: invalid magic %x", c->id, hdr->type));
                    996:       goto abort;
                    997:     }
                    998:     if (!PPTP_VALID_CTRL_TYPE(hdr->type)) {
                    999:       Log(LG_PHYS2, ("pptp%d: invalid ctrl type %d", c->id, hdr->type));
                   1000:       goto abort;
                   1001:     }
                   1002:     if (hdr->resv0 != 0) {
                   1003:       Log(LG_PHYS2, ("pptp%d: non-zero reserved field in header", c->id));
                   1004: #if 0
                   1005:       goto abort;
                   1006: #endif
                   1007:     }
                   1008:     if (hdr->length != sizeof(*hdr) + gPptpMsgInfo[hdr->type].length) {
                   1009:       Log(LG_PHYS2, ("pptp%d: invalid length %d for type %d",
                   1010:        c->id, hdr->length, hdr->type));
                   1011: abort:
                   1012:       PptpCtrlKillCtrl(c);
                   1013:       return;
                   1014:     }
                   1015:     return;
                   1016:   }
                   1017:   if (c->flen == hdr->length) {                        /* complete message */
                   1018:     void       *const msg = ((u_char *) hdr) + sizeof(*hdr);
                   1019: 
                   1020:     PptpCtrlSwap(hdr->type, msg);              /* byte swap message */
                   1021:     Log(LG_PHYS3, ("pptp%d: recv %s", c->id, gPptpMsgInfo[hdr->type].name));
                   1022:     PptpCtrlDump(LG_PHYS3, hdr->type, msg);
                   1023:     c->flen = 0;
                   1024:     PptpCtrlResetIdleTimer(c);
                   1025:     PptpCtrlMsg(c, hdr->type, msg);
                   1026:   }
                   1027: }
                   1028: 
                   1029: /*
                   1030:  * PptpCtrlMsg()
                   1031:  *
                   1032:  * We read a complete control message. Sanity check it and handle it.
                   1033:  */
                   1034: 
                   1035: static void
                   1036: PptpCtrlMsg(PptpCtrl c, int type, void *msg)
                   1037: {
                   1038:   PptpMsgInfo  const mi = &gPptpMsgInfo[type];
                   1039:   PptpField    field = gPptpMsgLayout[type];
                   1040:   PptpChan     ch = NULL;
                   1041:   PptpPendRep  *pp;
                   1042:   u_int                off;
                   1043:   static u_char        zeros[4];
                   1044: 
                   1045:   /* Make sure all reserved fields are zero */
                   1046:   for (off = 0; field->name; off += field->length, field++) {
                   1047:     if (!strncmp(field->name, PPTP_RESV_PREF, strlen(PPTP_RESV_PREF))
                   1048:        && memcmp((u_char *) msg + off, zeros, field->length)) {
                   1049:       Log(LG_PHYS2, ("pptp%d: non-zero reserved field %s in %s",
                   1050:        c->id, field->name, mi->name));
                   1051: #if 0
                   1052:       PptpCtrlKillCtrl(c);
                   1053:       return;
                   1054: #endif
                   1055:     }
                   1056:   }
                   1057: 
                   1058:   /* Find channel this message corresponds to (if any) */
                   1059:   if (mi->match.inField && !(ch = PptpCtrlFindChan(c, type, msg, TRUE)))
                   1060:     return;
                   1061: 
                   1062:   /* See if this message qualifies as the reply to a previously sent message */
                   1063:   for (pp = &c->reps; *pp; pp = &(*pp)->next) {
                   1064:     if ((*pp)->request->reqrep.reply == type && (*pp)->chan == ch)
                   1065:       break;
                   1066:   }
                   1067: 
                   1068:   /* If not, and this message is *always* a reply, ignore it */
                   1069:   if (*pp == NULL && mi->isReply) {
                   1070:     Log(LG_PHYS2, ("pptp%d: rec'd spurious %s", c->id, mi->name));
                   1071:     return;
                   1072:   }
                   1073: 
                   1074:   /* If so, cancel the matching pending reply */
                   1075:   if (*pp) {
                   1076:     PptpPendRep        const prep = *pp;
                   1077: 
                   1078:     TimerStop(&prep->timer);
                   1079:     *pp = prep->next;
                   1080:     Freee(prep);
                   1081:   }
                   1082: 
                   1083:   /* Check for invalid message and call or control state combinations */
                   1084:   if (!ch && ((1 << c->state) & mi->states) == 0) {
                   1085:     Log(LG_PHYS2, ("pptp%d: got %s in state %s",
                   1086:       c->id, gPptpMsgInfo[type].name, gPptpCtrlStates[c->state]));
                   1087:     PptpCtrlKillCtrl(c);
                   1088:     return;
                   1089:   }
                   1090:   if (ch && ((1 << ch->state) & mi->states) == 0) {
                   1091:     Log(LG_PHYS2, ("pptp%d-%d: got %s in state %s",
                   1092:       c->id, ch->id, gPptpMsgInfo[type].name, gPptpChanStates[ch->state]));
                   1093:     PptpCtrlKillCtrl(c);
                   1094:     return;
                   1095:   }
                   1096: 
                   1097:   /* Things look OK; process message */
                   1098:   (*mi->handler)(ch ? (void *) ch : (void *) c, msg);
                   1099: }
                   1100: 
                   1101: /*
                   1102:  * PptpCtrlWriteMsg()
                   1103:  *
                   1104:  * Write out a control message. If we should expect a reply,
                   1105:  * register a matching pending reply for it.
                   1106:  *
                   1107:  * NOTE: calling this function can result in the connection being shutdown!
                   1108:  */
                   1109: 
                   1110: static int
                   1111: PptpCtrlWriteMsg(PptpCtrl c, int type, void *msg)
                   1112: {
                   1113:   PptpMsgInfo          const mi = &gPptpMsgInfo[type];
                   1114:   union {
                   1115:       u_char                   buf[PPTP_CTRL_MAX_FRAME];
                   1116:       struct pptpMsgHead       hdr;
                   1117:   }                    frame;
                   1118:   PptpMsgHead          const hdr = &frame.hdr;
                   1119:   u_char               *const payload = (u_char *) (hdr + 1);
                   1120:   const int            totlen = sizeof(*hdr) + gPptpMsgInfo[type].length;
                   1121:   int                  nwrote;
                   1122: 
                   1123:   /* Build message */
                   1124:   assert(PPTP_VALID_CTRL_TYPE(type));
                   1125:   memset(hdr, 0, sizeof(*hdr));
                   1126:   hdr->length = totlen;
                   1127:   hdr->msgType = PPTP_CTRL_MSG_TYPE;
                   1128:   hdr->magic = PPTP_MAGIC;
                   1129:   hdr->type = type;
                   1130:   memcpy(payload, msg, gPptpMsgInfo[type].length);
                   1131:   Log(LG_PHYS3, ("pptp%d: send %s msg", c->id, gPptpMsgInfo[hdr->type].name));
                   1132:   PptpCtrlDump(LG_PHYS3, 0, hdr);
                   1133:   PptpCtrlDump(LG_PHYS3, type, msg);
                   1134: 
                   1135:   /* Byte swap it */
                   1136:   PptpCtrlSwap(0, hdr);
                   1137:   PptpCtrlSwap(type, payload);
                   1138: 
                   1139:   /* Send it; if TCP buffer is full, we abort the connection */
                   1140:   if ((nwrote = write(c->csock, frame.buf, totlen)) != totlen) {
                   1141:     if (nwrote < 0)
                   1142:       Log(LG_PHYS2, ("pptp%d: %s: %s", c->id, "write", strerror(errno)));
                   1143:     else
                   1144:       Log(LG_PHYS2, ("pptp%d: only wrote %d/%d", c->id, nwrote, totlen));
                   1145:     PptpCtrlKillCtrl(c);
                   1146:     return -1;
                   1147:   }
                   1148:   LogDumpBuf(LG_FRAME, frame.buf, totlen, "pptp%d: wrote %d bytes ctrl data", c->id, totlen);
                   1149: 
                   1150:   /* If we expect a reply to this message, start expecting it now */
                   1151:   if (PPTP_VALID_CTRL_TYPE(mi->reqrep.reply)) {
                   1152:     PptpPendRep        const prep = Malloc(MB_PPTP, sizeof(*prep));
                   1153: 
                   1154:     prep->ctrl = c;
                   1155:     prep->chan = PptpCtrlFindChan(c, type, msg, FALSE);
                   1156:     prep->request = mi;
                   1157:     TimerInit(&prep->timer, "PptpReply",
                   1158:       mi->reqrep.timeout * SECONDS, PptpCtrlReplyTimeout, prep);
                   1159:     TimerStart(&prep->timer);
                   1160:     prep->next = c->reps;
                   1161:     c->reps = prep;
                   1162:   }
                   1163: 
                   1164:   /* Done */
                   1165:   return 0;
                   1166: }
                   1167: 
                   1168: /*************************************************************************
                   1169:                CONTROL AND CHANNEL ALLOCATION FUNCTIONS
                   1170: *************************************************************************/
                   1171: 
                   1172: /*
                   1173:  * PptpCtrlGetCtrl()
                   1174:  *
                   1175:  * Get existing or create new control bock for given peer and return it.
                   1176:  * Returns NULL if there was some problem, and puts an error message
                   1177:  * into the buffer.
                   1178:  *
                   1179:  * If "orig" is TRUE, and we currently have no TCP connection to the peer,
                   1180:  * then initiate one. Otherwise, make sure we don't already have one,
                   1181:  * because that would mean we'd have two connections to the same peer.
                   1182:  */
                   1183: 
                   1184: static PptpCtrl
                   1185: PptpCtrlGetCtrl(int orig, struct u_addr *self_addr,
                   1186:        struct u_addr *peer_addr, in_port_t peer_port, char *buf, size_t bsiz)
                   1187: {
                   1188:     PptpCtrl                   c;
                   1189:     int                                k;
                   1190:     struct sockaddr_storage    peer;
                   1191:     char                       buf1[48];
                   1192: 
                   1193:     /* For incoming any control is new! */
                   1194:     if (orig) {
                   1195:        /* See if we're already have a control block matching this address and port */
                   1196:          for (k = 0; k < gNumPptpCtrl; k++) {
                   1197:                PptpCtrl        const c = gPptpCtrl[k];
                   1198:        
                   1199:                if (c != NULL
                   1200:                    && (c->active_sessions < gPPTPtunlimit)
                   1201:                    && (u_addrcompare(&c->peer_addr, peer_addr) == 0)
                   1202:                    && (c->peer_port == peer_port || c->orig != orig)
                   1203:                    && (u_addrempty(self_addr) || 
                   1204:                      (u_addrcompare(&c->self_addr, self_addr) == 0))) {
                   1205:                        return(c);
                   1206:                }
                   1207:          }
                   1208:     }
                   1209: 
                   1210:     /* Find/create a free one */
                   1211:     for (k = 0; k < gNumPptpCtrl && gPptpCtrl[k] != NULL; k++);
                   1212:     if (k == gNumPptpCtrl)
                   1213:        LengthenArray(&gPptpCtrl, sizeof(*gPptpCtrl), &gNumPptpCtrl, MB_PPTP);
                   1214:     c = Malloc(MB_PPTP, sizeof(*c));
                   1215:     gPptpCtrl[k] = c;
                   1216: 
                   1217:   /* Initialize it */
                   1218:   c->id = k;
                   1219:   c->orig = orig;
                   1220:   c->csock = -1;
                   1221:   c->self_addr = *self_addr;
                   1222:   c->peer_addr = *peer_addr;
                   1223:   c->peer_port = peer_port;
                   1224:   PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_IDLE);
                   1225: 
                   1226:   /* If not doing the connecting, return here */
                   1227:   if (!orig)
                   1228:     return(c);
                   1229: 
                   1230:   /* Connect to peer */
                   1231:   if ((c->csock = GetInetSocket(SOCK_STREAM, self_addr, 0, FALSE, buf, bsiz)) < 0) {
                   1232:     gPptpCtrl[k] = NULL;
                   1233:     PptpCtrlFreeCtrl(c);
                   1234:     return(NULL);
                   1235:   }
                   1236:   u_addrtosockaddr(&c->peer_addr, c->peer_port, &peer);
                   1237:   if (connect(c->csock, (struct sockaddr *) &peer, peer.ss_len) < 0
                   1238:       && errno != EINPROGRESS) {
                   1239:     (void) close(c->csock);
                   1240:     c->csock = -1;
                   1241:     snprintf(buf, bsiz, "pptp: connect to %s %u failed: %s",
                   1242:       u_addrtoa(&c->peer_addr,buf1,sizeof(buf1)), c->peer_port, strerror(errno));
                   1243:     gPptpCtrl[k] = NULL;
                   1244:     PptpCtrlFreeCtrl(c);
                   1245:     return(NULL);
                   1246:   }
                   1247: 
                   1248:   /* Wait for it to go through */
                   1249:   EventRegister(&c->connEvent, EVENT_WRITE, c->csock,
                   1250:     0, PptpCtrlConnEvent, c);
                   1251:   Log(LG_PHYS2, ("pptp%d: connecting to %s %u",
                   1252:     c->id, u_addrtoa(&c->peer_addr,buf1,sizeof(buf1)), c->peer_port));
                   1253:   return(c);
                   1254: }
                   1255: 
                   1256: /*
                   1257:  * PptpCtrlGetChan()
                   1258:  *
                   1259:  * Find a free data channel and attach it to the control channel.
                   1260:  */
                   1261: 
                   1262: static PptpChan
                   1263: PptpCtrlGetChan(PptpCtrl c, int chanState, int orig, int incoming,
                   1264:        int bearType, int frameType, int minBps, int maxBps,
                   1265:        const char *callingNum, const char *calledNum, const char *subAddress)
                   1266: {
                   1267:     PptpChan   ch;
                   1268:     int                k;
                   1269: 
                   1270:     TimerStop(&c->killTimer);
                   1271: 
                   1272:     /* Get a free data channel */
                   1273:     for (k = 0; k < c->numChannels && c->channels[k] != NULL; k++);
                   1274:     if (k == c->numChannels)
                   1275:        LengthenArray(&c->channels, sizeof(*c->channels), &c->numChannels, MB_PPTP);
                   1276:     ch = Malloc(MB_PPTP, sizeof(*ch));
                   1277:     c->channels[k] = ch;
                   1278:     c->active_sessions++;
                   1279:     ch->id = k;
                   1280:     while (gCallIds[gLastCallId])
                   1281:        gLastCallId++;
                   1282:     gCallIds[gLastCallId] = 1;
                   1283:     ch->cid = gLastCallId;
                   1284:     ch->ctrl = c;
                   1285:     ch->orig = orig;
                   1286:     ch->incoming = incoming;
                   1287:     ch->minBps = minBps;
                   1288:     ch->maxBps = maxBps;
                   1289:     ch->bearType = bearType;
                   1290:     ch->frameType = frameType;
                   1291:     strlcpy(ch->calledNum, calledNum, sizeof(ch->calledNum));
                   1292:     strlcpy(ch->callingNum, callingNum, sizeof(ch->callingNum));
                   1293:     strlcpy(ch->subAddress, subAddress, sizeof(ch->subAddress));
                   1294:     PptpCtrlNewChanState(ch, chanState);
                   1295:     return(ch);
                   1296: }
                   1297: 
                   1298: /*
                   1299:  * PptpCtrlDialResult()
                   1300:  *
                   1301:  * Link layer calls this to let us know whether an outgoing call
                   1302:  * has been successfully completed or has failed.
                   1303:  */
                   1304: 
                   1305: static void
                   1306: PptpCtrlDialResult(void *cookie, int result, int error, int cause, int speed)
                   1307: {
                   1308:   PptpChan                     const ch = (PptpChan) cookie;
                   1309:   PptpCtrl                     const c = ch->ctrl;
                   1310:   struct pptpOutCallReply      rep;
                   1311: 
                   1312:   memset(&rep, 0, sizeof(rep));
                   1313:   rep.cid = ch->cid;
                   1314:   rep.peerCid = ch->peerCid;
                   1315:   rep.result = result;
                   1316:   if (rep.result == PPTP_OCR_RESL_ERR)
                   1317:     rep.err = error;
                   1318:   rep.cause = cause;
                   1319:   rep.speed = speed;
                   1320:   rep.ppd = PPTP_PPD;          /* XXX should get this value from link layer */
                   1321:   rep.recvWin = PPTP_RECV_WIN; /* XXX */
                   1322:   rep.channel = PHYS_CHAN(ch);
                   1323:   if (rep.result == PPTP_OCR_RESL_OK)
                   1324:     PptpCtrlNewChanState(ch, PPTP_CHAN_ST_ESTABLISHED);
                   1325:   else
                   1326:     PptpCtrlKillChan(ch, "local outgoing call failed");
                   1327:   PptpCtrlWriteMsg(c, PPTP_OutCallReply, &rep);
                   1328: }
                   1329: 
                   1330: /*
                   1331:  * PptpCtrlConected()
                   1332:  *
                   1333:  * Link layer calls this to let us know whether an incoming call
                   1334:  * has been successfully connected.
                   1335:  */
                   1336: 
                   1337: static void
                   1338: PptpCtrlConected(void *cookie, int speed)
                   1339: {
                   1340:   PptpChan                     const ch = (PptpChan) cookie;
                   1341:   PptpCtrl                     const c = ch->ctrl;
                   1342:   struct pptpInCallConn con;
                   1343:   
                   1344:   /* Send back connected message */
                   1345:   memset(&con, 0, sizeof(con));
                   1346:   con.peerCid = ch->peerCid;
                   1347:   con.speed = speed;
                   1348:   con.recvWin = PPTP_RECV_WIN;         /* XXX */
                   1349:   con.ppd = PPTP_PPD;                  /* XXX */
                   1350:   con.frameType = ch->frameType;
                   1351:   PptpCtrlWriteMsg(c, PPTP_InCallConn, &con);
                   1352: }
                   1353: 
                   1354: static void
                   1355: PptpCtrlSetLinkInfo(void *cookie, u_int32_t sa, u_int32_t ra)
                   1356: {
                   1357:   PptpChan                     const ch = (PptpChan) cookie;
                   1358:   PptpCtrl                     const c = ch->ctrl;
                   1359:   struct pptpSetLinkInfo       rep;
                   1360: 
                   1361:   /* Only PNS should send SLI */
                   1362:   if (!PPTP_CHAN_IS_PNS(ch))
                   1363:        return;
                   1364: 
                   1365:   memset(&rep, 0, sizeof(rep));
                   1366:   rep.cid = ch->peerCid;
                   1367:   rep.sendAccm = sa;
                   1368:   rep.recvAccm = ra;
                   1369:   PptpCtrlWriteMsg(c, PPTP_SetLinkInfo, &rep);
                   1370: }
                   1371: 
                   1372: /*************************************************************************
                   1373:                    SHUTDOWN FUNCTIONS
                   1374: *************************************************************************/
                   1375: 
                   1376: /*
                   1377:  * PptpCtrlCloseCtrl()
                   1378:  */
                   1379: 
                   1380: static void
                   1381: PptpCtrlCloseCtrl(PptpCtrl c)
                   1382: {
                   1383:   char buf[48];
                   1384: 
                   1385:   Log(LG_PHYS2, ("pptp%d: closing connection with %s %u",
                   1386:     c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
                   1387:   switch (c->state) {
                   1388:     case PPTP_CTRL_ST_IDLE:
                   1389:     case PPTP_CTRL_ST_WAIT_STOP_REPLY:
                   1390:     case PPTP_CTRL_ST_WAIT_CTL_REPLY:
                   1391:       PptpCtrlKillCtrl(c);
                   1392:       return;
                   1393:     case PPTP_CTRL_ST_ESTABLISHED:
                   1394:       {
                   1395:        struct pptpStopCtrlConnRequest  req;
                   1396: 
                   1397:        memset(&req, 0, sizeof(req));
                   1398:        req.reason = PPTP_SCCR_REAS_LOCAL;
                   1399:        PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_WAIT_STOP_REPLY);
                   1400:        PptpCtrlWriteMsg(c, PPTP_StopCtrlConnRequest, &req);
                   1401:        return;
                   1402:       }
                   1403:       break;
                   1404:     case PPTP_CTRL_ST_DYING:
                   1405:       break;
                   1406:     default:
                   1407:       assert(0);
                   1408:   }
                   1409: }
                   1410: 
                   1411: /*
                   1412:  * PptpCtrlKillCtrl()
                   1413:  */
                   1414: 
                   1415: static void
                   1416: PptpCtrlKillCtrl(PptpCtrl c)
                   1417: {
                   1418:   int          k;
                   1419:   PptpPendRep  prep, next;
                   1420:   char         buf[48];
                   1421: 
                   1422:   /* Don't recurse */
                   1423:   assert(c);
                   1424:   if (c->state == PPTP_CTRL_ST_DYING)
                   1425:     return;
                   1426:   PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_DYING);
                   1427: 
                   1428:   /* Do ungraceful shutdown */
                   1429:   Log(LG_PHYS2, ("pptp%d: killing connection with %s %u",
                   1430:     c->id, u_addrtoa(&c->peer_addr,buf,sizeof(buf)), c->peer_port));
                   1431:   for (k = 0; k < c->numChannels; k++) {
                   1432:     PptpChan   const ch = c->channels[k];
                   1433: 
                   1434:     if (ch != NULL)
                   1435:       PptpCtrlKillChan(ch, "control channel shutdown");
                   1436:   }
                   1437:   gPptpCtrl[c->id] = NULL;
                   1438:   if (c->csock >= 0) {
                   1439:     close(c->csock);
                   1440:     c->csock = -1;
                   1441:   }
                   1442:   EventUnRegister(&c->connEvent);
                   1443:   EventUnRegister(&c->ctrlEvent);
                   1444:   TimerStop(&c->idleTimer);
                   1445:   TimerStop(&c->killTimer);
                   1446:   for (prep = c->reps; prep; prep = next) {
                   1447:     next = prep->next;
                   1448:     TimerStop(&prep->timer);
                   1449:     Freee(prep);
                   1450:   }
                   1451:   c->reps = NULL;
                   1452:   
                   1453:   /* Delay Free call to avoid "Modify after free" case */
                   1454:   TimerInit(&c->killTimer, "PptpKill", 0, (void (*)(void *))PptpCtrlFreeCtrl, c);
                   1455:   TimerStart(&c->killTimer);
                   1456: }
                   1457: 
                   1458: static void
                   1459: PptpCtrlFreeCtrl(PptpCtrl c)
                   1460: {
                   1461:     Freee(c->channels);
                   1462:     memset(c, 0, sizeof(*c));
                   1463:     Freee(c);
                   1464: }
                   1465: 
                   1466: /*
                   1467:  * PptpCtrlCloseChan()
                   1468:  *
                   1469:  * Gracefully clear a call.
                   1470:  */
                   1471: 
                   1472: static void
                   1473: PptpCtrlCloseChan(PptpChan ch, int result, int error, int cause)
                   1474: {
                   1475:   PptpCtrl     const c = ch->ctrl;
                   1476: 
                   1477:   /* Check call state */
                   1478:   switch (ch->state) {
                   1479:     case PPTP_CHAN_ST_ESTABLISHED:
                   1480:       if (PPTP_CHAN_IS_PNS(ch))
                   1481:        goto pnsClear;
                   1482:       else
                   1483:        goto pacClear;
                   1484:       break;
                   1485:     case PPTP_CHAN_ST_WAIT_ANSWER:
                   1486:       {
                   1487:        struct pptpOutCallReply reply;
                   1488: 
                   1489:        memset(&reply, 0, sizeof(reply));
                   1490:        reply.peerCid = ch->peerCid;
                   1491:        reply.result = PPTP_OCR_RESL_ADMIN;
                   1492:        PptpCtrlWriteMsg(c, PPTP_OutCallReply, &reply);
                   1493:        PptpCtrlKillChan(ch, "link layer shutdown");    /* XXX errmsg */
                   1494:        return;
                   1495:       }
                   1496:       break;
                   1497:     case PPTP_CHAN_ST_WAIT_IN_REPLY:           /* we are the PAC */
                   1498: pacClear:
                   1499:       {
                   1500:        struct pptpCallDiscNotify       disc;
                   1501: 
                   1502:        Log(LG_PHYS2, ("pptp%d-%d: clearing call", c->id, ch->id));
                   1503:        memset(&disc, 0, sizeof(disc));
                   1504:        disc.cid = ch->cid;
                   1505:        disc.result = result;
                   1506:        if (disc.result == PPTP_CDN_RESL_ERR)
                   1507:          disc.err = error;
                   1508:        disc.cause = cause;
                   1509:        /* XXX stats? */
                   1510:        PptpCtrlWriteMsg(c, PPTP_CallDiscNotify, &disc);
                   1511:        PptpCtrlKillChan(ch, "link layer shutdown");    /* XXX errmsg */
                   1512:       }
                   1513:       break;
                   1514:     case PPTP_CHAN_ST_WAIT_OUT_REPLY:          /* we are the PNS */
                   1515:     case PPTP_CHAN_ST_WAIT_CONNECT:            /* we are the PNS */
                   1516: pnsClear:
                   1517:       {
                   1518:        struct pptpCallClearRequest     req;
                   1519: 
                   1520:        Log(LG_PHYS2, ("pptp%d-%d: clearing call", c->id, ch->id));
                   1521:        memset(&req, 0, sizeof(req));
                   1522:        req.cid = ch->cid;
                   1523:        PptpCtrlWriteMsg(c, PPTP_CallClearRequest, &req);
                   1524:        PptpCtrlNewChanState(ch, PPTP_CHAN_ST_WAIT_DISCONNECT);
                   1525:       }
                   1526:       break;
                   1527:     case PPTP_CHAN_ST_WAIT_DISCONNECT:         /* call was already cleared */
                   1528:       return;
                   1529:     case PPTP_CHAN_ST_WAIT_CTRL:
                   1530:       PptpCtrlKillChan(ch, "link layer shutdown");
                   1531:       return;
                   1532:     case PPTP_CHAN_ST_DYING:
                   1533:       break;
                   1534:     default:
                   1535:       assert(0);
                   1536:   }
                   1537: }
                   1538: 
                   1539: /*
                   1540:  * PptpCtrlKillChan()
                   1541:  */
                   1542: 
                   1543: static void
                   1544: PptpCtrlKillChan(PptpChan ch, const char *errmsg)
                   1545: {
                   1546:   PptpCtrl     const c = ch->ctrl;
                   1547:   PptpPendRep  *pp;
                   1548: 
                   1549:   assert(ch);
                   1550:   /* Don't recurse */
                   1551:   if (ch->state == PPTP_CHAN_ST_DYING)
                   1552:     return;
                   1553: 
                   1554:   /* If link layer needs notification, tell it */
                   1555:   Log(LG_PHYS2, ("pptp%d-%d: killing channel", c->id, ch->id));
                   1556:   switch (ch->state) {
                   1557:     case PPTP_CHAN_ST_WAIT_IN_REPLY:
                   1558:     case PPTP_CHAN_ST_WAIT_OUT_REPLY:
                   1559:     case PPTP_CHAN_ST_WAIT_CONNECT:
                   1560:     case PPTP_CHAN_ST_ESTABLISHED:
                   1561:     case PPTP_CHAN_ST_WAIT_CTRL:
                   1562:     case PPTP_CHAN_ST_WAIT_DISCONNECT:
                   1563:        if (ch->linfo.cookie != NULL)
                   1564:            (*ch->linfo.result)(ch->linfo.cookie, errmsg, 0);
                   1565:       break;
                   1566:     case PPTP_CHAN_ST_WAIT_ANSWER:
                   1567:        if (ch->linfo.cookie != NULL)
                   1568:            (*ch->linfo.cancel)(ch->linfo.cookie);
                   1569:       break;
                   1570:     case PPTP_CHAN_ST_DYING:                           /* should never happen */
                   1571:     default:
                   1572:       assert(0);
                   1573:   }
                   1574:   PptpCtrlNewChanState(ch, PPTP_CHAN_ST_DYING);
                   1575: 
                   1576:   /* Nuke any pending replies pertaining to this channel */
                   1577:   for (pp = &c->reps; *pp; ) {
                   1578:     PptpPendRep        const prep = *pp;
                   1579: 
                   1580:     if (prep->chan == ch) {
                   1581:       TimerStop(&prep->timer);
                   1582:       *pp = prep->next;
                   1583:       Freee(prep);
                   1584:     } else
                   1585:       pp = &prep->next;
                   1586:   }
                   1587: 
                   1588:     /* Free channel */
                   1589:     gCallIds[ch->cid] = 0;
                   1590:     c->channels[ch->id] = NULL;
                   1591:     c->active_sessions--;
                   1592:     /* Delay Free call to avoid "Modify after free" case */
                   1593:     TimerInit(&ch->killTimer, "PptpKillCh", 0, (void (*)(void *))PptpCtrlFreeChan, ch);
                   1594:     TimerStart(&ch->killTimer);
                   1595: 
                   1596:     /* When the last channel is closed, close the control channel too. */
                   1597:     if (c->active_sessions == 0 && c->state <= PPTP_CTRL_ST_ESTABLISHED) {
                   1598:        /* Delay control close as it may be be needed soon */
                   1599:        TimerInit(&c->killTimer, "PptpUnused", gPPTPto * SECONDS,
                   1600:            (void (*)(void *))PptpCtrlCloseCtrl, c);
                   1601:        TimerStart(&c->killTimer);
                   1602:     }
                   1603: }
                   1604: 
                   1605: static void
                   1606: PptpCtrlFreeChan(PptpChan ch)
                   1607: {
                   1608:     memset(ch, 0, sizeof(*ch));
                   1609:     Freee(ch);
                   1610: }
                   1611: 
                   1612: /*************************************************************************
                   1613:                    TIMER RELATED FUNCTIONS
                   1614: *************************************************************************/
                   1615: 
                   1616: /*
                   1617:  * PptpCtrlReplyTimeout()
                   1618:  */
                   1619: 
                   1620: static void
                   1621: PptpCtrlReplyTimeout(void *arg)
                   1622: {
                   1623:   PptpPendRep  const prep = (PptpPendRep) arg;
                   1624:   PptpPendRep  *pp;
                   1625:   PptpChan     const ch = prep->chan;
                   1626:   PptpCtrl     const c = prep->ctrl;
                   1627: 
                   1628:   /* Log it */
                   1629:   if (ch) {
                   1630:     Log(LG_PHYS2, ("pptp%d-%d: no reply to %s after %d sec",
                   1631:       c->id, ch->id, prep->request->name, prep->request->reqrep.timeout));
                   1632:   } else {
                   1633:     Log(LG_PHYS2, ("pptp%d: no reply to %s after %d sec",
                   1634:       c->id, prep->request->name, prep->request->reqrep.timeout));
                   1635:   }
                   1636: 
                   1637:   /* Unlink pending reply */
                   1638:   for (pp = &c->reps; *pp != prep; pp = &(*pp)->next);
                   1639:   assert(*pp);
                   1640:   *pp = prep->next;
                   1641: 
                   1642:   /* Either close this channel or kill entire control connection */
                   1643:   if (prep->request->reqrep.killCtrl)
                   1644:     PptpCtrlKillCtrl(c);
                   1645:   else
                   1646:     PptpCtrlCloseChan(ch, PPTP_CDN_RESL_ERR, PPTP_ERROR_PAC_ERROR, 0);
                   1647: 
                   1648:   /* Done */
                   1649:   Freee(prep);
                   1650: }
                   1651: 
                   1652: /*
                   1653:  * PptpCtrlIdleTimeout()
                   1654:  *
                   1655:  * We've heard PPTP_IDLE_TIMEOUT seconds of silence from the peer.
                   1656:  * Send an echo request to make sure it's alive.
                   1657:  */
                   1658: 
                   1659: static void
                   1660: PptpCtrlIdleTimeout(void *arg)
                   1661: {
                   1662:   PptpCtrl                     const c = (PptpCtrl) arg;
                   1663:   struct pptpEchoRequest       msg;
                   1664: 
                   1665:   /* Send echo request */
                   1666:   memset(&msg, 0, sizeof(msg));
                   1667:   msg.id = ++c->echoId;
                   1668:   PptpCtrlWriteMsg(c, PPTP_EchoRequest, &msg);
                   1669: }
                   1670: 
                   1671: /*
                   1672:  * PptpCtrlResetIdleTimer()
                   1673:  *
                   1674:  * Reset the idle timer back up to PPTP_IDLE_TIMEOUT seconds.
                   1675:  */
                   1676: 
                   1677: static void
                   1678: PptpCtrlResetIdleTimer(PptpCtrl c)
                   1679: {
                   1680:   TimerStop(&c->idleTimer);
                   1681:   TimerInit(&c->idleTimer, "PptpIdle",
                   1682:     PPTP_IDLE_TIMEOUT * SECONDS, PptpCtrlIdleTimeout, c);
                   1683:   TimerStart(&c->idleTimer);
                   1684: }
                   1685: 
                   1686: /*************************************************************************
                   1687:                    CHANNEL MAINTENANCE FUNCTIONS
                   1688: *************************************************************************/
                   1689: 
                   1690: /*
                   1691:  * PptpCtrlCheckConn()
                   1692:  *
                   1693:  * Check whether we have any pending connection requests, and whether
                   1694:  * we can send them yet, or what.
                   1695:  */
                   1696: 
                   1697: static void
                   1698: PptpCtrlCheckConn(PptpCtrl c)
                   1699: {
                   1700:   int  k;
                   1701: 
                   1702:   switch (c->state) {
                   1703:     case PPTP_CTRL_ST_IDLE:
                   1704:     case PPTP_CTRL_ST_WAIT_CTL_REPLY:
                   1705:     case PPTP_CTRL_ST_WAIT_STOP_REPLY:
                   1706:       break;
                   1707:     case PPTP_CTRL_ST_ESTABLISHED:
                   1708:       for (k = 0; k < c->numChannels; k++) {
                   1709:        PptpChan        const ch = c->channels[k];
                   1710: 
                   1711:        if (ch == NULL || ch->state != PPTP_CHAN_ST_WAIT_CTRL)
                   1712:          continue;
                   1713:        if (ch->incoming) {
                   1714:          struct pptpInCallRequest      req;
                   1715: 
                   1716:          memset(&req, 0, sizeof(req));
                   1717:          req.cid = ch->cid;
                   1718:          req.serno = req.cid;
                   1719:          req.bearType = PPTP_BEARCAP_DIGITAL;
                   1720:          req.channel = PHYS_CHAN(ch);
                   1721:          req.dialingLen = strlen(ch->callingNum);
                   1722:          strncpy(req.dialing, ch->callingNum, sizeof(req.dialing));
                   1723:          req.dialedLen = strlen(ch->calledNum);
                   1724:          strncpy(req.dialed, ch->calledNum, sizeof(req.dialed));
                   1725:          strncpy(req.subaddr, ch->subAddress, sizeof(req.subaddr));
                   1726:          PptpCtrlNewChanState(ch, PPTP_CHAN_ST_WAIT_IN_REPLY);
                   1727:          PptpCtrlWriteMsg(c, PPTP_InCallRequest, &req);
                   1728:        } else {
                   1729:          struct pptpOutCallRequest     req;
                   1730: 
                   1731:          memset(&req, 0, sizeof(req));
                   1732:          req.cid = ch->cid;
                   1733:          req.serno = req.cid;
                   1734:          req.minBps = ch->minBps;
                   1735:          req.maxBps = ch->maxBps;
                   1736:          req.bearType = ch->bearType;
                   1737:          req.frameType = ch->frameType;
                   1738:          req.recvWin = PPTP_RECV_WIN;          /* XXX */
                   1739:          req.ppd = PPTP_PPD;                   /* XXX */
                   1740:          req.numLen = strlen(ch->calledNum);
                   1741:          strncpy(req.phone, ch->calledNum, sizeof(req.phone));
                   1742:          strncpy(req.subaddr, ch->subAddress, sizeof(req.subaddr));
                   1743:          PptpCtrlNewChanState(ch, PPTP_CHAN_ST_WAIT_OUT_REPLY);
                   1744:          PptpCtrlWriteMsg(c, PPTP_OutCallRequest, &req);
                   1745:        }
                   1746:       }
                   1747:       break;
                   1748:     case PPTP_CTRL_ST_DYING:
                   1749:       break;
                   1750:     default:
                   1751:       assert(0);
                   1752:   }
                   1753: }
                   1754: 
                   1755: /*
                   1756:  * PptpCtrlFindChan()
                   1757:  *
                   1758:  * Find the channel identified by this message. Returns NULL if
                   1759:  * the message is not channel specific, or the channel was not found.
                   1760:  */
                   1761: 
                   1762: static PptpChan
                   1763: PptpCtrlFindChan(PptpCtrl c, int type, void *msg, int incoming)
                   1764: {
                   1765:   PptpMsgInfo  const mi = &gPptpMsgInfo[type];
                   1766:   const char   *fname = incoming ? mi->match.inField : mi->match.outField;
                   1767:   const int    how = incoming ? mi->match.findIn : mi->match.findOut;
                   1768:   u_int16_t    cid;
                   1769:   int          k;
                   1770:   u_int                off = 0;
                   1771: 
                   1772:   /* Get the identifying CID field */
                   1773:   if (!fname)
                   1774:     return(NULL);
                   1775:   (void) PptpCtrlFindField(type, fname, &off);         /* we know len == 2 */
                   1776:   cid = *((u_int16_t *)(void *)((u_char *) msg + off));
                   1777: 
                   1778:   /* Match the CID against our list of active channels */
                   1779:   for (k = 0; k < c->numChannels; k++) {
                   1780:     PptpChan   const ch = c->channels[k];
                   1781:     u_int16_t  tryCid = 0;
                   1782: 
                   1783:     if (ch == NULL)
                   1784:       continue;
                   1785:     switch (how) {
                   1786:       case PPTP_FIND_CHAN_MY_CID:
                   1787:        tryCid = ch->cid;
                   1788:        break;
                   1789:       case PPTP_FIND_CHAN_PEER_CID:
                   1790:        tryCid = ch->peerCid;
                   1791:        break;
                   1792:       case PPTP_FIND_CHAN_PNS_CID:
                   1793:        tryCid = PPTP_CHAN_IS_PNS(ch) ? ch->cid : ch->peerCid;
                   1794:        break;
                   1795:       case PPTP_FIND_CHAN_PAC_CID:
                   1796:        tryCid = !PPTP_CHAN_IS_PNS(ch) ? ch->cid : ch->peerCid;
                   1797:        break;
                   1798:       default:
                   1799:        assert(0);
                   1800:     }
                   1801:     if (cid == tryCid)
                   1802:       return(ch);
                   1803:   }
                   1804: 
                   1805:   /* Not found */
                   1806:   Log(LG_PHYS2, ("pptp%d: CID 0x%04x in %s not found", c->id, cid, mi->name));
                   1807:   return(NULL);
                   1808: }
                   1809: 
                   1810: /*************************************************************************
                   1811:                          MISC FUNCTIONS
                   1812: *************************************************************************/
                   1813: 
                   1814: /*
                   1815:  * PptpCtrlNewCtrlState()
                   1816:  */
                   1817: 
                   1818: static void
                   1819: PptpCtrlNewCtrlState(PptpCtrl c, int new)
                   1820: {
                   1821:   Log(LG_PHYS3, ("pptp%d: ctrl state %s --> %s",
                   1822:     c->id, gPptpCtrlStates[c->state], gPptpCtrlStates[new]));
                   1823:   assert(c->state != new);
                   1824:   c->state = new;
                   1825: }
                   1826: 
                   1827: /*
                   1828:  * PptpCtrlNewChanState()
                   1829:  */
                   1830: 
                   1831: static void
                   1832: PptpCtrlNewChanState(PptpChan ch, int new)
                   1833: {
                   1834:   PptpCtrl     const c = ch->ctrl;
                   1835: 
                   1836:   Log(LG_PHYS3, ("pptp%d-%d: chan state %s --> %s",
                   1837:     c->id, ch->id, gPptpChanStates[ch->state], gPptpChanStates[new]));
                   1838:   assert(ch->state != new);
                   1839:   ch->state = new;
                   1840: }
                   1841: 
                   1842: /*
                   1843:  * PptpCtrlSwap()
                   1844:  *
                   1845:  * Byteswap message between host order <--> network order. Note:
                   1846:  * this relies on the fact that ntohs == htons and ntohl == htonl.
                   1847:  */
                   1848: 
                   1849: static void
                   1850: PptpCtrlSwap(int type, void *buf)
                   1851: {
                   1852:   PptpField    field = gPptpMsgLayout[type];
                   1853:   int          off;
                   1854: 
                   1855:   for (off = 0; field->name; off += field->length, field++) {
                   1856:     void *const ptr = (u_char *)buf + off;
                   1857: 
                   1858:     switch (field->length) {
                   1859:       case 4:
                   1860:        {
                   1861:          u_int32_t value;
                   1862: 
                   1863:          memcpy(&value, ptr, field->length);
                   1864:          value = ntohl(value);
                   1865:          memcpy(ptr, &value, field->length);
                   1866:        }
                   1867:        break;
                   1868:       case 2:
                   1869:        {
                   1870:          u_int16_t value;
                   1871: 
                   1872:          memcpy(&value, ptr, field->length);
                   1873:          value = ntohs(value);
                   1874:          memcpy(ptr, &value, field->length);
                   1875:        }
                   1876:        break;
                   1877:     }
                   1878:   }
                   1879: }
                   1880: 
                   1881: /*
                   1882:  * PptpCtrlDump()
                   1883:  *
                   1884:  * Debugging display of a control message.
                   1885:  */
                   1886: 
                   1887: #define DUMP_DING      65
                   1888: #define DUMP_MAX_DEC   100
                   1889: #define DUMP_MAX_BUF   200
                   1890: 
                   1891: static void
                   1892: PptpCtrlDump(int level, int type, void *msg)
                   1893: {
                   1894:   PptpField    field = gPptpMsgLayout[type];
                   1895:   char         line[DUMP_MAX_BUF];
                   1896:   int          off;
                   1897: 
                   1898:   if (!(gLogOptions & level))
                   1899:     return;
                   1900:   for (*line = off = 0; field->name; off += field->length, field++) {
                   1901:     u_char     *data = (u_char *) msg + off;
                   1902:     char       buf[DUMP_MAX_BUF];
                   1903: 
                   1904:     if (!strncmp(field->name, PPTP_RESV_PREF, strlen(PPTP_RESV_PREF)))
                   1905:       continue;
                   1906:     snprintf(buf, sizeof(buf), " %s=", field->name);
                   1907:     switch (field->length) {
                   1908:       case 4:
                   1909:       {
                   1910:        u_int32_t value;
                   1911: 
                   1912:        memcpy(&value, data, field->length);
                   1913:        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                   1914:          (value <= DUMP_MAX_DEC) ? "%d" : "0x%x", value);
                   1915:        break;
                   1916:       }
                   1917:       case 2:
                   1918:       {
                   1919:        u_int16_t value;
                   1920: 
                   1921:        memcpy(&value, data, field->length);
                   1922:        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                   1923:          (value <= DUMP_MAX_DEC) ? "%d" : "0x%x", value);
                   1924:        break;
                   1925:       }
                   1926:       case 1:
                   1927:        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                   1928:          "%d", *((u_int8_t *) data));
                   1929:        break;
                   1930:       default:
                   1931:        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                   1932:          "\"%s\"", (char *) data);
                   1933:        break;
                   1934:     }
                   1935:     if (*line && strlen(line) + strlen(buf) > DUMP_DING) {
                   1936:       Log(level, (" %s", line));
                   1937:       *line = 0;
                   1938:     }
                   1939:     strlcpy(line + strlen(line), buf, sizeof(line) - strlen(line));
                   1940:   }
                   1941:   if (*line)
                   1942:     Log(level, (" %s", line));
                   1943: }
                   1944: 
                   1945: /*
                   1946:  * PptpCtrlFindField()
                   1947:  *
                   1948:  * Locate a field in a structure, returning length and offset (*offset).
                   1949:  * Die if field was not found.
                   1950:  */
                   1951: 
                   1952: static int
                   1953: PptpCtrlFindField(int type, const char *name, u_int *offp)
                   1954: {
                   1955:   PptpField    field = gPptpMsgLayout[type];
                   1956:   u_int                off;
                   1957: 
                   1958:   for (off = 0; field->name; off += field->length, field++) {
                   1959:     if (!strcmp(field->name, name)) {
                   1960:       *offp = off;
                   1961:       return(field->length);
                   1962:     }
                   1963:   }
                   1964:   assert(0);
                   1965:   return(0);
                   1966: }
                   1967: 
                   1968: /*
                   1969:  * PptpCtrlInitCinfo()
                   1970:  */
                   1971: 
                   1972: static void
                   1973: PptpCtrlInitCinfo(PptpChan ch, PptpCtrlInfo ci)
                   1974: {
                   1975:   PptpCtrl     const c = ch->ctrl;
                   1976: 
                   1977:   memset(ci, 0, sizeof(*ci));
                   1978:   ci->cookie = ch;
                   1979:   ci->peer_addr = c->peer_addr;
                   1980:   ci->peer_port = c->peer_port;
                   1981:   ci->close =(void (*)(void *, int, int, int)) PptpCtrlCloseChan;
                   1982:   ci->answer = (void (*)(void *, int, int, int, int)) PptpCtrlDialResult;
                   1983:   ci->connected = PptpCtrlConected;
                   1984:   ci->setLinkInfo = PptpCtrlSetLinkInfo;
                   1985: }
                   1986: 
                   1987: /*************************************************************************
                   1988:                      CONTROL MESSAGE FUNCTIONS
                   1989: *************************************************************************/
                   1990: 
                   1991: /*
                   1992:  * PptpStartCtrlConnRequest()
                   1993:  */
                   1994: 
                   1995: static void
                   1996: PptpStartCtrlConnRequest(PptpCtrl c, struct pptpStartCtrlConnRequest *req)
                   1997: {
                   1998:     struct pptpStartCtrlConnReply      reply;
                   1999: 
                   2000:     /* Initialize reply */
                   2001:     memset(&reply, 0, sizeof(reply));
                   2002:     reply.vers = PPTP_PROTO_VERS;
                   2003:     reply.frameCap = PPTP_FRAMECAP_ANY;
                   2004:     reply.bearCap = PPTP_BEARCAP_ANY;
                   2005:     reply.firmware = PPTP_FIRMWARE_REV;
                   2006:     reply.result = PPTP_SCCR_RESL_OK;
                   2007:     gethostname(c->self_name, sizeof(c->self_name) - 1);
                   2008:     c->self_name[sizeof(c->self_name) - 1] = '\0';
                   2009:     strlcpy(reply.host, c->self_name, sizeof(reply.host));
                   2010:     strncpy(reply.vendor, MPD_VENDOR, sizeof(reply.vendor));
                   2011: 
                   2012: #ifdef LOOK_LIKE_NT
                   2013:     reply.firmware = 0;
                   2014:     reply.maxChan = 2;
                   2015:     memset(reply.host, 0, sizeof(reply.host));
                   2016:     snprintf(reply.host, sizeof(reply.host), "local");
                   2017:     memset(reply.vendor, 0, sizeof(reply.vendor));
                   2018:     snprintf(reply.vendor, sizeof(reply.vendor), "NT");
                   2019: #endif
                   2020: 
                   2021:     /* Check protocol version */
                   2022:     if (req->vers != PPTP_PROTO_VERS) {
                   2023:        Log(LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, req->vers));
                   2024:        reply.result = PPTP_SCCR_RESL_VERS;
                   2025:        if (PptpCtrlWriteMsg(c, PPTP_StartCtrlConnReply, &reply) == -1)
                   2026:            return;
                   2027:        PptpCtrlKillCtrl(c);
                   2028:        return;
                   2029:     }
                   2030: 
                   2031:     strlcpy(c->peer_name, req->host, sizeof(c->peer_name));
                   2032: 
                   2033:     /* OK */
                   2034:     PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_ESTABLISHED);
                   2035:     PptpCtrlWriteMsg(c, PPTP_StartCtrlConnReply, &reply);
                   2036: }
                   2037: 
                   2038: /*
                   2039:  * PptpStartCtrlConnReply()
                   2040:  */
                   2041: 
                   2042: static void
                   2043: PptpStartCtrlConnReply(PptpCtrl c, struct pptpStartCtrlConnReply *rep)
                   2044: {
                   2045: 
                   2046:     /* Is peer happy? */
                   2047:     if (rep->result != 0 && rep->result != PPTP_SCCR_RESL_OK) {
                   2048:        Log(LG_PHYS2, ("pptp%d: my %s failed, result=%s err=%s",
                   2049:            c->id, gPptpMsgInfo[PPTP_StartCtrlConnRequest].name,
                   2050:            PPTP_SCCR_RESL_CODE(rep->result), PPTP_ERROR_CODE(rep->err)));
                   2051:        PptpCtrlKillCtrl(c);
                   2052:        return;
                   2053:     }
                   2054: 
                   2055:     /* Check peer's protocol version */
                   2056:     if (rep->vers != PPTP_PROTO_VERS) {
                   2057:        struct pptpStopCtrlConnRequest  req;
                   2058: 
                   2059:        Log(LG_PHYS2, ("pptp%d: incompatible protocol 0x%04x", c->id, rep->vers));
                   2060:        memset(&req, 0, sizeof(req));
                   2061:        req.reason = PPTP_SCCR_REAS_PROTO;
                   2062:        PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_WAIT_STOP_REPLY);
                   2063:        PptpCtrlWriteMsg(c, PPTP_StopCtrlConnRequest, &req);
                   2064:        return;
                   2065:     }
                   2066: 
                   2067:     strlcpy(c->peer_name, rep->host, sizeof(c->peer_name));
                   2068: 
                   2069:     /* OK */
                   2070:     PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_ESTABLISHED);
                   2071:     PptpCtrlCheckConn(c);
                   2072: }
                   2073: 
                   2074: /*
                   2075:  * PptpStopCtrlConnRequest()
                   2076:  */
                   2077: 
                   2078: static void
                   2079: PptpStopCtrlConnRequest(PptpCtrl c, struct pptpStopCtrlConnRequest *req)
                   2080: {
                   2081:   struct pptpStopCtrlConnReply rep;
                   2082: 
                   2083:   Log(LG_PHYS2, ("pptp%d: got %s: reason=%s",
                   2084:     c->id, gPptpMsgInfo[PPTP_StopCtrlConnRequest].name,
                   2085:     PPTP_SCCR_REAS_CODE(req->reason)));
                   2086:   memset(&rep, 0, sizeof(rep));
                   2087:   rep.result = PPTP_SCCR_RESL_OK;
                   2088:   PptpCtrlNewCtrlState(c, PPTP_CTRL_ST_IDLE);
                   2089:   if (PptpCtrlWriteMsg(c, PPTP_StopCtrlConnReply, &rep) == -1)
                   2090:     return;
                   2091:   PptpCtrlKillCtrl(c);
                   2092: }
                   2093: 
                   2094: /*
                   2095:  * PptpStopCtrlConnReply()
                   2096:  */
                   2097: 
                   2098: static void
                   2099: PptpStopCtrlConnReply(PptpCtrl c, struct pptpStopCtrlConnReply *rep)
                   2100: {
                   2101:   PptpCtrlKillCtrl(c);
                   2102: }
                   2103: 
                   2104: /*
                   2105:  * PptpEchoRequest()
                   2106:  */
                   2107: 
                   2108: static void
                   2109: PptpEchoRequest(PptpCtrl c, struct pptpEchoRequest *req)
                   2110: {
                   2111:   struct pptpEchoReply reply;
                   2112: 
                   2113:   memset(&reply, 0, sizeof(reply));
                   2114:   reply.id = req->id;
                   2115:   reply.result = PPTP_ECHO_RESL_OK;
                   2116:   PptpCtrlWriteMsg(c, PPTP_EchoReply, &reply);
                   2117: }
                   2118: 
                   2119: /*
                   2120:  * PptpEchoReply()
                   2121:  */
                   2122: 
                   2123: static void
                   2124: PptpEchoReply(PptpCtrl c, struct pptpEchoReply *rep)
                   2125: {
                   2126:   if (rep->result != PPTP_ECHO_RESL_OK) {
                   2127:     Log(LG_PHYS2, ("pptp%d: echo reply failed: res=%s err=%s",
                   2128:       c->id, PPTP_ECHO_RESL_CODE(rep->result), PPTP_ERROR_CODE(rep->err)));
                   2129:     PptpCtrlKillCtrl(c);
                   2130:   } else if (rep->id != c->echoId) {
                   2131:     Log(LG_PHYS2, ("pptp%d: bogus echo reply: %u != %u",
                   2132:       c->id, rep->id, c->echoId));
                   2133:     PptpCtrlKillCtrl(c);
                   2134:   }
                   2135: }
                   2136: 
                   2137: /*
                   2138:  * PptpOutCallRequest()
                   2139:  */
                   2140: 
                   2141: static void
                   2142: PptpOutCallRequest(PptpCtrl c, struct pptpOutCallRequest *req)
                   2143: {
                   2144:   struct pptpOutCallReply      reply;
                   2145:   struct pptpctrlinfo          cinfo;
                   2146:   struct pptplinkinfo          linfo;
                   2147:   PptpChan                     ch = NULL;
                   2148:   char                         calledNum[PPTP_PHONE_LEN + 1];
                   2149:   char                         subAddress[PPTP_SUBADDR_LEN + 1];
                   2150: 
                   2151:   /* Does link allow this? */
                   2152:   if (gGetOutLink == NULL)
                   2153:     goto denied;
                   2154: 
                   2155:   /* Copy out fields */
                   2156:   strncpy(calledNum, req->phone, sizeof(calledNum) - 1);
                   2157:   calledNum[sizeof(calledNum) - 1] = 0;
                   2158:   strncpy(subAddress, req->subaddr, sizeof(subAddress) - 1);
                   2159:   subAddress[sizeof(subAddress) - 1] = 0;
                   2160: 
                   2161:   /* Get a data channel */
                   2162:   if ((ch = PptpCtrlGetChan(c, PPTP_CHAN_ST_WAIT_ANSWER, FALSE, FALSE,
                   2163:       req->bearType, req->frameType, req->minBps, req->maxBps,
                   2164:       PPTP_STR_INTERNAL_CALLING, calledNum, subAddress)) == NULL) {
                   2165:     Log(LG_PHYS2, ("pptp%d: no free channels for outgoing call", c->id));
                   2166:     goto chFail;
                   2167:   }
                   2168: 
                   2169:   /* Ask link layer about making the outgoing call */
                   2170:   PptpCtrlInitCinfo(ch, &cinfo);
                   2171:   linfo = (*gGetOutLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port, req->bearType,
                   2172:     req->frameType, req->minBps, req->maxBps, calledNum, subAddress);
                   2173:   if (linfo.cookie == NULL)
                   2174:     goto denied;
                   2175: 
                   2176:   /* Link layer says it's OK; wait for link layer to report back later */
                   2177:   ch->serno = req->serno;
                   2178:   ch->peerCid = req->cid;
                   2179:   ch->peerPpd = req->ppd;
                   2180:   ch->recvWin = req->recvWin;
                   2181:   ch->linfo = linfo;
                   2182:   return;
                   2183: 
                   2184:   /* Failed */
                   2185: denied:
                   2186:   Log(LG_PHYS2, ("pptp%d: peer's outgoing call request denied", c->id));
                   2187:   if (ch)
                   2188:     PptpCtrlKillChan(ch, "peer's outgoing call request denied");
                   2189: chFail:
                   2190:   memset(&reply, 0, sizeof(reply));
                   2191:   reply.peerCid = req->cid;
                   2192:   reply.result = PPTP_OCR_RESL_ADMIN;
                   2193:   PptpCtrlWriteMsg(c, PPTP_OutCallReply, &reply);
                   2194: }
                   2195: 
                   2196: /*
                   2197:  * PptpOutCallReply()
                   2198:  */
                   2199: 
                   2200: static void
                   2201: PptpOutCallReply(PptpChan ch, struct pptpOutCallReply *reply)
                   2202: {
                   2203:   PptpCtrl     const c = ch->ctrl;
                   2204: 
                   2205:   /* Did call go through? */
                   2206:   if (reply->result != PPTP_OCR_RESL_OK) {
                   2207:     char       errmsg[100];
                   2208: 
                   2209:     snprintf(errmsg, sizeof(errmsg),
                   2210:       "pptp%d-%d: outgoing call failed: res=%s err=%s",
                   2211:       c->id, ch->id, PPTP_OCR_RESL_CODE(reply->result),
                   2212:       PPTP_ERROR_CODE(reply->err));
                   2213:     Log(LG_PHYS2, ("%s", errmsg));
                   2214:     (*ch->linfo.result)(ch->linfo.cookie, errmsg, 0);
                   2215:     PptpCtrlKillChan(ch, "remote outgoing call failed");
                   2216:     return;
                   2217:   }
                   2218: 
                   2219:   /* Call succeeded */
                   2220:   ch->peerPpd = reply->ppd;
                   2221:   ch->recvWin = reply->recvWin;
                   2222:   ch->peerCid = reply->cid;
                   2223:   Log(LG_PHYS2, ("pptp%d-%d: outgoing call connected at %d bps",
                   2224:     c->id, ch->id, reply->speed));
                   2225:   PptpCtrlNewChanState(ch, PPTP_CHAN_ST_ESTABLISHED);
                   2226:   (*ch->linfo.result)(ch->linfo.cookie, NULL, ch->frameType);
                   2227: }
                   2228: 
                   2229: /*
                   2230:  * PptpInCallRequest()
                   2231:  */
                   2232: 
                   2233: static void
                   2234: PptpInCallRequest(PptpCtrl c, struct pptpInCallRequest *req)
                   2235: {
                   2236:   struct pptpInCallReply       reply;
                   2237:   struct pptpctrlinfo          cinfo;
                   2238:   struct pptplinkinfo          linfo;
                   2239:   PptpChan                     ch;
                   2240:   char                         callingNum[PPTP_PHONE_LEN + 1];
                   2241:   char                         calledNum[PPTP_PHONE_LEN + 1];
                   2242:   char                         subAddress[PPTP_SUBADDR_LEN + 1];
                   2243: 
                   2244:   /* Copy out fields */
                   2245:   if (req->dialedLen > PPTP_PHONE_LEN)
                   2246:     req->dialedLen = PPTP_PHONE_LEN;
                   2247:   if (req->dialingLen > PPTP_PHONE_LEN)
                   2248:     req->dialingLen = PPTP_PHONE_LEN;
                   2249:   strncpy(callingNum, req->dialing, sizeof(callingNum) - 1);
                   2250:   callingNum[req->dialingLen] = 0;
                   2251:   strncpy(calledNum, req->dialed, sizeof(calledNum) - 1);
                   2252:   calledNum[req->dialedLen] = 0;
                   2253:   strncpy(subAddress, req->subaddr, sizeof(subAddress) - 1);
                   2254:   subAddress[sizeof(subAddress) - 1] = 0;
                   2255: 
                   2256:   Log(LG_PHYS2, ("pptp%d: peer incoming call to \"%s\" from \"%s\"",
                   2257:     c->id, calledNum, callingNum));
                   2258: 
                   2259:   /* Initialize reply */
                   2260:   memset(&reply, 0, sizeof(reply));
                   2261:   reply.peerCid = req->cid;
                   2262:   reply.recvWin = PPTP_RECV_WIN;       /* XXX */
                   2263:   reply.ppd = PPTP_PPD;                        /* XXX */
                   2264: 
                   2265:   /* Get a data channel */
                   2266:   if ((ch = PptpCtrlGetChan(c, PPTP_CHAN_ST_WAIT_CONNECT, FALSE, TRUE,
                   2267:       req->bearType, 0, 0, INT_MAX,
                   2268:       callingNum, calledNum, subAddress)) == NULL) {
                   2269:     Log(LG_PHYS2, ("pptp%d: no free channels for incoming call", c->id));
                   2270:     reply.result = PPTP_ICR_RESL_ERR;
                   2271:     reply.err = PPTP_ERROR_NO_RESOURCE;
                   2272:     goto done;
                   2273:   }
                   2274:   reply.cid = ch->cid;
                   2275: 
                   2276:   /* Ask link layer about accepting the incoming call */
                   2277:   PptpCtrlInitCinfo(ch, &cinfo);
                   2278:   linfo.cookie = NULL;
                   2279:   linfo.result = NULL;
                   2280:   linfo.setLinkInfo = NULL;
                   2281:   linfo.cancel = NULL;
                   2282:   if (gGetInLink)
                   2283:     linfo = (*gGetInLink)(&cinfo, &c->self_addr, &c->peer_addr, c->peer_port,
                   2284:       req->bearType, callingNum, calledNum, subAddress);
                   2285:   ch->linfo = linfo;
                   2286:   if (linfo.cookie == NULL) {
                   2287:     Log(LG_PHYS2, ("pptp%d: incoming call request denied", c->id));
                   2288:     reply.result = PPTP_ICR_RESL_NAK;
                   2289:     goto done;
                   2290:   }
                   2291: 
                   2292:   /* Link layer says it's OK */
                   2293:   Log(LG_PHYS2, ("pptp%d-%d: accepting incoming call to \"%s\" from \"%s\"",
                   2294:     c->id, ch->id, calledNum, callingNum));
                   2295:   reply.result = PPTP_ICR_RESL_OK;
                   2296:   ch->serno = req->serno;
                   2297:   ch->peerCid = req->cid;
                   2298:   ch->bearType = req->bearType;
                   2299:   strncpy(ch->callingNum, req->dialing, sizeof(ch->callingNum));
                   2300:   strncpy(ch->calledNum, req->dialed, sizeof(ch->calledNum));
                   2301:   strncpy(ch->subAddress, req->subaddr, sizeof(ch->subAddress));
                   2302: 
                   2303:   /* Return result */
                   2304: done:
                   2305:   if (PptpCtrlWriteMsg(c, PPTP_InCallReply, &reply) == -1)
                   2306:     return;
                   2307:   if (reply.result != PPTP_ICR_RESL_OK)
                   2308:     PptpCtrlKillChan(ch, "peer incoming call failed");
                   2309: }
                   2310: 
                   2311: /*
                   2312:  * PptpInCallReply()
                   2313:  */
                   2314: 
                   2315: static void
                   2316: PptpInCallReply(PptpChan ch, struct pptpInCallReply *reply)
                   2317: {
                   2318:   PptpCtrl             const c = ch->ctrl;
                   2319: 
                   2320:   /* Did call go through? */
                   2321:   if (reply->result != PPTP_ICR_RESL_OK) {
                   2322:     char       errmsg[100];
                   2323: 
                   2324:     snprintf(errmsg, sizeof(errmsg),
                   2325:       "pptp%d-%d: peer denied incoming call: res=%s err=%s",
                   2326:       c->id, ch->id, PPTP_ICR_RESL_CODE(reply->result),
                   2327:       PPTP_ERROR_CODE(reply->err));
                   2328:     Log(LG_PHYS2, ("%s", errmsg));
                   2329:     (*ch->linfo.result)(ch->linfo.cookie, errmsg, 0);
                   2330:     PptpCtrlKillChan(ch, "peer denied incoming call");
                   2331:     return;
                   2332:   }
                   2333: 
                   2334:   /* Call succeeded */
                   2335:   Log(LG_PHYS2, ("pptp%d-%d: incoming call accepted by peer", c->id, ch->id));
                   2336:   ch->peerCid = reply->cid;
                   2337:   ch->peerPpd = reply->ppd;
                   2338:   ch->recvWin = reply->recvWin;
                   2339:   PptpCtrlNewChanState(ch, PPTP_CHAN_ST_ESTABLISHED);
                   2340:   (*ch->linfo.result)(ch->linfo.cookie, NULL, ch->frameType);
                   2341: }
                   2342: 
                   2343: /*
                   2344:  * PptpInCallConn()
                   2345:  */
                   2346: 
                   2347: static void
                   2348: PptpInCallConn(PptpChan ch, struct pptpInCallConn *con)
                   2349: {
                   2350:   PptpCtrl     const c = ch->ctrl;
                   2351: 
                   2352:   Log(LG_PHYS2, ("pptp%d-%d: peer incoming call connected at %d bps",
                   2353:     c->id, ch->id, con->speed));
                   2354:   ch->peerPpd = con->ppd;
                   2355:   ch->recvWin = con->recvWin;
                   2356:   ch->frameType = con->frameType;
                   2357:   (*ch->linfo.result)(ch->linfo.cookie, NULL, ch->frameType);
                   2358:   PptpCtrlNewChanState(ch, PPTP_CHAN_ST_ESTABLISHED);
                   2359: }
                   2360: 
                   2361: /*
                   2362:  * PptpCallClearRequest()
                   2363:  */
                   2364: 
                   2365: static void
                   2366: PptpCallClearRequest(PptpChan ch, struct pptpCallClearRequest *req)
                   2367: {
                   2368:   struct pptpCallDiscNotify    notify;
                   2369:   PptpCtrl                     const c = ch->ctrl;
                   2370: 
                   2371:   if (PPTP_CHAN_IS_PNS(ch)) {
                   2372:     Log(LG_PHYS2, ("pptp%d-%d: got %s, but we are PNS for this call",
                   2373:       c->id, ch->id, gPptpMsgInfo[PPTP_CallClearRequest].name));
                   2374:     PptpCtrlKillCtrl(c);
                   2375:     return;
                   2376:   }
                   2377:   Log(LG_PHYS2, ("pptp%d-%d: call cleared by peer", c->id, ch->id));
                   2378:   memset(&notify, 0, sizeof(notify));
                   2379:   notify.cid = ch->cid;                        /* we are the PAC, use our CID */
                   2380:   notify.result = PPTP_CDN_RESL_REQ;
                   2381:   /* XXX stats? */
                   2382:   PptpCtrlKillChan(ch, "cleared by peer");
                   2383:   PptpCtrlWriteMsg(c, PPTP_CallDiscNotify, &notify);
                   2384: }
                   2385: 
                   2386: /*
                   2387:  * PptpCallDiscNotify()
                   2388:  */
                   2389: 
                   2390: static void
                   2391: PptpCallDiscNotify(PptpChan ch, struct pptpCallDiscNotify *notify)
                   2392: {
                   2393:   PptpCtrl     const c = ch->ctrl;
                   2394: 
                   2395:   Log(LG_PHYS2, ("pptp%d-%d: peer call disconnected res=%s err=%s",
                   2396:     c->id, ch->id, PPTP_CDN_RESL_CODE(notify->result),
                   2397:     PPTP_ERROR_CODE(notify->err)));
                   2398:   PptpCtrlKillChan(ch, "disconnected by peer");
                   2399: }
                   2400: 
                   2401: /*
                   2402:  * PptpWanErrorNotify()
                   2403:  */
                   2404: 
                   2405: static void
                   2406: PptpWanErrorNotify(PptpChan ch, struct pptpWanErrorNotify *notif)
                   2407: {
                   2408:   PptpCtrl     const c = ch->ctrl;
                   2409: 
                   2410:   Log(LG_PHYS2, ("pptp%d-%d: ignoring %s",
                   2411:     c->id, ch->id, gPptpMsgInfo[PPTP_WanErrorNotify].name));
                   2412: }
                   2413: 
                   2414: /*
                   2415:  * PptpSetLinkInfo()
                   2416:  */
                   2417: 
                   2418: static void
                   2419: PptpSetLinkInfo(PptpChan ch, struct pptpSetLinkInfo *info)
                   2420: {
                   2421:   PptpCtrl     const c = ch->ctrl;
                   2422: 
                   2423:   if (ch->linfo.setLinkInfo)
                   2424:     (*ch->linfo.setLinkInfo)(ch->linfo.cookie, info->sendAccm, info->recvAccm);
                   2425:   else {
                   2426:     Log(LG_PHYS2, ("pptp%d-%d: ignoring %s",
                   2427:       c->id, ch->id, gPptpMsgInfo[PPTP_SetLinkInfo].name));
                   2428:   }
                   2429: }
                   2430: 
                   2431: /*
                   2432:  * PptpsStat()
                   2433:  */
                   2434: 
                   2435: int
                   2436: PptpsStat(Context ctx, int ac, char *av[], void *arg)
                   2437: {
                   2438:     int                k;
                   2439:     char       buf1[48], buf2[48];
                   2440: 
                   2441:     Printf("Active PPTP tunnels:\r\n");
                   2442:     for (k = 0; k < gNumPptpCtrl; k++) {
                   2443:        PptpCtrl        const c = gPptpCtrl[k];
                   2444:        if (c) {
                   2445: 
                   2446:            u_addrtoa(&c->self_addr, buf1, sizeof(buf1));
                   2447:            u_addrtoa(&c->peer_addr, buf2, sizeof(buf2));
                   2448:            Printf("pptp%d\t %s %d <=> %s %d\t%s\t%d calls\r\n",
                   2449:                c->id, buf1, c->self_port, buf2, c->peer_port,
                   2450:                gPptpCtrlStates[c->state], c->active_sessions);
                   2451:        }
                   2452:     }
                   2453: 
                   2454:     return 0;
                   2455: }

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