/************************************************************************ ** * ** Copyright © 1996 Digital Equipment Corporation. * ** All rights reserved. * ** * ** Redistribution and use in source and binary forms are permitted * ** provided that the above copyright notice and this paragraph are * ** duplicated in all such forms and that any documentation, * ** advertising materials, and other materials related to such * ** distribution and use acknowledge that the software was developed * ** by Digital Equipment Corporation. The name of the * ** Corporation may not be used to endorse or promote products derived * ** from this software without specific prior written permission. * ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * ** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * ** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * ** * ************************************************************************* ** * ** Important Note: * ** * ** This coding example uses privileged OpenVMS interfaces. * ** OpenVMS does not guarantee that these interfaces will * ** be supported indefinitely, and may change these interfaces * ** without prior notice. * ** * ************************************************************************* **++ ** FACILITY: ** ** PPPD ** ** ABSTRACT: ** ** This moudle implements a callback routine to start a protocol ** a protocol running over PPP. The routine is called when a user ** types the "CONNECT" command in the PPPD utility. It is ** registered via the "SET NETWORK" command with the ** /pppd_callout switch. ** ** The code assumes that the sample exe (in this case IP_VCM.EXE) ** contains pointer to the rotuine to the start the protocol in ** the first longword of the nonpaged base section of the image. ** A protocol doesn't have to be implemented this way, it was ** just one of the ways it can be done. ** ** AUTHORS: ** ** Patrick Crilly, Networks Engineering (Australia). ** ** CREATION DATE: ** ** 5-March-1996 ** ** MODIFICATION HISTORY: ** ** 17-December-1996 Barry W. Kierstein ** Replaced the standard Digital copyright with ** one compatible with the CMU copyright. ** ** 1-October-1996 Forrest A. Kenney ** Remove 4 character device name restriction also make ** string is null terminated. ** ** 1-August-1996 Barry W. Kierstein ** Added "Important Note" disclaimer. ** ** 24-July-1996 Barry W. Kierstein ** Corrected copyright notice. ** ** 5-March-1996 Original version. ** **-- */ /* ** ** import definitions: ** SS$_xxx ** */ #include "ssdef.h" /* ** ** import definitions: ** printf ** */ #include "stdio.h" /* ** ** import definitions: ** descriptors ** */ #include "descrip.h" /* ** ** import definitions: ** strncmp ** */ #include "string.h" /* ** ** import definitions: ** ldrimg defintions ** */ #include "ldrimgdef.h" #define MIN( a, b ) ((a) < (b) ? (a) : (b)) /* ** External variables */ extern void *LDR$GQ_IMAGE_LIST; /* ** Callback routine to start the protocol ** ** It accepts the name of the TTAx: device to start the protocol on ** as an input parameter. ** ** The callback routine is fairly straight forward. It hunts down the ** list of loaded execlets to find IP_VCM.EXE. The first longword of ** IP_VCM.EXE contains a pointer to the routine which causes the VCM ** to start the protocol. When the IP_VCM image is found a pointer to the ** routine to start the protocol is saved. The routine is then called. ** ** One thing to note is that the routine to start the protocol in the sample ** VCM doesn't accept device names greater than 5 characters (not including the ** NULL). Check out the comments in ip_vcm.c */ int PPPD$OPEN_CONNECT(struct dsc$descriptor *devName ) { int status = SS$_NORMAL; LDRIMG *imageP; /* pointer to executive image */ void *rtnAddr = NULL; /* pointer to routine */ char ttDevName[20]; /* startProtocol won't let it be longer than 4 bytes */ int (*startProtocol)( char * ); /* pointer to startRoutine in VCM */ /* ** Set-up the name of the TTAx: device to use */ if ( devName->dsc$w_length >= sizeof(ttDevName) ) { return ( SS$_BUFFEROVF ); } strncpy( ttDevName, devName->dsc$a_pointer, devName->dsc$w_length ); ttDevName[devName->dsc$w_length] = '\0'; /* ** Find the IP_VCM.EXE execlet. */ for ( imageP = (LDRIMG *)LDR$GQ_IMAGE_LIST; imageP != (LDRIMG *)&LDR$GQ_IMAGE_LIST; imageP = imageP->ldrimg$l_flink ) { if ( !strncmp(imageP->ldrimg$t_imgnam, "IP_VCM.EXE", MIN(imageP->ldrimg$b_imgnamlen, strlen("IP_VCM.EXE")))) { rtnAddr = *(void **)imageP->ldrimg$l_nonpag_w_base; } } /* Call the routine in the test VCM which starts the protocol */ startProtocol = (int (*)())rtnAddr; if ( startProtocol ) { status = (*startProtocol)( ttDevName ); } else { status = SS$_ABORT; } return (status); }