  Using the TCP/IP stack

To start the TCP/IP stack, run TCP.EXE without
arguments.

To unload the TCP/IP stack, run TCP.EXE with
  /UNLOAD
as the only argument.

  How to use the TCP services in your own programs

This TCP/IP stack works using software interrupts.
It has the following commands:

  (AX = 0) Service

Reads raw packets from the incoming packet buffer, parses
them and writes the data to the corresponding sockets
read buffers. Sends all data that is waiting in sockets
write buffers.

  (AX = 1) Connect

DS:SI = pointer to DNS or IP address
BX = port
CX = udp socket (0 if tcp)

Resolves DNS and creates a socket. Returns the socket
descriptor to AX, or -1 if an error happened. Note that
the socket is not usable before the server responds to the
SYN by sending ACK. Writing or reading from a socket that
is not ready sets an error code. This function must be called in a loop
with the same arguments until it returns something else than -1.

Possible errors:
ENOTCONN       a DNS request is not yet answered - call this function again
               until this error goes away.

ENOMEM         not enough resources to create a new socket.

HOST_NOT_FOUND the DNS server responded with an error.


  (AX = 2) Read

BX = socket descriptor
ES:DX = pointer to destination buffer
CX = count of bytes to read

Reads from the socket. Returns the count of the bytes
that were read, or -1 if an error happened.


  (AX = 3) Write

BX = socket descriptor
ES:DX = pointer to source buffer
CX = count of bytes to read

Writes to the socket. Returns the count of the written
bytes, or -1 if an error happened.

  (AX = 4) Close socket

BX = socket descriptor

Closes the socket. Returns -1 if an error happened. Normally returns 0.

  (AX = 5) Open port

BX = port
CX = udp (0 if tcp)

Opens a port. Returns a special socket descriptor in AX.
Reading the descriptor returns 0 if the port has no incoming
connections. If the port has an incoming connection, the new socket
descriptor has to be extracted by reading at least two bytes at a time.
The read returns the socket descriptor of an accepted connection to the
buffer as a little-endian integer.

The port can be closed by calling the close function with the port's
socket descriptor.

  (AX = 6) Get error code
  
Returns the last error code to AX. The error code is zeroed after that.
The error codes are defined in the ERRDEF.C file.

  (AX = 7) Check that a socket exist

BX = socket descriptor

Returns 0 if the socket still exists, and -1 if the remote end has closed
the connection.

  (AX = 8) Check socket status

BX = socket descriptor

Return values:

0: Handshake
1: Established
2: Waiting for ACK
3: Closing or closed
-1: The socket does not exist

With UDP sockets this function always returns 1.

  (AX = 9) New socket

BX = protocol (0: ipv4, 1: ipv6)
CX = type (0: tcp, 1: udp)

Creates a new socket. Returns the socket descriptor
or -1 if an error happened.

  (AX = 10) Bind socket

BX = socket descriptor
ES:DX = pointer to a sockaddr struct containing local address
CX = address length

Binds the socket to a local port. Returns -1 if
an error happened. Normally returns 0.

  (AX = 11) BSD-style connect()

BX = socket descriptor
ES:DX = pointer to a sockaddr struct containing remote address

Connects the socket to the address in the sockaddr struct.
Returns -1 if an error happened. Normally returns 0.
This function is always non-blocking. Use function 8 to detect when the
socket is ready.

  (AX = 12) getpeername
  (AX = 28) getsockname

BX = socket descriptor
ES:DX = pointer to a sockaddr struct
CX = max length of buffer

Returns the peer/local name and remote/local port of a socket to the sockaddr
struct.  Returns -1 to the AX register if an error happened. If the value in
the CX register was too small to fit the sockaddr struct, returns the minimum
length to fit the struct to AX. Returns 0 to AX when the call was successful.

  (AX = 24) Check send state

Returns 1 if the packet driver supports asynchronic sends and the send
buffers are full. Otherwise this call returns 0. This can be used in
applications that support high-performance networking I/O to prevent getting
"stuck" in blocking send_pkt calls.

  (AX = 25) Set idle interrupt

Enables the int 28h handler for automatic packet processing.

  (AX = 26) Unset idle interrupt

Disables the int 28h handler.

  (AX = 27) BSD-style listen()

BX = socket descriptor

Makes a listening socket.
