Telnet/ssh connection to network devices and snmp

Hello folks,…

Prolog I can handle. Prolog networking I struggle with, (I have just found)

have looked at many examples and I did try and find solutions and could see a number of client/server{mainly} examples, but after 2 days, im pushing the help button

Objective:

I would like to login to a number of my network devices (switch/routers) to receive and send data/commands.

Ideally I would login and capture output to parse with DCG pio to build information structures to then work with.

(I am also looking at access data via snmp, but again fighting the lack of knowledge of networking, so perhaps another topic. *red herrings.)

Problem(s)

I could connect to my network device, but found that it was saying (via Putty) ‘Account :’ sadly there was no line feed so struggled to simpy get a line when in prolog.

When connecting successfully (char by char) ? and getting characters I found the values were not what I was expecting, having spent ages looking at utf8, text modes etc, I struggle to get anywhere

code and output below (just enough to get me to the problem)

go :-create_client(‘10.12.13.14’, 23).

create_client(Host, Port) :-
tcp_socket(Socket),
tcp_connect(Socket, Host:Port),
tcp_open_socket(Socket, In, _Out),
repeat,
get_byte(In, CODE),
write(CODE),nl,
fail.

results…

?- go.
255
253
24
255
253
32
255
253
35
255
253
39

I investicated Bom’s and FF,FE’s but got nowhere (im ff,fd)
However when using ssh connectivity to the same device, could see a header but then nothing as it most likley went off to the sshland.
So another red herring came (ssh connectivity)

Ideal World

1 - to connect to Telenet and have a simple chat (read_line(s) and respond )
2 - as (1) but ssh, as i dont really want to use telnet on my devices
3 - generate and read an snmp output

Conclusion

I have learnt lots about prolog networking tcp/udp, snmp and ssh
but sadly the number of permuations for a beginner in that field has outwhitted me

Anyone out there that can help or has done this so i can reuse?

prolog_server/2 might be a useful reference (source here).

I know I’ve seen issues with BOM stuff in Prolog when using open/4 (requiring passing in the option bom(false), but I guess that doesn’t apply here.

What input are you expecting to get from the client? You mention ssh; is the connection encrypted?

Thx, have seen this … Really the prolog is the client and my switch the server. I am connecting to the switch, so i can then send login details and then followed by a command, and collect the output, and logout…
so really its like scraping a telnet session Prolog controls…

Ill worry about ssh once simple telnet works

You have two different problems:

  1. Figure out the protocol the switch is using
  2. Parse the protocol using Prolog

I suggest figure out #1 before trying #2
In order to solve #1 I suggest you use wireshark (putty is not really enough with non-ascii characters) to capture the protocol while another client is logging into the switch. After you have the protocol figured out, then code it in prolog.

1 Like

A few generic comments from someone who has done a fair bit of network programming and has the (mental) scars to prove it:

  • netcat is your friend - if you connect to it, you eliminate one variable (the behavior of the remote server). There may be some other, similar, programs that you can use.
  • run your client and server on the same machine in different windows, connecting with 127.0.0.1 (localhost) - eliminates another variable (the network, firewalls, etc.)
  • try to avoid firewalls between your client and server, at least while developing
  • the Stevens TCP books are invaluable, and have some utility programs that can help if netcat doesn’t suffice
  • instead of telnet/ssh, you might see whether the server supports HTTP. Also check what other simple services it might have, to help you determine whether your problem is in the client, network, or server. (e.g, echo, daytime, time: Service Name and Transport Protocol Port Number Registry)
  • wireshark (ethereal) is awesome - you’ll be astounded by all the traffic on your network, and delighted by how wireshark can isolate and display individual connections and “conversations”. tcpdump is an alternative

(The above apply to Linux systems. If you’re on Windows, you have my sympathy)

SNMP is its own weirdness – and sometimes uses UDP instead of TCP. There are utility programs for dealing with it, but I don’t remember the details (it’s been almost 20 years since I’ve had to deal with it).

1 Like

WSL 2

Hmmm … that’s sandboxed but shouldn’t be a problem, although I don’t think it can do X, so you might be limited to tcpdump instead of wireshark - or maybe there are permissioning issues with libpcap under WSL.
I have had problems in the past with NAT being “clever” with incorrectly modifying data inside certain kinds of protocol streams, but that shouldn’t affect telnet and similar; and you’re probably not using NAT anyway.

Are you referring to X Windows.

See: Windows Subsystem for Linux GUI

I have not used this but others have noted they like it.

im digging deeper and wiresharked up - its telnet for sure, so plenty of protocol… and i can see my embedded data, and responces

Cant do ssh on router . can telnet on my machine ‘windows’ so firewalls ok. (but have linux) firewalls not a problem

Going to have to dig deeper … this is networks not prolog so will take time out to hack more - thnks guys… (ill look to see if i can find a tellnet proxy that takes simple stdio ansi.) think the stopper so far is protocol…

Q: could I spawn a local telnet and somehow connect to the stdin and stdout ! then i could do simple ansi

RFC 854 - Telnet Protocol Specification :wink:

People tend to use telnet for both real telnet (login, etc.) and raw connection. For the latter, netcat (nc) is better.
Here’s an example of debugging an HTTP server using netcat: Use netcat instead of telnet for debugging – UNIX fu https://www.redhat.com/sysadmin/telnet-netcat-troubleshooting
and you can find lots of other tutorials in the internets, such as this, which might help you debug your client: Bash/nc: netcat as a simple telnet server · GitHub

2 Likes

Yes, rfc854 is what describes what is going on here, but just to save some time, this whole 255 253 business is telnet’s feature negotiation. Basically the server you’re connecting to is trying to figure out what this client that just connected can actually do, and you’re supposed to reply with that sort of information.

Assuming you’re not interested in building a fully-fledged telnet client, consider calling a telnet client process from prolog instead. Then you can just use input/output to that process as you’d expect, while the telnet client handles all the whacky protocol negotiation stuff.
Have a look at the process library. It lets you open a process in a way that gives you an input stream and an output stream connected to that process, so as long as your telnet client reads from standard input and writes to standard output, you can then use that instead of a direct network connection.

Thank you ALL… much clearer now.

(FYI im hoping to build some code that will take a SNMP dump and parse it to prolog, then build a simple Monitoring/Analysis tool) FYI there is a windows tool(oh dear but use also have linux best of both worlds) that will ‘snmpwalk.exe’ that creates a nice file to parse.

I will be back if i get somewhere… Hopefully with code in hand… - it may take a while as my day job starts!

Great forum

A general pattern I’ve developed after tinkering quite a bit with getting JavaScript browsers to act as clients for SWI-Prolog servers is to use JSON calls and responses.

The basic idea is the browser sends JSON which looks something like this

{"cmd":  "some command name", "arg1": "whatever arg 1 is", ....} 

The prolog server code looks like this:

:- use_module([ library(http/http_unix_daemon)
              , library(http/http_server)
              ]).

:- http_handler(/, cmd_handler, []).

cmd_handler(Request) :-
  http_read_json_dict(Request, DictIn),
  cmd_manager(DictIn.cmd, DictIn, DictOut),
  reply_json_dict(DictOut).

cmd_manager("some command name", DictIn, DictOut}) :-
  % manipulate DictIn.arg1 etc to produce DictOut
  ....

This is accessed from the browser by JavaScript along these lines;

function foo(event) {
  fetch('/cmd', { method: 'POST'
                , headers: {"Content-Type": "application/json"}
                , body: JSON.stringify({ "cmd": "some command name"
                                       , "arg1": "whatever arg1 is"
                                       ...
                                       })
                     })
	            .then(response => response.json())
                .then(data => ... manipulate the return JSON values ....);
}

A newby mistake I originally made was to use SWI Prolog as the root http server serving entire HTML documents, when all I really wanted were little JSON dictionary messages going back and forth.

A practical example of the above is a browser based editor I recently mentioned in a different discussion at at Is there a Prolog mode for CodeMirror?

The above basic framework is very easy to extend. The text editor I started on a few days ago already has a shell commandline, file navigator…

I don’t think that is generally valid. The SWI-Prolog HTML infrastructure is quite good at generating HTML from data. It is not good at dealing with large and mostly static pages with a few dynamic elements. Completely static pages is fine again. Also generating the overall page for JavaScript based dynamic sites are fine (an HTML skeleton, CSS and JavaScript dependencies).

1 Like

I didn’t mean that as a criticism of SWI-Prolog’s HTML generating abilities. It’s just a generally good tip for any web application framework as pointed out in the Nginx documentation Pitfalls and Common Mistakes | NGINX

Keeping html files html, css css etc helps with syntax highlighting for starters.

That’s essentially the mechanism I use in GitHub - kamahen/swipl-server-js-client: Sample SWI-Prolog server with JavaScript client
I suspect it’d be faster using protobufs or fast_write/2, especially if used over encrypted channels.

If you have static content, it simplifies things to serve that content using the SWI-Prolog HTTP server, to avoid Cross-Origin Resource Sharing (CORS) issues. (There are multiple examples of doing this, including my GitHub - kamahen/swipl-server-js-client: Sample SWI-Prolog server with JavaScript client)

update : well im now well into telnet negotiation protocols :robot: and trying to negotiate with it … well rabit hole here i come,… but making small progress… challenge is blocking on reading codes back from input streams

done 1. now on 2.

1 Like

Another tool that complements netcat, and might help you: socat.