How hard would it be to have an FB program that listens on a TCP port, and returns some status information to the client computer?
Basically, doing something like the Check_MK Agent that listens on port 6556, and non-interactively dumps a text-based stream of information out to it when something connects.
The Linux version of the agent is just a bash script that is generally served using xinetd, but the Windows version is a binary and runs as a service, with code that listens on the port itself.
However, I've found whatever it does can be unreliable on some machines, and fail to return anything. So I'm thinking of writing a small, stand-alone program that intercepts the requests, calls the agent itself, and sends back the output. Would this be easy to do?
How can I listen and serve information over a TCP port? [Windows]
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How can I listen and serve information over a TCP port? [Windows]
Well, the first thing I'd investigate, whould be: "are my assuptions" regardingcounting_pine wrote:However, I've found whatever it does can be unreliable on some machines, and fail to return anything.
the way, the agent is "expected" to react, correct? (may not be the case)
Before that, I'd not even start to look at a possible way, to solve the issue.
In general, security-people tend to have very specific ways of thinking:
- typically, expecting some sort of authentication, from connecting device
(let's call it a security-token or similar, may need to be encrypted, too)
Just my two cents, at the moment.
Re: How can I listen and serve information over a TCP port? [Windows]
If you want to really implement something yourself, have a look at the Winsock documentation (which works quite similar to Unix sockets). You'll also find an example there:
https://docs.microsoft.com/en-us/window ... erver-code
If you want to have a little bit less work take an existing network library for FB that wraps winsock (and unix sockets) like TSNE or SimpleNetwork. There are also others, but I can't remember their names right now.
https://docs.microsoft.com/en-us/window ... erver-code
If you want to have a little bit less work take an existing network library for FB that wraps winsock (and unix sockets) like TSNE or SimpleNetwork. There are also others, but I can't remember their names right now.
Re: How can I listen and serve information over a TCP port? [Windows]
Afaik winsock is not that hard. Simply searching for some C winsock sample and converting it should suffice if you have a winsock2 header. Installing as service is afaik not necessary for ports over 1024.
However the reliability of the existing binary might not be the binary itself, just security software related (firewall/antivirus).
However the reliability of the existing binary might not be the binary itself, just security software related (firewall/antivirus).
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: How can I listen and serve information over a TCP port? [Windows]
Thanks for the suggestions!
I've ported the example Microsoft code:I've tested it with 'telnet localhost 27015', and it works. (It echoes every character as I type).
Now I just have to see if I can adapt this to run the program and return the output to the client. It hopefully shouldn't be too hard.
I've ported the example Microsoft code:
Code: Select all
' https://docs.microsoft.com/en-us/windows/desktop/winsock/complete-server-code
#define WIN32_LEAN_AND_MEAN
#include "win/winsock2.bi"
#include "win/ws2tcpip.bi"
const DEFAULT_BUFLEN = 512
const DEFAULT_PORT = "27015"
dim as WSADATA wsaData
dim as long iResult
dim as SOCKET ListenSocket = INVALID_SOCKET
dim as SOCKET ClientSocket = INVALID_SOCKET
dim as addrinfo ptr result = NULL
dim as addrinfo hints
dim as long iSendResult
dim as ubyte recvbuf(0 to DEFAULT_BUFLEN - 1)
dim as long recvbuflen = DEFAULT_BUFLEN
'' Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), @wsaData)
if iResult <> 0 then
print "WSAStartup failed with error: " & iResult
end 1
end if
ZeroMemory(@hints, sizeof(hints))
with hints
.ai_family = AF_INET
.ai_socktype = SOCK_STREAM
.ai_protocol = IPPROTO_TCP
.ai_flags = AI_PASSIVE
end with
'' Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, @hints, @result)
if iResult <> 0 then
print "getaddrinfo failed with error: " & iResult
WSACleanup()
end 1
end if
'' Create a SOCKET for connecting to server
ListenSocket = socket_(result->ai_family, result->ai_socktype, result->ai_protocol)
if ListenSocket = INVALID_SOCKET then
print "socket failed with error: " & WSAGetLastError()
freeaddrinfo(result)
WSACleanup()
end 1
end if
'' Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, result->ai_addrlen)
if iResult = SOCKET_ERROR then
print "bind failed with error: " & WSAGetLastError()
freeaddrinfo(result)
WSACleanup()
end 1
end if
freeaddrinfo(result)
iResult = listen(ListenSocket, SOMAXCONN)
if iResult = SOCKET_ERROR then
print "listen failed with error: " & WSAGetLastError()
closesocket(ListenSocket)
WSACleanup()
end 1
end if
'' Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL)
if ClientSocket = INVALID_SOCKET then
print "accept failed with error: " & WSAGetLastError()
closesocket(ListenSocket)
WSACleanup()
end 1
end if
'' No longer need server socket
closesocket(ListenSocket)
'' Receive until the peer shuts down the connection
do
iResult = recv(ClientSocket, @recvbuf(0), recvbuflen, 0)
if iResult then
print "Bytes received: " & iResult
'' Echo the buffer back to the sender
iSendResult = send(ClientSocket, @recvbuf(0), iResult, 0)
if iSendResult = SOCKET_ERROR then
print "send failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
end 1
end if
print "Bytes sent: " & iSendResult
elseif iResult = 0 then
print "Connection closing..."
else
print "recv failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
end 1
end if
loop while iResult > 0
'' shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND)
if iResult = SOCKET_ERROR then
print "shutdown failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
end 1
end if
'' cleanup
closesocket(ClientSocket)
WSACleanup()
end 0
Now I just have to see if I can adapt this to run the program and return the output to the client. It hopefully shouldn't be too hard.