|
|
|
|
|
QNX® 6 - System Architecture
Chapter 10: TCP/IP Networking |
|
|
| Table of Contents |
 |
|
|
|
|
|
|
|
| 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. Even if you're not connecting to "The Internet" per se, 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). More and more
businesses are turning to the World Wide Web, which commonly rides on IP, for communication with
their customers, advertising, and other business connectivity.
Given these and many other user requirements, we've
designed the Neutrino Tiny TCP/IP stack (npi-ttcpip) to be very light on resources, while
using the common BSD API.
The Neutrino TCP/IP suite is also modular. For
example, it provides client NFS as a separate module. With this kind of modularity, together with
small-sized modules, embedded systems developers can more easily build small TCP/IP-capable
systems.
|
|
|
| Structure of TCP/IP manager |  |
|
|
|
|
The npi-ttcpip module is designed as a
multithreaded resource manager. It shares in the standard resource manager structure, which allows it
to gain code savings and a standard interface. Its multithreading allows it to service many clients
virtually simultaneously. Due to the natural priority inheritance of QNX® IPC, clients will
be dealt with in priority and time order, which leads to a more natural allocation of CPU
resources.
 |
The npi-ttcpip.so suite and
dependents. |
Most of the link-layer support is implemented
outside of npi-ttcpip.PPP is a separate process that communicates
with npi-ttcpip via open(), read(), write(),
devctl(), and close() functions.
Note that npi-ttcpip
acts as a protocol shared library to the io-net process, which
directs data to the correct driver. Network drivers are shared libraries as well.
Other components of the npi-
ttcpip suite such as CIFS are implemented outside of
npi-ttcpip. This leads to better modularity and fault-
tolerance.
|
|
|
| Socket API |  |
|
|
|
|
The BSD Socket API was the obvious choice for
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:
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()
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.
 |
Given its size constraints, the Neutrino embedded TCP/IP
implementation has some API limitations worth noting here:
- The MSG_WAITALL flag used by recv*() functions isn't supported.
- The tiny stack doesn't support ancillary data. See the msghdr
structure passed in recvmsg() and sendmsg().
- The MSG_OOB and MSG_DONTROUTE flags used by send*() functions aren't supported.
- There's no support for socketpair().
- There's no support for UNIX domain sockets.
|
Database routines
The database routines have been modified to better
suit embedded systems.
/etc/resolv.conf
The information in
/etc/resolv.conf can be put in the environment variable
RESCONF. This 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.
|
|
|
| Network interoperability |  |
|
|
|
|
The npi-ttcpip
module was designed and implemented with interoperability in mind. The code for
npi-ttcpip takes into account both the RFCs and the real world; it
also addresses the functionality proposed in RFC 1122. The ARP, IP, ICMP, UDP, and TCP protocols are
supported as well.
 |
In order to meet the size requirements for
npi-ttcpip, we had to leave out certain features sometimes found
in stacks meant for Unix servers:
- There's no support in the tiny stack for the arp utility. You
can't change or display entries in the ARP cache.
- Although the tiny stack currently doesn't support ifconfig
and route to set the configuration parameters, you can apply
interface and route configuration parameters on the command line.
- There's no support in the tiny stack for the netstat utility,
but you can view information related to the interfaces, routes, and connections from the
/proc/ipstats device (e.g.
cat /proc/ipstats)
- Ethernet and PPP interfaces are the only drivers currently supported.
|
|
|
|
| Dynamic host configuration |  |
|
|
|
|
Neutrino supports DHCP (Dynamic Host Configuration
Protocol), which is used to obtain TCP/IP configuration parameters. The Neutrino 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.
For more information, see the
dhcp.client entry in the Neutrino Utilities
Reference.
|
|
|
| Embedded web server |  |
|
|
|
|
Our embedded web server 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. |
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 different ways of accessing generated (dynamic) HTML:
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:
- execute utilities at user-defined points in an HTML document (the output of these utilities can
be optionally placed in the document).
- insert contents of other HTML files at a user-defined point.
- handle conditional statements (if,
break, goto) so you can define what
parts of an HTML file are transmitted.
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.
 |
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. |
|
|
|
| Future directions |  |
|
|
|
|
Instead of bloating npi-
ttcpip with server features not normally needed in resource-constrained environments, we've
decided to provide a second stack for server use. This stack will be a direct derivative of
the BSD 4.4 stack, which is powering many of the large servers on the Internet today.
Our BSD 4.4 implementation will provide an NFS
server module, multicasting, supernetting, virtual packet interface, and more.
The applications you write will use one API,
regardless of which stack you'll ultimately use. Without recompiling or relinking, you'll be able to
change from using the tiny stack on one target to using the large stack on a different
target.
<<
Previous |
Index |
Next >>
|
|