File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / pptp_ctrl.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (3 years, 4 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

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

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