QDOS TCP/IP programming in Assembler

Anything QL Software or Programming Related.
Martin_Head
Aurora
Posts: 986
Joined: Tue Dec 17, 2013 1:17 pm

Re: QDOS TCP/IP programming in Assembler

Post by Martin_Head »

XorA wrote:Get yourself a copy of wireshark to install on the PC, this will show you everything that is going on network wise. Its essential tool for debugging network issues.
Thanks, I'll download a copy
tofro wrote:when you use recvfrom (), you need to actually allocate some space for the call to store the address of the sender. It should be empty (it's about to be overwritten by the recvfrom() call anyhow), and have enough space for an IPv4 adress, that is, you must allocate memory for a struct sockaddr_in structure, even if the prototype only asks for a struct sockaddr. If there's not enough space, recvfrom() will complain.
for the sockaddr structure I am using something like (working from memory here)

Code: Select all

sockaddr  dc.w     2                 ;family AF_INET
          dc.w     1002              ;port
          dc.b     172,16,0,15       ;IP address
          dc.l     0
          dc.l     0
With the length of the structure defined as 16 bytes.

Does this look about right?
tofro wrote:Bind the socket to a port (should be otherwise un-used and above at least 1024, better above 5000)
Note with some of the open() keys in combination with a properly formed device name, you can actually do both of the above steps in one
This is one of my vague areas, I'm not entirely sure I am opening the channel correctly. When you give the "host:port" is it always "the other computers IP address:other computers port", or does it have different meanings between TCP_ and UDP_?

If it's any help to you this is the documentation I am using for IP_OPEN

Code: Select all

IP_OPEN		TRAP#2		D0=1

Opens a channel.

	Input

	D1 = Job ID
	D3 = code where bit:
	         0 = creates a socket of requested type/protocol. 
            1 = TCP and UDP. host and port must be specified. Opens a
                connection TCP, or sets peer address for UDP sockets.  
                Returns without error if connection can't be completed within
                1-2/50s, internally the connection buildup continues. Every i/o  
                operation will be blocked until the connection succeeds or fails. 
	         2 = bind TCP or UDP socket to an address. Such sockets 
                can be used for accepting incoming connections.
	        Channel ID = SCK only. accpet connection for socket
                specified by channel_id.  Returns error if can't complete
                immediately.
            A0 = Address of channel name

	Output

	D0 = result (0 if OK)
	D1 = Job ID
	A0 = channel ID


Martin


User avatar
XorA
Site Admin
Posts: 1665
Joined: Thu Jun 02, 2011 11:31 am
Location: Shotts, North Lanarkshire, Scotland, UK

Re: QDOS TCP/IP programming in Assembler

Post by XorA »

Paul wrote:
XorA wrote:QL can easily handle HTML

SSL requirement for email however will be the killer!

G
In order to be still able to email on our ZX81s after the last provider made SSL mandantory a friend installed a relay server that "translates" our connections to ssl connections (or did he implement a mail server without SSL?). Anyway, I'm not an expert on those things, we are using text based email on our ZX81s happily without SSL.
Kind regards
Paul
Probably a variation on stunnel which can run in client or server mode. If you were going this route I would suggest the ideal for QL would be a small ARM board connected to a Hermes to act as a PPP/SLIP->Ethernet converter with the appropriate logic to startup SSL tunnels as needed. A Pi or Beaglebone type device is ideal.

An enterprising QL user could probably find another million uses for that sort of setup too. In theory a BBB could emulate a microdrive using the PRU.


User avatar
dex
Gold Card
Posts: 312
Joined: Thu Dec 23, 2010 1:40 pm

Re: QDOS TCP/IP programming in Assembler

Post by dex »

Image

My further software development is paused due to insuficienct time. :(
But SSL secured connection will be no problem, as this box itself can handle secured protocols (SSL3/TLS1, HTTPS, FTPS).

The point is:
If we all want to have some solution to access the Internet on the QL, we are supposed to have unique common solution, the same for all.
Otherwise we will be broken into more groups with incompatible internet hardware and obviously different software solution and applications.


User avatar
tofro
Font of All Knowledge
Posts: 3146
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QDOS TCP/IP programming in Assembler

Post by tofro »

Martin_Head wrote: for the sockaddr structure I am using something like (working from memory here)

Martin,

all of what you're doing doesn't look wrong.
You might want to use a port # above 1024, though (although I'm pretty sure that doesn't matter on Windows)

But, according to your experiments, I have come back to fiddle around with TCP/IP and C on QPC2 and, alas, I can't get UDP P2P networking to work with recvfrom() and sendto() either, even from C on QPC2. With apparently correct programs that work properly on other platforms (uqlx and Linux).
TCP seems to work alright though. Will need to give it some more thought and investigation.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Martin_Head
Aurora
Posts: 986
Joined: Tue Dec 17, 2013 1:17 pm

Re: QDOS TCP/IP programming in Assembler

Post by Martin_Head »

tofro wrote:But, according to your experiments, I have come back to fiddle around with TCP/IP and C on QPC2 and, alas, I can't get UDP P2P networking to work with recvfrom() and sendto() either, even from C on QPC2. With apparently correct programs that work properly on other platforms (uqlx and Linux).
TCP seems to work alright though. Will need to give it some more thought and investigation.

Tobias
Ah, maybe it's not me then....

The documentation I am working from by Richard Zidlicky does state that "UDP does not work from BASIC". I don't know why he states that, unless he means that the standard QDOS I/O Traps like IO_FSTRG only work with TCP_ connections.

Martin


User avatar
tofro
Font of All Knowledge
Posts: 3146
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QDOS TCP/IP programming in Assembler

Post by tofro »

Martin_Head wrote: The documentation I am working from by Richard Zidlicky does state that "UDP does not work from BASIC".
I guess what this meant to say is there is no way to hand over the two additional parameters that sendto() needs (address and address length) over io_sstrg() directly from S*BASIC (i.e. without someone writing a proper toolkit routine).

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Martin_Head
Aurora
Posts: 986
Joined: Tue Dec 17, 2013 1:17 pm

Re: QDOS TCP/IP programming in Assembler

Post by Martin_Head »

I've put together a little demonstration of using the QDOS IP driver to access the Windows default printer from within QPC2.

It is a two part program, One a QDOS device driver, the other a Windows Visual Basic program.

The QDOS driver sends the printer output to the Windows program, which then sends it to the default Windows printer.

It is a very simple, no frills, program. I have included the Windows and QDOS source codes.

It can be downloaded here http://www31.zippyshare.com/v/xFnrFf9Q/file.html

Martin


Martin_Head
Aurora
Posts: 986
Joined: Tue Dec 17, 2013 1:17 pm

Re: QDOS TCP/IP programming in Assembler

Post by Martin_Head »

I was wondering if any of the Network experts here could help me with a problem.

I have written in assembler a simple client/server chat program using the IP drivers.

If I run it on one machine, with 2 copies of QPC2 loaded, and telling the client to use IP address 127.0.0.1. It works fine.

However if I try to use two computers on a local network, the client side fails with an error 61 (ENODATA No data available) when the 'Connect' system call is executed.

The connection type is TCP, the server is running on a Windows XP system, the client is running on a Windows 8 system. And the server's IP address is 172.16.0.6.

If I 'ping' 172.16.0.6 on the client machine, I get the expected response's, so I know that the client can see the server OK.

If I trace through the client program, everything seems to get set up correctly for the 'connect' system call.

I have tried switching off the Firewall on the Windows 8 machine, but that made no difference.

Before I spend a lot of time chasing this, is it something in Windows that is blocking me? Something that I just need to turn on or off? Something like, I need to allow TCP connections or a particular port, over the local network.
.
.
.
While typing this, a thought has occurred to me. The server program 'binds' the socket it creates to IP address 127.0.0.1 and port 10000.

As I understand it, this is the local host IP address. Is it effectively the same as the actual IP address of 172.16.0.6 ?

Is the client trying to connect to 172.16.0.6, but the server is using 127.0.0.1, and they are not actually the same?


Thanks in advance...

Martin Head


User avatar
tofro
Font of All Knowledge
Posts: 3146
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QDOS TCP/IP programming in Assembler

Post by tofro »

Martyn,

One first caveat. On the server side, you decide with the bind() call which address (or rather, which hardware interface) the server will be listening to:
0.0.0.0 (INADDRESS_ANY) means "don't care", it will actually listen to all packets on all interfaces, provided the destinantion port is yours
anything else (i.e. any other IP address, will filter the potential traffic on the interface that is bound to that IP address, so
"127.0.0.1" will only listen on the loopback interface. <your-real-ip-address> only on that specific ethernet port bound to that address. You thus probably want to use INADDRESS_ANY (0.0.0.0, best option) or "255.255.255.255" which on most systems behaves the same.

A very useful tool to debug networking problems (in case they are TCP) is telnet.

Have your server run and do a telnet (or rather "c:\Windows\System32\telnet.exe") on the client machine with the IP address of the server and the port as arguments. If the server is properly bound to that address and reachable from the client computer, telnet will happily connect and wait for keyboard input. If not, it will complain with (hopefully) some further hint. Try that first. (If your server accepts ASCII input, you can even simulate your client with the keyboard)

Another important command is "netstat". Use that on the server side to find out address details of the socket your server is bound to. Used without arguments, it would list IP addresses and port numbers of sockets open on your machine and their connection status. Find your port number, you should then see what address your server socket is actually bound - and thus listening - to.

Hope this helps,
Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
martyn_hill
QL Wafer Drive
Posts: 1117
Joined: Sat Oct 25, 2014 9:53 am

Re: QDOS TCP/IP programming in Assembler

Post by martyn_hill »

Hi Martin

Just to add to Tobias' response and in direct answer to your last question - 127.0.0.1 (local/loopback) is definitely NOT the same entity as the IP of the NIC. Binding to the loopback IP will ONLY see traffic sent from local sockets (to the loopback).

IIRC, ANY IP starting with 127 will be treated similarly.

In fact, any mature network stack (whether on Win, Unix, BSD etc) will simply drop any packets inbound (through the NIC, for example) where the destination IP is the local/loopback IP. Equally, a host will filter-out packets destined for the loopback address and never let them out 'on the wire.' That's usually taken care of by the TCP/IP stack itself before a FW comes in to play.

Probably clear by now, for your server to receive packets, it would need to be bound to either (ANY) or else (one of) the NIC IP(s), and the client send to that same IP.

:-)


Post Reply