Choose a TCP port on a Windows machine, add a firewall exception if necessary (programmatically)? - c++

Thank you for reading my post.
Can you help me interpret what the following line from "netstat -anb" means:
Proto Local Address Foreign Address State
TCP 192.168.2.241:52440 64.233.166.103:443 ESTABLISHED
[firefox.exe]
In particular:
does this mean that the TCP port 52440 is opened on the machine which IP is 192.168.2.241?
does this mean "firefox.exe" is bound to this port?
Can you guess how "firefox.exe" knew it could use this port (without interfering with another program already bound to that port)?
As a matter of fact, "firefox.exe" is using a lot of ports.
For example, right now on 192.168.2.241, "firefox.exe" is using the ports nro 52163, 57019, 57022, 57030, 57045, 57046, 57049, 57051.
I am asking all this because I would like to write a program which binds to a TCP port to enable communication between the machine where the program is installed and a remote machine on the Internet using sockets.
Contrary to "Firefox" I need only one TCP port on the machine where the program will be installed.
I only need this mechanism to work once, the first time the program is executed (this is not a permanent feature of the program).
How can this port be chosen?
How can this port be chosen programmatically (not manually)?
If there is a firewall preventing the use of any port/the chosen port, how is the program going to behave?
Can an exception be added programmatically to the firewall to open this port?
The machine running the program is a Windows machine.
I would program this in C/C++.
Best regards.
Below is a complement to my original question.
Well, my apologies, maybe you're right: maybe it's wrong to add an exception in the firewall of the user...
What I mean by "adding an exception in the firewall of the user" is doing something like this:
netsh advfirewall firewall add rule name="An exn" dir=in action=allow protocol=TCP localport=6667 program="where/the/program/is/stored/prog.exe" enable=yes
Until now, I thought that, if an application was already "using" a TCP port for its own usage, no other application could "use" this very same port. (I'm aware of the fact that the word "use" is very imprecise. I'd be glad to be able to formulate things more accurately...)
I'm saying this because, as I need a TCP port, I was wondering if I could use an "already available" TCP port... (When I say "already available", I don't exactly know what I mean (maybe I would like to say "open" and "bindable" / or a port already "used" by another application): I'm thinking about TCP port 80 which is often "available"... Again, I wish I could be more specific about this.)
Please let me try to reformulate what I'm willing to do.
A user runs a program "setup.exe" on its machine "M".
"setup.exe" sends a message "m1" to an Internet remote server "RS".
"RS" sends back some information "m2" to "setup.exe" running on machine "M" through a TCP port.
To be able to allow this bidirectional communication between "M" and "RS", I need to "have" a TCP port on machine "M" from which "setup.exe" can receive information sent by "RS". ("RS" is not a problem to me, I can do anything I want on it).
Given the fact that I know nothing about "M" a priori apart from the fact that it is a Windows machine (in particular I do not know what kind of firewall protects it, etc.), I don't really know how to handle the problem correctly. What I would like to avoid is having "setup.exe" fail silently without telling why the TCP port on machine "M" can't be "used".
Given the fact that I need to "have a TCP port available" for the program "setup.exe" running on machine M, what steps should I follow to make it as smooth as possible for the user.
Suppose I'm trying to "use" TCP port 6667, and suppose I'm not "allowed" to.
Apart from a firewall, or another application already "using" this port, what could be the reasons why this port is not available?
I simulated the two machines "M" and "RS" basically using this code http://msdn.microsoft.com/en-us/library/windows/desktop/ms737889%28v=vs.85%29.aspx.
I didn't add an exception to "M"'s firewall.
The two programs on machines "M" and "RS" could communicate smoothly and correctly.
But as you pointed it out in your first answer, "there are no outbound port rules in the firewall at all" on these test machines...
So, I tried, as a simulation, to add an exception into the M's firewall in the section "Outbound rules" to block completely the connection to port TCP 6667 on machine "M": the scenario described above (steps 1) 2) 3)) fails in that case.
I hope this literature is not too indigestible and sorry for the approximations and misunderstandings.
Thank you for helping. Best regards.

does this mean that the TCP port 52440 is opened on the machine which IP is 192.168.2.241?
Possibly, but more probably it means there are no outbound port rules in the firewall at all, as there shouldn't be, being pointless.
does this mean "firefox.exe" is bound to this port?
It means that socket of firefox.exe is bound to that port. It can have many other sockets, and usually does.
I would like to write a program which binds to a TCP port to enable communication between the machine where the program is installed and a remote machine on the Internet using sockets.
You need to state whether your program is a client or a server. If it's a client, it's exactly like Firefox, and you don't have a problem. If it's a server, you have to bind to a port that is open for incoming in your firewall, and Firefox is completely and utterly irrelevant.
Contrary to "Firefox" I need only one TCP port on the machine where the program will be installed.
Sounds like a server, but you need to tell us. For simplicity I am assuming it's a server from here on.
I only need this mechanism to work once, the first time the program is executed (this is not a permanent feature of the program).
You don't need this mechanism to work at all. You need the user to open the port. The user won't appreciate software that breaks his firewall configuration, assuming you can do it at all, which you shouldn't.
How can this port be chosen?
By you. Choose it now. Use one that isn't reserved by IANA.
How can this port be chosen programmatically (not manually)?
You can specify port zero but then you have to tell the user so he can open it at the firewall.
If there is a firewall preventing the use of any port/the chosen port, how is the program going to behave?
Incoming connections won't succeed so the program will do nothing.
Can an exception be added programmatically to the firewall to open this port?
No idea, but it's a bad idea, see above.

Related

TCP port access and C++

If a program is running on a Linux machine, is there a way for that program to scan for ports that are allowed through the firewall? for example, if a programmer wants to make a chat system, but the program needs to know what ports aren't being refused access to incoming connections by a user's firewall, is there a way to check for this in your code? A program may not fail to bind a socket to a port even if the firewall is blocking that same port from incoming connections. Is there a way to check for open firewall ports?
Sidenote: This is purely for educational purposes and free of bad intentions, to be clear I am writing a chat system, and during testing, I was unable to connect desktop->laptop until I manually opened a port via allowing it through my firewall. This seemed a bit off to me, and unlike something that a programmer's code should require a user to do. Not to mention I don't want to leave the few people using this code at risk (if leaving a port permanently open does so). So It seems like I would be better suited finding a way to utilize ports that are already open to incoming TCP connections.
sidesidenote: all clients are running fedora
You have stumbled onto the second biggest issue governing the creation of new Internet applications nowadays. The first biggest of course is NAT, which is a strongly related issue (and hopefully going away eventually because of IPv6).
And there is no easy answer. One good answer is UPnP, but that's not an easy answer, and by no means universal. My network doesn't run it.
Another answer is to somehow tunnel everything you do over https (or http if you must). But that's a huge pain for something like a chat application.

How do I check if a TCP port is already being listened on?

I have a third party library that acts as a HTTP server. I pass it an address and port, which it then uses to listen for incoming connections. This library listens in such a way that it doesn't receive exclusive usage of the port and address it's bound to. As a result, I can listen on the same port multiple times.
I need to run multiple instances of this HTTP server in the same process. Each instance has a default port, but if that port isn't available, it should use the next available port. This is where my problem is; I can end up with two HTTP servers listening on the same port.
I cannot change the HTTP server's code and the HTTP server will not alert me if it cannot listen on the port I give it, so I have to be able to check if a port is already in use before starting each HTTP server. I have tried checking if a port is already being listened on by binding my own socket with SO_REUSEADDR set to FALSE and SO_EXCLUSIVEADDRUSE set to TRUE, but the bind and listen calls both succeed when an existing HTTP server is already listening on that port.
How is this HTTP server achieving this effect, and how can I accurately check if a port is being listened on in this manner?
The quick and dirty method would be to try to connect() to the port on localhost. If the connect() call succeeds, then you know the port is currently being listened on (by whomever received the connection). If the connect call fails (in particular with ECONNREFUSED) then you can be pretty sure that nobody is listening on that port.
Of course, there's a race condition here: Nothing is really stopping another program from swooping in and grabbing the port immediately after you ran the above test, but before you get around to binding to the port yourself. So you should take the result of the test as more of a hint than an absolute rule, and (hopefully) have some way of handling it if you later find out that the port is in use after all.
Use a port number of 0. The OS will pick a free port.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx explains how the different options interact.
You haven't given us nearly enough information to tell us exactly what's going on in your use case, but I can work through one arbitrary use case that would look like what you're seeing.
Let's say you're on Win 2003 or later, and your primary NIC is 10.0.0.1, and everything is running under the same user account.
The first instance of your app comes up, and your test code tries to bind 10.0.0.1:12345 with SO_EXCLUSIVEADDREUSE. Of course this works.
You close the socket, then tell the HTTP server to listen to port 12345. It binds 0.0.0.0:12345 with SO_REUSEADDR, which of course works.
Now a second instance of your app comes up, and your test code tries to bind 10.0.0.1:12345 with SO_EXCLUSIVEADDREUSE. According to the chart in the MSDN article, that works.
You close the socket, then tell the HTTP server to listen to port 12345. It binds 0.0.0.0:12345 with SO_REUSEADDR, which works.
If this is the problem, assuming you can't get the HTTP server to bind a specific address, you can solve things by using 0.0.0.0 in your test code. (Of course if it's one of the other hundreds of possible problems, that solution won't work.)
If you don't know what socket options, address, etc. the HTTP server is using, and don't have the source, just run it in the debugger and breakpoint the relevant calls.

Checking open UDP Port in C++

How can I check if a remote UDP port is open by using native C++? Since UDP is connection-less, calling connect() is not helpful. I cannot try binding it since it is not local. nmap cannot also indicate. (however netstat can find out, but I think it looks at internal information about open ports/files). Is there anyway to detect it? If I go a layer down on network level, is it possible to send a ICMP message by C++ to check port-unreachable status? I mean, would that give enough information on port status?
Platform is Linux.
I assume that you are trying to determine whether or not a UDP port on a remote machine is being passed through a firewall and/or has an application running on it.
You cannot reliably determine this. The closest you can come is to try sending a series of small datagrams to that address and port, spaced about 1 second apart for about 10 seconds.
If there are no firewalls blocking the port and no application is running, then the remote system might send back ICMP_UNREACH_PORT (port unreachable). If there are no blocking firewalls and the remote system is down, a router might send back ICMP_UNREACH_HOST or ICMP_UNREACH_NET. If a firewall is blocking you, it might send back ICMP_UNREACH_FILTER_PROHIB, but most firewalls don't send back anything.
The odds of getting any of those back are pretty slim because most firewalls block that sort of ICMP feedback. Even if an ICMP message does come back, linux generally does not let you see it unless you are running as root. Some operating systems will report ICMP errors as a failure of the next sendto() to the same address/port, which is why you need to repeat the message several times. But some do not, in which case you must open a specific ICMP port and parse any return messages.
Even if you do somehow get an ICMP message, understand that they are not reliable. For example, you could get ICMP_UNREACH_PORT even though an application is not only listening, but actively sending you data. (That's rare, but I've seen it happen.)
If an application is running on the given port and if you know what that application is and if you know how to craft a message which will cause that application to respond to you, then doing so and getting a response is the best indication that the port is open. But getting no response means nothing: maybe the port is blocked, maybe the application is not running, or maybe it just didn't like your message.
Bottom line: no, not really.
There is no bulletproof way to check if a remote port is ready to receive your UDP datagrams. Since UDP is connectionless you can just tell if the remote host is answering something meaningful to you. There may be ways to get an hint (as port scanners do) but that is nothing I would rely on in production code.

C/C++ detect network type

I need to write a win32 c/c++ application which will be able to determine whether the PC it's running on is connected to one of 2 networks. The first network is the company LAN (which has no internet connection) and the second network is a standalone switch with a single PC connected to it (the PC that the program is running on).
I'm pretty new to network programming but so far I have tried testing to see if a network drive which is held on our LAN can be mapped. This works fine if the PC is connected to the LAN, the drive mapping succeeds so so LAN detection is successful. However, if the PC is connected to the switch, this results in a VERY long timeout which is not a suitable as it will delay the program so much as to make it unusable.
Does anyone have any alternative suggestions?
I'm using c/c++ in VS 6.0
[Update]
Whilst trying a few different ideas and looking at some of the suggestions below I thought I should update with some additional information as many (if not all) of the suggestions I don't think will work.
(1) The aforementioned LAN has no external connections at all, it is completely isolated so no resolving of external DNS or pinging websites is possible.
(2) Hostname, MAC address, IP, Default Gateway, Subnet etc etc (basically everything you see in ipconfig -all) are all manually configured (not dynamic from the router) so checking any of these settings will return the same whether connected to the LAN or the switch.
(3) Due to point (2), any attempts to communicate with the switch seem to be unsuccessful, in fact almost all networking commands (ping, arp etc) seem to fail - I think due to the machine trying to connect to the LAN when it isn't there :-(
One thing I have found which works is pinging the default gateway IP which times out when connected to the switch. This is sort of ok as I can reduce the timeout of ping so it doesn't just hang for ages but it feels like a bit of a hack and I would certainly appreciate any better solutions.
Thanks
As far as TCP/IP is concerned there is no such thing as a LAN on WAN. There are a set of non-internet routable addresses like 192.168.x.x and 10.x.x.x but these are sometimes used by ISP short of IP addresses.
You best bet is to use Asynchronous APIs when making TCP/IP connections. WIN32 defines a whole buch of OVERLAPPED APIs for this purpose. This will prevent your application from grinding to a halt while waiting for a remote connection.
Alternatively put the socket stuff into another thread and then only notify the UI when the operation is done.
I would first try to differentiate between the two using information available locally--that is, from your computer. Does the output of ipconfig /all differ depending on which network you're connected to? If so, exploit that difference if you can.
Is it possible to get the MAC address of the standalone switch? Of the switch that controls the company LAN? That would be a sure way to tell. Unless somebody cloned the MAC address.
If you try using the existence or non-existence of some network service to determine which network you're connected to, you can never be sure. For example, if you failed to map that network drive, all you know is that the network drive isn't available. You can't say for certain that you're not connected to the company LAN. Same is true if you use ping. Lack of response from a particular machine means only that the machine didn't respond.
Various things you can look at for differentiation:
DNS domain name (GetComputerNameEx)
MAC address of gateway (ping it, then GetIpNetTable)
Routing table(do you have a gateway and default route on the company LAN)
WNet discovered network resources (WNetOpenEnum, WNetEnumResource)
Ability to resolve external hostnames (try a 5-10 names like www.google.com, www.microsoft.com and so on, if one resolves you should have internet)
You'll have to decide how many indicators are "enough" to decide you're on one or the other LAN though if tests fail. Then keep retrying until you have a definite result.
http://msdn.microsoft.com/en-us/library/aa366071%28v=VS.85%29.aspx has a lot of network related functions that you can experiment with to create further indicators.

TCP simultaneous open and self connect prevention

TCP standard has "simultaneous open" feature.
The implication of the feature, client trying to connect to local port, when the port is from ephemeral range, can occasionally connect to itself (see here).
So client think it's connected to server, while it actually connected to itself. From other side, server can not open its server port, since it's occupied/stolen by client.
I'm using RHEL 5.3 and my clients constantly tries to connect to local server.
Eventually client connects to itself.
I want to prevent the situation. I see two possible solutions to the problem:
Don't use ephemeral ports for server ports.
Agree ephemeral port range and configure it on your machines (see ephemeral range)
Check connect() as somebody propose here.
What do you thinks?
How do you handle the issue?
P.S. 1
Except of the solution, which I obviously looking for,
I'd like you to share your real life experience with the problem.
When I found the cause of the problem, I was "astonished" on my work place people are not familiar with it. Polling server by connecting it periodically is IMHO common practice,
so how it's that the problem is not commonly known.
When I stumbled into this I was flabbergasted. I could figure out that the outgoing
port number accidentally matches the incoming port number, but not why the TCP
handshake (SYN SYN-ACK ACK) would succeed (ask yourself: who is sending the ACK if
there is nobody doing a listen() and accept()???)
Both Linux and FreeBSD show this behavior.
Anyway, one solution is to stay out of the high range of port numbers for servers.
I noticed that Darwin side-steps this issue by not allowing the outgoing port
to be the same as the destination port. They must have been bitten by this as well...
An easy way to show this effect is as follows:
while true
do
telnet 127.0.0.1 50000
done
And wait for a minute or so and you will be chatting with yourself...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello?
hello?
Anyway, it makes good job interview material.
Bind the client socket to port 0 (system assigns), check the system assigned port, if it matches the local server port you already know the server is down and and can skip connect().
For server you need to bind() socket to port. Once addr:port pair had socket bound, it will no longer be used for implicit binding in connect().
No problem, no trouble.
Note that this solution is theoretical and I have not tested it on my own. I've not experienced it before (or did not realize) and hopefully I won't experience it anymore.
I'm assuming that you cannot edit neither the client source code nor the server source. Additionally I'm assuming the real problem is the server which cannot start.
Launch the server with a starter application. If the target port that the server will bind is being used by any process, create an RST (reset packet) by using raw sockets.
The post below briefly describes what an RST packet is (taken from http://forum.soft32.com/linux/killing-socket-connection-cmdline-ftopict473059.html)
You have to look at a "raw socket" packet generator.
And you have to be superuser.
You probably need a network sniffer as well.
http://en.wikipedia.org/wiki/Raw_socket
http://kerneltrap.org/node/3072 - TCP RST attacks
http://search.cpan.org/dist/Net-RawIP/lib/Net/RawIP.pm - a Perl module
http://mixter.void.ru/rawip.html - raw IP in C
In the C version, you want a TH_RST packet.
RST is designed to handle the following case.
A and B establish a connection.
B reboots, and forgets about this.
A sends a packet to B to port X from port Y.
B sends a RST packet back, saying "what are you talking about? I don't
have a connection with you. Please close this connection down."
So you have to know/fake the IP address of B, and know both ports X
and Y. One of the ports will be the well known port number. The other
you have to find out. I thnk you also need to know the sequence
number.
Typically people do this with a sniffer. You could use a switch with a
packet mirroring function, or run a sniffer on either host A or B.
As a note, Comcast did this to disable P2P traffic.
http://www.eff.org/wp/packet-forgery-isps-report-comcast-affair
In our case we don't need to use a sniffer since we know the information below:
So you have to know/fake the IP address of B, and know both ports X
and Y
X = Y and B's IP address is localhost
Tutorial on http://mixter.void.ru/rawip.html describes how to use Raw Sockets.
NOTE that any other process on the system might also steal our target port from ephemeral pool. (e.g. Mozilla Firefox) This solution will not work on this type of connections since X != Y B's IP address is not localhost but something like 192.168.1.43 on eth0. In this case you might use netstat to retrieve X, Y and B's IP address and then create a RST packet accordingly.
Hmm, that is an odd problem. If you have a client / server on the same machine and it will always be on the same machine perhaps shared memory or a Unix domain socket or some other form of IPC is a better choice.
Other options would be to run the server on a fixed port and the client on a fixed source port. Say, the server runs on 5000 and the client runs on 5001. You do have the issue of binding to either of these if something else is bound to them.
You could run the server on an even port number and force the client to an odd port number. Pick a random number in the ephemeral range, OR it with 1, and then call bind() with that. If bind() fails with EADDRINUSE then pick a different odd port number and try again.
This option isn't actually implemented in most TCPs. Do you have an actual problem?
That's an interesting issue! If you're mostly concerned that your server is running, you could always implement a heartbeat mechanism in the server itself to report status to another process. Or you could write a script to check and see if your server process is running.
If you're concerned more about the actual connection to the server being available, I'd suggest moving your client to a different machine. This way you can verify that your server at least has some network connectivity.
In my opinion, this is a bug in the TCP spec; listening sockets shouldn't be able to send unsolicited SYNs, and receiving a SYN (rather than a SYN+ACK) after you've sent one should be illegal and result in a reset, which would quickly let the client close the unluckily-chosen local port. But nobody asked for my opinion ;)
As you say, the obvious answer is not to listen in the ephemeral port range. Another solution, if you know you'll be connecting to a local machine, is to design your protocol so that the server sends the first message, and have a short timeout on the client side for receiving that message.
The actual problem you are having seems to be that while the server is down, something else can use the ephemeral port you expect for your server as the source port for an outgoing connection. The detail of how that happens is separate to the actual problem, and it can happen in ways other than the way you describe.
The solution to that problem is to set SO_REUSEADDR on the socket. That will let you create a server on a port that has a current outgoing connection.
If you really care about that port number, you can use operating specific methods to stop it being allocated as an ephemeral port.