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.