TCP/IP Networking

Introduction

As the Internet has grown to become more and more visible in our daily lives, the protocol it's based on — IP (Internet Protocol) — has become increasingly important. The IP protocol and tools that go with it are ubiquitous, making IP the de facto choice for many private networks.

IP is used for everything from simple tasks (e.g. remote login) to more complicated tasks (e.g. delivering realtime stock quotes). Most businesses are turning to the World Wide Web, which commonly rides on IP, for communication with their customers, advertising, and other business connectivity. QNX Neutrino is well-suited for a variety of roles in this global network, from embedded devices connected to the Internet, to the routers that are used to implement the Internet itself.

Given these and many other user requirements, we've made our TCP/IP stack (included in io-pkt*) relatively light on resources, while using the common BSD API.

Stack configurations

We provide the following stack configurations:

NetBSD TCP/IP stack
Based on the latest RFCs, including UDP, IP, and TCP. Also supports forwarding, broadcast and multicast, hardware checksum support, routing sockets, Unix domain sockets, multilink PPP, PPPoE, supernetting (CIDR), NAT/IP filtering, ARP, ICMP, and IGMP, as well as CIFS, DHCP, AutoIP, DNS, NFS (v2 and v3 server/client), NTP, RIP, RIPv2, and an embedded web server.

To create applications for this stack, you use the industry-standard BSD socket API. This stack also includes optimized forwarding code for additional performance and efficient packet routing when the stack is functioning as a network gateway.

Enhanced NetBSD stack with IPsec and IPv6
Includes all the features in the standard stack, plus the functionality targeted at the new generation of mobile and secure communications. This stack provides full IPv6 and IPsec (both IPv4 and IPv6) support through KAME extensions, as well as support for VPNs over IPsec tunnels.

This dual-mode stack supports IPv4 and IPv6 simultaneously and includes IPv6 support for autoconfiguration, which allows device configuration in plug-and-play network environments. IPv6 support includes IPv6-aware utilities and RIP/RIPng to support dynamic routing. An Advanced Socket API is also provided to supplement the standard socket API to take advantage of IPv6 extended-development capabilities.

IPsec support allows secure communication between hosts or networks, providing data confidentiality via strong encryption algorithms and data authentication features. IPsec support also includes the IKE (ISAKMP/Oakley) key management protocol for establishing secure host associations.

The QNX TCP/IP suite is also modular. For example, it provides NFS as separate modules. With this kind of modularity, together with small-sized modules, embedded systems developers can more easily and quickly build small TCP/IP-capable systems.

Structure of the TCP/IP manager

As a resource manager, io-pkt* benefits from the code savings and standard interface that all native resource managers enjoy. Due to the natural priority inheritance of QNX Neutrino IPC, clients will be dealt with in priority and time order, which leads to a more natural allocation of CPU resources.


io-pkt and its dependents


The io-pkt suite and its dependents.

PPP is implemented as part of io-pkt-*. Since io-pkt* handles the transmission of PPP packets, there's no need for a memory copy of the packet data. This approach allows for high-performance PPPoE connections.

Other components of the TCP/IP suite (such as the NFS, the snmpd daemon, etc.) are implemented outside of io-pkt*. This leads to better modularity and fault-tolerance.

Socket API

The BSD Socket API was the obvious choice for QNX Neutrino. The Socket API is the standard API for TCP/IP programming in the UNIX world. In the Windows world, the Winsock API is based on and shares a lot with the BSD Socket API. This makes conversion between the two fairly easy.

All the routines that application programmers would expect are available, including (but not limited to):

accept()
bind()
bindresvport()
connect()
dn_comp()
dn_expand()
endprotoent()
endservent()
gethostbyaddr()
gethostbyname()
getpeername()
getprotobyname()
getprotobynumber()
getprotoent()
getservbyname()
getservent()
getsockname()
getsockopt()
herror()
hstrerror()
htonl()
htons()
h_errlist()
h_errno()
h_nerr()
inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
ioctl()
listen()
ntohl()
ntohs()
recv()
recvfrom()
res_init()
res_mkquery()
res_query()
res_querydomain()
res_search()
res_send()
select()
send()
sendto()
setprotoent()
setservent()
setsockopt()
shutdown()
socket()

For more information, see the Neutrino Library Reference.

The common daemons and utilities from the Internet will easily port or just compile in this environment. This makes it easy to leverage what already exists for your applications.

Database routines

The database routines have been modified to better suit embedded systems.

/etc/resolv.conf

You can use configuration strings (via the confstr() function) to override the data usually contained in the /etc/resolv.conf file. You can also use the RESCONF environment variable to do this. Either method lets you use a nameserver without /etc/resolv.conf. This affects gethostbyname() and other resolver routines.

/etc/protocols

The getprotobyname() and getprotobynumber() functions have been modified to contain a small number of builtin protocols, including IP, ICNP, UDP, and TCP. For many applications, this means that the /etc/protocols file doesn't need to exist.

/etc/services

The getservbyname() function has been modified to contain a small number of builtin services, including ftp, telnet, smtp, domain, nntp, netbios-ns, netbios-ssn, sunrpc, and nfsd. For many applications, this means that the /etc/services file doesn't need to exist.

Multiple stacks

The QNX Neutrino network manager (io-pkt) lets you load multiple protocol shared objects. You can even run multiple, independent instances of the network manager (io-pkt*) itself. As with all QNX Neutrino system components, each io-pkt* naturally benefits from complete memory protection thanks to our microkernel architecture.

IP filtering and NAT

The IP filtering and NAT (Network Address Translation) io-pkt* module (lsm-pf-*.so) is a dynamically loadable TCP/IP stack module. This module provides high-efficiency firewall services and includes such features as:

The IP filtering and NAT rules can be added or deleted dynamically to a running system. Logging services are also provided with the suite of utilities to monitor and control this module.

NTP

NTP (Network Time Protocol) allows you to keep the time of day for the devices in your network synchronized with the Internet standard time servers. The QNX NTP daemon supports both server and client modes.

In server mode, a daemon on the local network synchronizes with the standard time servers. It will then broadcast or multicast what it learned to the clients on the local network, or wait for client requests. The client NTP systems will then be synchronized with the server NTP system. The NTP suite implements NTP v4 while maintaining compatibility with v3, v2, and v1.

Dynamic host configuration

We support DHCP (Dynamic Host Configuration Protocol), which is used to obtain TCP/IP configuration parameters. Our DHCP client (dhcp.client) will obtain its configuration parameters from the DHCP server and configure the TCP/IP host for the user. This allows the user to add a host to the network without knowing what parameters (IP address, gateway, etc.) are required for the host. DHCP also allows a system administrator to control how hosts are added to the network. A DHCP server daemon (dhcpd) and relay agent (dhcprelay) are also provided to manage these clients.

For more information, see the dhcp.client, dhcpd, and dhcprelay entries in the Utilities Reference.

AutoIP

Developed from the Zeroconf IETF draft, lsm-autoip.so is an io-pkt* module that automatically configures the IPv4 address of your interface without the need of a server (as per DHCP) by negotiating with its peers on the network. This module can also coexist with DHCP (dhcp.client), allowing your interface to be assigned both a link-local IP address and a DHCP-assigned IP address at the same time.

PPP over Ethernet

We support the Point-to-Point Protocol over Ethernet (PPPoE), which is commonly deployed by broadband service providers. Our PPPoE support consists of the io-pkt-* stack as well as the pppoectl utility, which negotiates the PPPoE session. Once the PPPoE session is established, the pppd daemon creates a PPP connection.

When you use PPPoE, you don't need to specify any configuration parameters — our modules will automatically obtain the appropriate configuration data from your ISP and set up everything for you.

For more information, see the following in the Utilities Reference:

io-pkt
Networking manager.
pppoectl
Display or set parameters for a PPPoE interface.
phlip
Photon TCP/IP and dialup configuration tool.
phdialer
Photon modem dialer.

/etc/autoconnect

Our autoconnect feature automatically sets up a connection to your ISP whenever a TCP/IP application is started. For example, suppose you want to start a dialup connection to the Internet. When your Web browser is started, it will pause and the /etc/autoconnect script will automatically dial your ISP. The browser will resume when the PPP session is established.

For more information, see the entry for /etc/autoconnect in the Utilities Reference.

Embedded web server

Our embedded web server, slinger, uses very little memory and communicates over TCP/IP sockets. The embedded web server supports CGI 1.1, HTTP 1.1, and dynamic HTML (via SSI commands).


Embedded web server


Embedded web server.

Many embedded servers force the user to relink the server in order to add pages, which compromises reliability as vendor and user code compete in a shared memory space.

Despite its size, our embedded web server provides enough functionality to support accessing generated (dynamic) HTML via CGI or SSI.

CGI method

The embedded web server supports the Common Gateway Interface (CGI) 1.1, a readily available means of handling dynamic data. The downside of CGI is that it's resource-heavy because an interpreted language is often involved.

SSI method

With SSI (Server Side Includes), a type of command language that can be embedded in HTML files, you can add dynamic content to your HTML. For example, the embedded server can:

Note that SSI tags are available to interact with a data server.

Data server method

You can also handle dynamic HTML by using what we call a data server. The data server allows multiple threads to share data without regard for process boundaries. Since the embedded web server supports SSI, we've extended this support by adding the ability to talk to the data server.

Now you can have a process updating the data server about the state of a hardware device while the embedded web server accesses that state in a decoupled but reliable manner.


Note: You can write a simple I/O manager to provide dynamic data. Note that this method isn't specific to the embedded web server and that the I/O manager can handle only output, not posts.