File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / pptp_ctrl.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (10 years, 11 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, HEAD
5.7

    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;
  693:   memset(cinfo, 0, sizeof(*cinfo));
  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>