From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 11-MAR-1993 03:10:03.77
To:	Info-VAX@KL.SRI.COM
CC:	
Subj:	Re: Getting the IP-addres of a terminal connected to VAX via LAN


In article <01GVKHJ3XPO08WVZWI@RUGR86.RUG.NL>, rutges_ass@RUGB38.BDK.RUG.NL () writes:
|>Howdy,
|>
|>We use Wollongong TCP/IP 5.1 here, and we would want to extract the IP-numbers
|>of the users who login by means of NCSA telnet over our NETWARE 3.11 LAN.

I had a dream once where all of our customers were running current
version software on all their machines...then I woke up.

WIN/TCP V5.2 provides this information through the TT_ACCPORNAM item
of the F$GETDVI lexical function. For those of you stranded on V5.1,
I've included a sample C program which may serve as a base upon which
you may build.

NOTE: THIS PROGRAM SPENDS PART OF ITS TIME IN KERNEL MODE. ANY MISTAKES
      MAY RESULT IN A SYSTEM CRASH! IF YOU DON'T UNDERSTAND WHY, DON'T
      TRY TO USE THIS PROGRAM.

NOTE ALSO: This program is entirely unsupported. There is no warranty of
           any kind associated with it, and Customer Support won't have
           any idea what you're talking about.

|>Send mail directly, I will summarize if others request the same info.

I'm emailing this response to the original poster, as well as posting
it. I suggest any further discussion be moved to the newsgroup
'vmsnet.networks.tcp-ip.wintcp' (I'd add a Followup-To: line, but I
know not everyone gets the vmsnet hierarchy).

--
Reece R. Pollack
Senior Software Engineer
The Wollongong Group, Inc.


-------------------------- Cut Here --------------------------
#module ACCPORNAM "V1.0-000"

/*
**++
**  FACILITY:  WIN/TCP sample programs
**
**  MODULE DESCRIPTION:
**
**	This program fetches the sockaddr_in structure from
**	an NTYn: device UCB and displays its contents.
**
**  AUTHORS:
**
**	Reece R. Pollack
**	Senior Software Engineer
**	The Wollongong Group, Inc.
**
**  CREATION DATE:  30-Oct-1991
**
**  DESIGN ISSUES:
**
**	Portions of this program execute in kernel mode.
**	Modifications should be done with extreme care
**	or a system crash or corruption may result.
**
**  INCLUDED FILES:
**
**	ssdef.h
**	descrip.h
**	sys/types.h
**	netinet/in.h
**	vms/ucbdef.h
**	vms/ttyucbdef.h
**
**
**  MODIFICATION HISTORY:
**
**      None.
**
**  DISCLAIMER:
**
**	This is completely unsupported software. No warranty
**	of usability or correctness of any kind is given or
**	implied.
**
**--
*/


/*
**
**  INCLUDE FILES
**
*/
#include <ssdef.h>
#include <descrip.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <vms/ucbdef.h>
#include <vms/ttyucbdef.h>

/*
**  UCB structure for NTY device
*/
struct NTYUCB {
    char		filler[ UCB$K_TT_LENGTH ];
    long		ucb$l_nt_data;
    struct sockaddr_in	ucb$l_nt_addr;
};

/*
**  CCB structure and definitions
*/
struct CCB {
    struct NTYUCB	*ccb$l_ucb;
    struct WCB		*ccb$l_wind;
    char		ccb$b_sts;
    char		ccb$b_amod;
    unsigned short	ccb$w_ioc;
    struct IRP		*ccb$l_dirp;
};
#define	CCB$K_LENGTH	16
#define	CCB$C_LENGTH	16
#define	CCB$S_CCBDEF	16


/*
** CCB base address pointer
*/
globalref const struct CCB * const ctl$gl_ccbbase;



/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**	Kernel-mode routine to get the sockaddr_in structure
**	from the end of an NTYn: device UCB structure.
**
**  FORMAL PARAMETERS:
**
**	chan:
**	    channel to the NTYn: device
**
**	sin:
**	    pointer to a sockaddr_in structure
**
**  RETURN VALUE:
**
**	One of:
**	    SS$_NORMAL		- normal successful completion
**	    SS$_IVCHAN		- invalid channel specified
**	    SS$_BADCONTEXT	- UCB too short
**
**  SIDE EFFECTS:
**
**      None
**
**  DESIGN:
**
**      {@description or none@}
**
**
**--
*/
static int fetch_sin (
    const unsigned short chan,
    struct sockaddr_in * const sin )
{
    register const struct CCB		*ccb;
    register const struct NTYUCB	*ucb;

    ccb = (char *)ctl$gl_ccbbase - chan;
    if( ccb->ccb$b_amod == 0 )
	return( SS$_IVCHAN );

    ucb = ccb->ccb$l_ucb;
    if( ((struct UCB *)ucb)->ucb$w_size < sizeof(*ucb) )
	return( SS$_BADCONTEXT );

    *sin = ucb->ucb$l_nt_addr;
    return( SS$_NORMAL );
}


/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**	Main function of program
**
**  FORMAL PARAMETERS:
**
**	None
**
**  RETURN VALUE:
**
**	{@description or none@}
**
**  SIDE EFFECTS:
**
**	None
**
**  DESIGN:
**
**      {@description or none@}
**
**
**  [@optional function tags@]...
**
**--
*/
int main (
    int		argc,
    char	*argv[] )
{
    register int	ss;
    short		chan;
    struct sockaddr_in	sin;
    static $DESCRIPTOR( devnam, "SYS$COMMAND" );

    struct {
	long			argcnt;
	unsigned long		chan;
	struct sockaddr_in	*sin;
    } arglst;

    union {
	unsigned long	network;
	unsigned char	byte[4];
    } s_addr;

    /*
    **	Assign a channel to the NTY device
    */
    ss = sys$assign( &devnam, &chan, 0, 0 );
    if( !(ss & 1) )
	return( ss );


    /*
    **	Fetch the sockaddr_in structure from the UCB
    */
    arglst.argcnt = 2;
    arglst.chan   = chan;
    arglst.sin    = &sin;
    ss = sys$cmkrnl( &fetch_sin, &arglst );
    if( !(ss & 1) )
	return( ss );


    /*
    **	Print the remote IP address and port number
    */
    s_addr.network = sin.sin_addr.s_addr;
    printf( "Remote IP address:  %d.%d.%d.%d\n", s_addr.byte[0],
		 s_addr.byte[1], s_addr.byte[2], s_addr.byte[3] );
    printf( "Remote port number: %d\n", ntohs(sin.sin_port) );
    return( SS$_NORMAL );
}

