Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a TCP connection is local?

Tags:

c++

tcp

sockets

For a project, I need to know whether the network connection is from the local computer or from a remote computer.

How to achieve this?

like image 964
Refugnic Eternium Avatar asked Aug 23 '14 14:08

Refugnic Eternium


People also ask

How do I check TCP connection status?

Press the Windows key + R, then type "cmd.exe" and click OK. Enter "telnet + IP address or hostname + port number" (e.g., telnet www.example.com 1723 or telnet 10.17. xxx. xxx 5000) to run the telnet command in Command Prompt and test the TCP port status.

How do I know if a TCP socket is connected?

If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.

How is a TCP connection identified?

A TCP data stream is uniquely identified by a group of four numbers. These are the two hosts addresses and the two port numbers. Destination port number. This is the "target" port number on the remote system.

How check TCP connection in Linux?

Telnet and nc are common tools used to test port connectivity from Linux server. Telnet can be used to test tcp port connections, where as nc can be used to test both tcp/udp ports connectivity. Make sure telnet and nc tools are installed on the Linux server you are trying to test connectivity.


1 Answers

This can be achieved by utilizing the getpeername and the getsockname functions.

This snipped does exactly what I need it to:

 bool checkForLocalConnection(SOCKET Sock) {
      sockaddr_in RemAddr, LocAddr;
      int Len = sizeof(RemAddr);
      getpeername(Sock, (sockaddr *)&RemAddr, &Len);
      getsockname(Sock, (sockaddr *)&LocAddr, &Len);
      return (RemAddr.sin_addr.S_un.S_addr == LocAddr.sin_addr.S_un.S_addr);
 }

The endianess of the result is always the same, which is why you don't even have to convert it to native endianess.

Why this works and why it's necessary:

If you connect to localhost or 127.0.0.1, getpeername will always yield the address 127.0.0.1 (converted to an unsigned long, obviously). That means, you could just check for htonl(2130706433); and be done with it (Minding the endianess). However if you enter the actual address...or any of your other local addresses your NIC might have, getpeername will return that address, instead of 127.0.0.1.

getsockname will return the local interface this socket is connected on, which means it will choose the correct interface and tell you its address, which is equal only if you're connected from a local machine.

I hope this will help someone, since I had to search forever to find that little info. It should work for most common cases. (There are some exceptions)

List of exceptions:

Multi-Address network cards. These are on the same machine but either not on the same NIC or bound to a different IP. There isn't that much you can do about that.

Calling localhost on a different IP than 127.0.0.1. getsockname will always return 127.0.0.1, regardless of which 127.x.x.x you're calling. As a 'guard' against that, you can check specifically for the 127 in the first octet of the peer address.

Many thanks for the help with this goes to harper.

like image 53
Refugnic Eternium Avatar answered Sep 22 '22 03:09

Refugnic Eternium