VMware Horizon Community
guyrleech
Virtuoso
Virtuoso
Jump to solution

Getting the View client's IP address

I have some code that uses the well established WTSQuerySessionInformation() API call (), via the WTSClientAddress argument, to retrieve the IP address of the client that is connected to an RDP session.

When this code is run inside a View session (on XP SP3), it always returns 127.0.0.1 rather than the IP address of the client connecting to the View session. If I disconnect the View session and reconnect as the same user via an RDP console session then the client IP address is correctly returned. Using the WTSClientName argument to return the client name always returns the correct client name, regardless of whether the session is connected through RDP or the View client.

Anyone got any ideas how I retrieve the client IP address please? Probably should be posted to a developer community but I can't really find a relevant one.

-- If you found this or any other answer useful please consider the use of the Helpful or Correct buttons to award points.
0 Kudos
1 Solution

Accepted Solutions
admin
Immortal
Immortal
Jump to solution

This is happening because of the View tunnel, because in tunneled mode the RDP control connects to 127.0.0.1 (on the client-side) and the socket connection is then tunneled over to the remote side. The session information is populated with information provided by the RDP client hence the discrepancy.

We intend to address this issue in a future version of VMware View by providing various details about the client as environment variables available from within the RDP session, including the client's true IP address, e.g.:

ViewClient_Broker_DNS_Name=broker.foo.com

ViewClient_Broker_Remote_IP_Address=1.2.3.4

ViewClient_Broker_Tunneled=false

ViewClient_Broker_URL=https://broker.foo.com:443

ViewClient_IP_Address=5.6.7.8

ViewClient_LoggedOn_Domainname=FOO

ViewClient_LoggedOn_Username=user

ViewClient_Machine_Domain=bar

ViewClient_Machine_Name=baz

ViewClient_MAC_Address=00-12-34-56-BE-EF

ViewClient_Type=Windows

View solution in original post

0 Kudos
8 Replies
admin
Immortal
Immortal
Jump to solution

This is happening because of the View tunnel, because in tunneled mode the RDP control connects to 127.0.0.1 (on the client-side) and the socket connection is then tunneled over to the remote side. The session information is populated with information provided by the RDP client hence the discrepancy.

We intend to address this issue in a future version of VMware View by providing various details about the client as environment variables available from within the RDP session, including the client's true IP address, e.g.:

ViewClient_Broker_DNS_Name=broker.foo.com

ViewClient_Broker_Remote_IP_Address=1.2.3.4

ViewClient_Broker_Tunneled=false

ViewClient_Broker_URL=https://broker.foo.com:443

ViewClient_IP_Address=5.6.7.8

ViewClient_LoggedOn_Domainname=FOO

ViewClient_LoggedOn_Username=user

ViewClient_Machine_Domain=bar

ViewClient_Machine_Name=baz

ViewClient_MAC_Address=00-12-34-56-BE-EF

ViewClient_Type=Windows

0 Kudos
admin
Immortal
Immortal
Jump to solution

At the moment you could use the %Clientname% env. variable on the virtual desktop. write a script where you ping this variable and you'll get back the IP.

Blog: http://communities.vmware.com/blogs/dommermuth

guyrleech
Virtuoso
Virtuoso
Jump to solution

Thanks but I suspect that will only work when the client name is known to the DNS at the server side so won't help for remote clients and non-AD joined clients.

---

If you found this or any other answer useful please consider the use of the Helpful or Correct buttons to award points.

-- If you found this or any other answer useful please consider the use of the Helpful or Correct buttons to award points.
0 Kudos
guyrleech
Virtuoso
Virtuoso
Jump to solution

Thank you for the prompt information - I'll see about getting us on to the beta program.

---

If you found this or any other answer useful please consider the use of the Helpful or Correct buttons to award points.

-- If you found this or any other answer useful please consider the use of the Helpful or Correct buttons to award points.
0 Kudos
wbarnes
Contributor
Contributor
Jump to solution

I'm looking for this functionality as well.

I can script a fair amount of things if I know where the client is on our network. (closet printer, etc.)

my temporary workaround is to carefully name my thin clients, and use that in my scripts if the IP address comes back as 127.0.0.1

(I'm using WTSManager.shell in my scripts)

here's a snippet of what I'm doing:

if ( ipaddress = "127.0.0.1" ) then

ClientName = WTS.MyClientName

matchClientName = left(ClientName,6)

Select Case matchClientName

Case "XX-F1-": Vlan = 189

Case "XX-F2-": Vlan = 182

Case "XX-F3-": Vlan = 186

Case "XX-F4-": Vlan = 184

End Select

somethign like that.

0 Kudos
phil_
Contributor
Contributor
Jump to solution

I would also to like to read the WTSClientAddress with WTSQuerySessionInformation from the WTS API.

Unfortunately this will deliver no information when using vmware view 5.1 .

Is it not possible for vmware to fill this information, to handle the windows terminal server API right?

all the best and thanks

phil

0 Kudos
virtualseed
Contributor
Contributor
Jump to solution

View Agent writes this data to the registry under HKCU\Volatile Environment on each connect/re-connect of a client.

0 Kudos
phil_
Contributor
Contributor
Jump to solution

Hi

Of course i know that the information can be found in the HKCU, the Users Registry.

But i have a Windows-Services, running under Local-Service rights that catch all events of login and logout of each user via the Windows Terminal Service API (WTS, now called Remote Desktop Service API).

This server is then sending the informations of the users to server. The User can't stop or change anything releated to this service, so there is no fake logout.

So the point is, microsoft is providing a API to retrieve the information, but it isn't used/filled in by vmware.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383861%28v=vs.85%29.aspx

I don't think its easy and the normal way to read from the users registry with a service running under local-service account rights.

Greetings

Phil

Here the story in c# with cassia, my code is free to use.

protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            _log.Debug("OnSessionChange triggered.");

            // Inform the base class of the change as well
            base.OnSessionChange(changeDescription);

            // Use a switch block to segment the actions to perform for
            // different session changes
            switch (changeDescription.Reason)
            {
                case SessionChangeReason.SessionLogon:
                    {
                        _log.Debug("SessionLogon...");
                        string username = "";
                        string clientAddress = ""; //used for rdp clients

                        try
                        {                         

                            ITerminalServicesManager manager = new TerminalServicesManager();
                            using (ITerminalServer server = manager.GetLocalServer())
                            {
                                ITerminalServicesSession session = server.GetSession(changeDescription.SessionId);

                                //username (each user gets a connection.)
                                username = session.UserName;

                                //when the user connects via a remote session, get the origin address
                                if (session.ClientIPAddress != null)
                                {
                                    clientAddress = session.ClientIPAddress.ToString();
                                }
                            }

                            m_connections.Create(changeDescription.SessionId).SendLogonInfo(username, clientAddress);

                            //log if requested
                            _log.Debug("SessionLogon Done, Session: '" + changeDescription.SessionId .ToString() + "', Username: '" + username + "'.");
                        }
                        catch (Exception ex)
                        {
                            _log.Error("SessionLogon Exception: " + ex.Message);
                        }
                    }
                    break;

                case SessionChangeReason.SessionLogoff:
                    {
                        _log.Debug("SessionLogoff...");
                        string username = "";

                        //logoff
                        try
                        {
                            //username (each user gets a connection.)
                            ITerminalServicesManager manager = new TerminalServicesManager();
                            using (ITerminalServer server = manager.GetLocalServer())
                            {
                                ITerminalServicesSession session = server.GetSession(changeDescription.SessionId);

                                //username (each user gets a connection.)
                                username = session.UserName;
                            }

                            m_connections.Create(changeDescription.SessionId).SendLogoffInfo(username);

                            //log if requested
                            _log.Debug("SessionLogoff Done, Session: '" + changeDescription.SessionId.ToString() + "', Username: '" + username + "'.");
                        }
                        catch (Exception ex)
                        {
                            _log.Error("SessionLogoff, Exception: " + ex.Message);
                        }

                        //remove connection
                        try
                        {
                            //username (each user gets a connection.)
                            m_connections.Delete(changeDescription.SessionId);
                        }
                        catch (Exception ex)
                        {
                            _log.Error("SessionLogoff, remove Connection, Exception: " + ex.Message);
                        }

                    }
                    break;              
            }//switch
           
        }//OnSessionChange()

0 Kudos