Jump to content

TCPIPDLL.LIB

From EDM2

TCPIPDLL.LIB is the import library for the IBM TCP/IP for OS/2 BSD Sockets layer, distributed with the IBM OS/2 Developer's Toolkit. It provides linker stubs for the Berkeley Sockets API and companion networking functions implemented by TCPIPDLL.DLL, the core socket runtime shipped with IBM TCP/IP for OS/2 and integrated into OS/2 Warp 3 and later.

File size in the OS/2 Warp 4.52 Toolkit 4.5: 9,216 bytes (2000-10-16). Source DLL: TCPIPDLL.DLL.

Symbols are exported with a leading underscore following the EMX/GCC OMF naming convention. C programs compiled with EMX or IBM VisualAge C++ call these functions by their standard BSD names (e.g. accept); the compiler automatically prepends the underscore, and the import library resolves the reference to the corresponding export in TCPIPDLL.DLL.

Architecture

IBM TCP/IP for OS/2 is a dual-model stack:

Component DLL Purpose
BSD Sockets API TCPIPDLL.DLL (this library) Application-level sockets; streams (TCP), datagrams (UDP), raw sockets
NetBIOS NETAPI.DLL LAN-Manager NetBIOS interface (separate library)
RPC runtime RPCSDK.LIB / RPC*.DLL OS/2 ONC RPC client/server (separate toolkit)
SNMP SNMPAPI.LIB / SNMP.DLL SNMP manager/agent API (separate toolkit)

TCPIPDLL.DLL runs as a DLL in the application process. It communicates with the TCP/IP kernel driver (INET.SYS) and related protocol drivers (TCP.SYS, UDP.SYS) via device driver IOCTLs on the \DEV\SOCKET$ device.

API Groups

Socket Lifecycle

_socket(domain, type, protocol)
Creates an endpoint for communication. Returns a socket descriptor (integer) on success, -1 on error. domain is the protocol family:
  • AF_INET (2) — IPv4
  • AF_UNIX (1) — Unix-domain sockets (local IPC, limited support)
type is the socket type:
  • SOCK_STREAM (1) — reliable byte stream (TCP)
  • SOCK_DGRAM (2) — unreliable datagram (UDP)
  • SOCK_RAW (3) — raw protocol access
protocol is the protocol number (0 = default for type).
_soclose(socket)
Closes a socket descriptor, flushing any pending data and releasing resources. OS/2-specific name for the BSD close() on socket descriptors. Using the standard C close() on a socket descriptor does not work; soclose() must be used.
_soabort(socket)
Immediately aborts a socket connection, discarding any buffered data. Sends a TCP RST on connected TCP sockets.
_shutdown(socket, how)
Disables send (SHUT_WR), receive (SHUT_RD), or both (SHUT_RDWR) directions of a socket without closing the descriptor. Used for half-close of TCP connections.

Address Binding and Connection

_bind(socket, addr, addrlen)
Assigns a local address and port to a socket. addr is a pointer to a struct sockaddr_in for IPv4. Required before listen(); optional before connect() (OS assigns an ephemeral port if not called).
_listen(socket, backlog)
Marks a stream socket as passive (ready to accept incoming connections). backlog specifies the maximum queue depth of pending unaccepted connections.
_accept(socket, addr, addrlen)
Extracts the first connection from the listening queue and returns a new socket descriptor for that connection. addr and addrlen are filled with the remote address.
_connect(socket, addr, addrlen)
Initiates a connection on a stream socket (SOCK_STREAM), or sets the default destination address on a datagram socket (SOCK_DGRAM).
_getpeername(socket, addr, addrlen)
Returns the address of the peer to which the socket is connected.
_getsockname(socket, addr, addrlen)
Returns the locally bound address of the socket.

Data Transfer

_send(socket, buf, len, flags)
Sends data on a connected socket. flags: MSG_OOB (out-of-band data), MSG_DONTROUTE.
_recv(socket, buf, len, flags)
Receives data from a connected socket. flags: MSG_OOB, MSG_PEEK (peek without consuming), MSG_WAITALL.
_sendto(socket, buf, len, flags, to, tolen)
Sends a datagram to a specified remote address. Used with SOCK_DGRAM or SOCK_RAW.
_recvfrom(socket, buf, len, flags, from, fromlen)
Receives a datagram, filling from with the sender's address.
_sendmsg(socket, msg, flags)
Sends a message described by a struct msghdr, supporting scatter/gather I/O and ancillary (control) data.
_recvmsg(socket, msg, flags)
Receives a message into a struct msghdr. Supports scatter/gather I/O buffers and optional ancillary data (e.g. IP_RECVDSTADDR, timestamping).
_readv(socket, iov, iovcount)
Scatter-read: reads data from the socket into iovcount non-contiguous buffers described by struct iovec iov[].
_writev(socket, iov, iovcount)
Gather-write: sends data from iovcount non-contiguous buffers.

Socket Options

_getsockopt(socket, level, optname, optval, optlen)
Queries a socket option. Common level / optname combinations:
Level Option Type Meaning
SOL_SOCKET SO_REUSEADDR int Allow rebind to a port in TIME_WAIT
SOL_SOCKET SO_KEEPALIVE int Enable TCP keepalives
SOL_SOCKET SO_SNDBUF int Send buffer size in bytes
SOL_SOCKET SO_RCVBUF int Receive buffer size in bytes
SOL_SOCKET SO_LINGER struct linger Linger-on-close behavior
SOL_SOCKET SO_ERROR int Pending socket error (read and clear)
SOL_SOCKET SO_TYPE int Socket type (SOCK_STREAM etc.)
SOL_SOCKET SO_BROADCAST int Allow broadcast sends on UDP
IPPROTO_TCP TCP_NODELAY int Disable Nagle algorithm
IPPROTO_IP IP_TTL int Outgoing TTL value
IPPROTO_IP IP_MULTICAST_TTL unsigned char Multicast TTL
IPPROTO_IP IP_ADD_MEMBERSHIP struct ip_mreq Join multicast group
_setsockopt(socket, level, optname, optval, optlen)
Sets a socket option. Same level/option space as getsockopt.

I/O Control and Multiplexing

_ioctl(socket, cmd, data, datalen)
Performs device-control operations on a socket. Key commands:
  • FIONBIO — set non-blocking mode (pass pointer to non-zero int to enable)
  • FIONREAD — query bytes available to read without blocking
  • SIOCGIFCONF — get network interface configuration list
  • SIOCGIFADDR / SIOCSIFADDR — get/set interface address
  • SIOCGIFFLAGS / SIOCSIFFLAGS — get/set interface flags (IFF_UP, IFF_BROADCAST, etc.)
_select(nfds, readfds, writefds, exceptfds, timeout)
Monitors up to nfds socket descriptors for readability, writability, or exceptional conditions. timeout is a struct timeval; NULL means wait indefinitely. Returns the number of descriptors that are ready.
_bsdselect(nfds, readfds, writefds, exceptfds, timeout)
BSD-compatible variant of select(). On OS/2, select() operates on socket descriptors only; bsdselect() is an alias provided for source compatibility.

Socket Cancellation

_so_cancel(socket)
Cancels a blocking socket call on the given socket descriptor from another thread. Posts a cancel to any thread currently blocked in recv, send, accept, connect, or select on that socket.
_sock_cancel(tid)
Cancels a blocking socket call by target thread ID. Useful when the caller knows the thread but not the socket.

Initialization and Cleanup

_sock_init()
Initializes the TCPIPDLL socket library for the current process. Must be called once before any other socket function. Sets up the per-process socket table and connects to the kernel INET.SYS driver. Returns 0 on success.
_sock_term()
Shuts down the socket library, closing all open sockets for the current process and releasing all resources. Typically called at program exit.
_addsockettolist(socket) / _removesocketfromlist(socket) / _cleanupsockets()
Internal socket-list management functions used to track open descriptors across DLL unloads and process termination. Not normally called directly by applications.

Host Database (gethostbyname / DNS)

_gethostbyname(name)
Looks up a hostname and returns a pointer to a struct hostent containing the hostname, aliases, address type (AF_INET), and list of IPv4 addresses. Consults the local hosts file (%ETC%\HOSTS), then the DNS resolver.
_gethostbyaddr(addr, len, type)
Reverse-resolves an IPv4 address (passed as a pointer to a struct in_addr) to a hostname via reverse DNS (PTR lookup) or the local hosts file.
_gethostent() / _sethostent(stayopen) / _endhostent()
Sequential enumeration of the local hosts file. sethostent(1) keeps the file open between calls; endhostent() closes it.
_gethostid()
Returns the primary IPv4 address of the local host as an unsigned long.
_sethostfile(path)
Overrides the default path of the local hosts file (normally %ETC%\HOSTS) for the current process.
_hostalias(name)
Looks up name in the local hosts aliases file (%ETC%\HOSTS alias entries). Returns the canonical name, or NULL if no alias is found.
_getinetversion(buf, buflen)
Returns the IBM TCP/IP stack version string (e.g. "IBM TCP/IP for OS/2 4.1") into buf.

Internal Host Table Functions

The double-underscore functions access the in-process parsed host table cache:

__gethtbyname, __gethtbyaddr, __gethtent, __sethtent, __endhtent, __host_file

These are used internally by gethostbyname / gethostbyaddr when the hosts file is read before a DNS query. They are not part of the public API.

Network Database

_getnetbyname(name) / _getnetbyaddr(net, type)
Look up a network by name or numeric address in %ETC%\NETWORKS. Return a pointer to a struct netent.
_getnetent() / _setnetent(stayopen) / _endnetent()
Sequential enumeration of the networks file.

Protocol Database

_getprotobyname(name)
Returns a pointer to a struct protoent for the protocol named name (e.g. "tcp", "udp", "icmp"), looked up from %ETC%\PROTOCOL.
_getprotobynumber(proto)
Returns the struct protoent for protocol number proto.
_getprotoent() / _setprotoent(stayopen) / _endprotoent()
Sequential enumeration of the protocols file.

Service Database

_getservbyname(name, proto)
Returns a pointer to a struct servent for the service named name on protocol proto (e.g. getservbyname("http", "tcp")), looked up from %ETC%\SERVICES.
_getservbyport(port, proto)
Looks up a service by port number (in network byte order) and protocol.
_getservent() / _setservent(stayopen) / _endservent()
Sequential enumeration of the services file.

Internet Address Utilities

_inet_addr(cp)
Converts an IPv4 address in dotted-decimal notation (e.g. "192.168.1.1") to a 32-bit network-byte-order value. Returns INADDR_NONE (0xFFFFFFFF) on failure.
_inet_ntoa(in)
Converts a network-byte-order struct in_addr to a dotted-decimal string. Returns a pointer to a static buffer; not thread-safe.
_inet_network(cp)
Converts a network address in dotted-decimal notation to host byte order.
_inet_makeaddr(net, lna)
Constructs a struct in_addr from a network number and local host address.
_inet_lnaof(in)
Returns the local (host) part of the IPv4 address according to the classful subnet mask.
_inet_netof(in)
Returns the network part of the IPv4 address according to the classful subnet mask.

DNS Resolver

The resolver functions provide direct access to the DNS protocol layer, bypassing the hosts file cache.

_res_init()
Reads %ETC%\RESOLV2 (IBM OS/2 TCP/IP name for resolv.conf) to initialize the global _res resolver state structure (struct __res_state). Sets the default domain, search list, nameserver addresses, and option flags. Called automatically by gethostbyname if not already initialized.
_res_query(dname, class, type, answer, anslen)
Sends a DNS query for dname of class and record type, and places the raw DNS wire-format response in answer[anslen]. Returns the response length on success, -1 on error with h_errno set.
_res_querydomain(name, domain, class, type, answer, anslen)
Appends domain to name and calls res_query. Used internally by res_search for the search-list iterations.
_res_search(dname, class, type, answer, anslen)
Performs a DNS search using the search domains from _res.search[], trying each in order. Returns the first successful response.
_res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
Constructs a DNS query message in buf. op is the query opcode (QUERY, IQUERY).
_res_send(msg, msglen, answer, anslen)
Sends a pre-built DNS query msg to the configured nameservers and returns the response in answer.
_res_close()
Closes the resolver's UDP socket to the nameserver (the socket is normally kept open between queries for performance).
__res
The global resolver state variable of type struct __res_state. Applications can set _res.options flags directly (e.g. RES_DEBUG, RES_USEVC for TCP, RES_RECURSE) after calling res_init().

Resolver String Tables

__res_opcodes — array of C strings naming DNS opcode values (e.g. "QUERY", "IQUERY", "STATUS").

__res_resultcodes — array of C strings naming DNS response codes (e.g. "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN").

DNS Name Compression

Low-level DNS wire-format helpers used by the resolver and by applications parsing raw DNS packets:

_dn_comp(src, dst, dstsiz, dnptrs, lastdnptr)
Compresses a domain name into DNS wire format using a pointer compression table.
_dn_expand(msg, eomorig, comp_dn, exp_dn, length)
Expands a compressed domain name from a DNS message buffer into a printable string.
_dn_skipname(comp_dn, eom)
Skips over one compressed domain name label sequence in a DNS message, returning a pointer past the name.

DNS Debug Output

Pretty-print functions used by tools like NSLOOKUP.EXE and NSQUERY.EXE (shipped with IBM TCP/IP for OS/2):

_p_query(msg)
Prints a complete DNS query/response message in human-readable form to stdout.
_fp_query(msg, file)
Same as _p_query but writes to a FILE*.
_p_cdname(cp, msg, file)
Prints a compressed domain name.
_p_rr(rr, msg, file)
Prints a single resource record.
_p_type(type) / _p_class(class) / _p_time(value)
Return printable strings for DNS type, class, and TTL values.

Byte-Order and Utility

_bswap(value)
Swaps the byte order of a 32-bit value. Equivalent to ntohl/htonl on a little-endian host.
_lswap(value)
Swaps a 32-bit value (long swap). Alias or variant of _bswap.
_getlong(p) / _putlong(p, v)
Read or write a 32-bit big-endian value from/to an unaligned byte pointer. Used when parsing DNS wire format on architectures that do not support unaligned memory access.
_getshort(p) / _putshort(p, v)
Read or write a 16-bit big-endian value from/to an unaligned byte pointer.

Time and Process

_gettimeofday(tp, tzp)
Returns the current time as a struct timeval (seconds and microseconds since epoch). On OS/2, microsecond resolution is approximated from the system timer.
_alarm(seconds)
Schedules an SIGALRM-equivalent signal (via _xsignal) after seconds seconds. Used by the resolver to implement query timeouts.
_getpid()
Returns the current process ID. Used internally by the resolver to generate unique DNS query IDs.

Remote Execution

_rexec(ahost, inport, user, passwd, cmd, fd2p)
Connects to a remote rexecd daemon and executes command cmd as user user (authenticated with password passwd). Returns a socket connected to the remote program's stdin/stdout; fd2p if non-NULL receives a socket connected to the remote program's stderr. Not recommended for new code (transmits password in cleartext); available for legacy BSD application porting.

Error Reporting

_h_errno
The global variable holding the last host-resolver error. Set by gethostbyname, gethostbyaddr, res_query, and related functions. Values:
  • HOST_NOT_FOUND (1) — authoritative "no such host" response from DNS
  • TRY_AGAIN (2) — DNS server timeout or transient failure
  • NO_RECOVERY (3) — non-recoverable DNS error (FORMERR, REFUSED, etc.)
  • NO_DATA (4) — hostname exists but has no address records of the requested type
_tcperrno
The global socket error variable, equivalent to Unix errno for socket operations. Set by socket functions on failure. Maps to standard BSD error codes (EWOULDBLOCK, ECONNREFUSED, ETIMEDOUT, etc.) defined in <nerrno.h>.
_perror(s)
Prints a human-readable error message for the current _tcperrno value, prefixed by s. OS/2 TCP/IP-specific version of the standard C perror().

Miscellaneous

_getopt(argc, argv, optstring)
Standard POSIX option-string parser. Included in TCPIPDLL.DLL for use by TCP/IP utility programs (ping, ftp, telnet, etc.) shipped with IBM TCP/IP for OS/2.
_rindex(s, c)
Finds the last occurrence of character c in string s. BSD string utility included alongside the socket API.
_isforwarding()
Returns non-zero if IP forwarding (packet routing between interfaces) is currently enabled on this host.
_xsignal(signum, handler)
Sets a signal handler for socket-related signals (SIGALRM, SIGPIPE) within the TCP/IP library context. OS/2-specific wrapper around the signal delivery mechanism.
_message(format, ...)
Internal diagnostic printf, used by TCP/IP utility programs.

Error Codes

Socket functions return -1 on error and set tcperrno. The OS/2 TCP/IP error constants are defined in <nerrno.h> (not the standard C <errno.h>):

Constant Value Meaning
SOCEWOULDBLOCK 10035 Operation would block (non-blocking socket)
SOCEINPROGRESS 10036 Connection in progress
SOCEALREADY 10037 Operation already in progress
SOCENOTSOCK 10038 Not a socket
SOCEDESTADDRREQ 10039 Destination address required
SOCEMSGSIZE 10040 Message too long
SOCEPROTOTYPE 10041 Protocol type mismatch
SOCENOPROTOOPT 10042 Protocol option not available
SOCEPROTONOSUPPORT 10043 Protocol not supported
SOCESOCKTNOSUPPORT 10044 Socket type not supported
SOCEOPNOTSUPP 10045 Operation not supported on socket
SOCEAFNOSUPPORT 10047 Address family not supported
SOCEADDRINUSE 10048 Address already in use
SOCEADDRNOTAVAIL 10049 Address not available
SOCENETDOWN 10050 Network is down
SOCENETUNREACH 10051 Network unreachable
SOCECONNABORTED 10053 Connection aborted
SOCECONNRESET 10054 Connection reset by peer
SOCENOBUFS 10055 No buffer space available
SOCEISCONN 10056 Socket already connected
SOCENOTCONN 10057 Socket not connected
SOCETIMEDOUT 10060 Connection timed out
SOCECONNREFUSED 10061 Connection refused

Usage

Initialization pattern

Every application using TCPIPDLL must call sock_init() exactly once at startup and sock_term() at exit:

#include <types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <utils.h>   /* sock_init / sock_term */

int main(void)
{
    if (sock_init() != 0) {
        psock_errno("sock_init");
        return 1;
    }

    /* ... socket code here ... */

    sock_term();
    return 0;
}

TCP client example

#include <types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <utils.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
    sock_init();

    struct hostent *he = gethostbyname("www.os2world.com");
    if (!he) { herror("gethostbyname"); return 1; }

    struct sockaddr_in sa;
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port   = htons(80);
    memcpy(&sa.sin_addr, he->h_addr_list[0], he->h_length);

    int s = socket(AF_INET, SOCK_STREAM, 0);
    if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        psock_errno("connect");
        soclose(s);
        return 1;
    }

    const char *req = "GET / HTTP/1.0\r\nHost: www.os2world.com\r\n\r\n";
    send(s, req, strlen(req), 0);

    char buf[4096];
    int  n;
    while ((n = recv(s, buf, sizeof(buf)-1, 0)) > 0) {
        buf[n] = '\0';
        printf("%s", buf);
    }

    soclose(s);
    sock_term();
    return 0;
}

UDP server example

#include <types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <utils.h>

int main(void)
{
    sock_init();

    int s = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in sa;
    sa.sin_family      = AF_INET;
    sa.sin_addr.s_addr = INADDR_ANY;
    sa.sin_port        = htons(9999);
    bind(s, (struct sockaddr *)&sa, sizeof(sa));

    char buf[1500];
    struct sockaddr_in from;
    int fromlen = sizeof(from);
    int n = recvfrom(s, buf, sizeof(buf), 0,
                     (struct sockaddr *)&from, &fromlen);
    /* process datagram */

    soclose(s);
    sock_term();
    return 0;
}

Building

IBM VisualAge C++ / ILINK

icc -O2 -Gm -I%ETC%\..\include\tcpip -c myapp.c
ilink /PM:VIO myapp.obj os2386.lib tcpipdll.lib

OpenWatcom

wcl386 -bt=os2 -mf -I%ETC%\..\include\tcpip -c myapp.c
wlink system os2v2 file myapp.obj library os2386.lib library tcpipdll.lib

EMX/GCC

gcc -Zomf -Zmtd -I/tcpip/include -c myapp.c
gcc -Zomf -o myapp.exe myapp.o -los2386 -ltcpipdll

Include files

IBM TCP/IP for OS/2 headers reside in the TCPIP include tree. Location depends on the installation:

Header Contents
types.h BSD type definitions (u_char, u_short, u_long, u_int)
sys/socket.h struct sockaddr, sockaddr_in, socket constants (AF_*, SOCK_*, SOL_SOCKET, SO_*), socket()/bind()/… prototypes
netinet/in.h struct in_addr, INADDR_ANY, INADDR_BROADCAST, htons()/htonl()/ntohs()/ntohl()
netdb.h struct hostent, struct netent, struct protoent, struct servent; gethostbyname()/getservbyname()/… prototypes; h_errno
arpa/inet.h inet_addr(), inet_ntoa(), inet_makeaddr(), inet_network()
arpa/nameser.h DNS wire-format constants (T_A, T_CNAME, T_NS, T_PTR, T_MX, etc.); HEADER struct; dn_comp()/dn_expand() prototypes
resolv.h struct __res_state (_res); res_init()/res_query()/… prototypes; RES_* option flags
nerrno.h SOCE* error constants; tcperrno external declaration
utils.h sock_init(), sock_term(), psock_errno(), soclose()
sys/select.h fd_set type; FD_ZERO/FD_SET/FD_CLR/FD_ISSET macros; select() prototype
sys/ioctl.h ioctl() prototype; FIONBIO, FIONREAD, SIOC* constants

Configuration Files

IBM TCP/IP for OS/2 reads configuration from the directory pointed to by the %ETC% environment variable (typically C:\MPTN\ETC\ on OS/2 Warp 4):

File Purpose
HOSTS Static hostname-to-IP mappings; consulted before DNS
RESOLV2 DNS resolver configuration: nameserver, domain, search, options lines
SERVICES Service name to port number mapping
PROTOCOL Protocol name to number mapping
NETWORKS Network name to address mapping
INETD.LST inetd super-server service table (for servers using the TCP/IP inetd daemon)

Version History

Version Product Date Notes
1.x IBM TCP/IP for OS/2 1.0/1.2 1988–1990 First OS/2 TCP/IP stack, separate product. Basic BSD 4.3 sockets; no DNS search list. Single-threaded socket access; applications must serialize socket calls.
2.x IBM TCP/IP for OS/2 2.0 1992 Rewritten; multithreaded socket access; DNS resolver updated; added RESOLV2 config file.
3.x OS/2 Warp 3 (integrated) 1994 Integrated into OS/2 Warp base product as MPTS (Multi-Protocol Transport Services). Added multicast, IP_MULTICAST_* socket options.
4.x OS/2 Warp 4 / 4.52 1996–2001 Final IBM release. Added getinetversion, so_cancel/sock_cancel for asynchronous cancel support, and bsdselect alias. File in Toolkit 4.5: 9,216 bytes (2000-10-16).

See Also