TCP/IP Networking

This chapter includes:

Overview of TCP/IP

The term TCP/IP implies two distinct protocols: TCP and IP. Since these protocols have been used so commonly together, TCP/IP has become a standard terminology in today's Internet. Essentially, TCP/IP refers to network communications where the TCP transport is used to deliver data across IP networks.

This chapter provides information on setting up TCP/IP networking on a Neutrino network. It also provides troubleshooting and other relevant details from a system-administration point of view. A Neutrino-based TCP/IP network can access resources located on any other system that supports TCP/IP.

Clients and servers

There are two types of TCP/IP hosts: clients and servers. A client requests TCP/IP service; a server provides it. In planning your network, you must decide which hosts will be servers and which will be clients.

For example, if you want to telnet from a machine, you need to set it up as a client; if you want to telnet to a machine, it has to be a server.

Hosts and gateways

In TCP/IP terminology, we always refer to network-accessible computers as hosts or gateways.

Host
A node running TCP/IP that doesn't forward IP packets to other TCP/IP networks; a host usually has a single interface (network card) and is the destination or source of TCP/IP packets.
Gateway
A node running TCP/IP that forwards IP packets to other TCP/IP networks, as determined by its routing table. These systems have two or more network interfaces. If a TCP/IP host has Internet access, there must be a gateway located on its network.

Note: In order to use TCP/IP, you need an IP address, and you also need the IP address of the host you wish to communicate with. You typically refer to the remote host by using a textual name that's resolved into an IP address by using a name server.

Name servers

A name server is a database that contains the names and IP addresses of hosts. You normally access a TCP/IP or Internet host with a textual name (e.g. www.qnx.com) and use some mechanism to translate the name into an IP address (e.g. 209.226.137.1).

The simplest way to do this mapping is to use a table in the /etc/hosts file. This works well for small to medium networks; if you have something a bit more complicated than a small internal network with a few hosts, you need a name server (e.g. for an ISP connection to the Internet).

When you use a name to connect to a TCP/IP host, the name server is asked for the corresponding IP address, and the connection is then made to that IP address. You can use either:

You can use phlip, the Photon TCP/IP and dialup configuration tool, to configure the network and specify name servers; phlip sets the configuration string _CS_RESOLVE. You can also set _CS_RESOLVE manually. This string, if it exists, is always searched instead of /etc/resolv.conf.

For more information on finding TCP/IP hostnames and name servers, see /etc/hosts, /etc/nsswitch.conf and /etc/resolv.conf in the Utilities Reference.


Note: If the name server isn't responding, there's a timeout of 1.5 minutes per name server. You can't change this timeout, but many TCP/IP utilities have a -n option that you can use to prevent name lookups.

Routing

Routing determines how to get a packet to its intended destination. The general categories of routing are:

Minimal routing
You will only be communicating with hosts on your own network. For example, you're isolated on your own network.
Static routing
If you're on a network with a small (and static over time) number of gateways, then you can use the route command to manually manipulate the TCP/IP routing tables and leave them that way.

This is a very common configuration. If a host has access to the Internet, it likely added one static route called a default route. This route directs all the TCP/IP packets from your host that aren't destined for a host on your local network to a gateway that provides access to the Internet.

Dynamic routing
If you're on a network with more than one possible route to the same destination on your network, you might need to use dynamic routing. This relies on routing protocols to distribute information about the changing state of the network. If you need to react to these changes, run routed, which implements the Routing Information Protocol (RIP) and RIPv2.

There's often confusion between routing and routing protocols. The TCP/IP stack determines the routing by using routing tables; routing protocols let those tables change.

Software components for TCP/IP networking

To use TCP/IP, you need the following software components:


TCP/IP components


Components of TCP/IP in Neutrino.

io-pkt*
Manager that provides support for dynamically loaded networking modules. It includes a fully featured TCP/IP stack derived from the NetBSD code base.
devn-*, devnp-*
Managers that form an interface with the hardware.

To set configuration parameters, use the ifconfig and route utilities, as described below.

If you're using the Dynamic Host Configuration Protocol (DHCP), you can use dhcp.client or phlip to set the configuration parameters for you as provided by the DHCP server.


Note: The device enumerator starts io-pkt* automatically when you boot, loads the TCP/IP stack, and starts the appropriate drivers for the detected devices. If you want to specify any options (e.g. to enable IPSec) when you boot, you need to edit the device-enumeration files. For more information and an example, see Device enumeration in the Controlling How Neutrino Starts chapter in this guide.

The TCP/IP stack is based on the NetBSD TCP/IP stack, and it supports similar features. If you aren't using phlip (the Photon TCP/IP and dialup configuration tool) to configure the stack, you have to use the ifconfig and route utilities as described below.

To configure an interface with an IP address, you must use the ifconfig utility. To configure your network interface with an IP address of 10.0.0.100, you would use the following command:

ifconfig if_name 10.0.0.100

where if_name is the interface name that the driver uses.

If you also want to specify your gateway, use the route command:

route add default 10.0.0.1

This configures the gateway host as 10.0.0.1.

If you then want to view your network configuration, use the netstat command (netstat -in displays information about the network interfaces):

Name Mtu    Network   Address           Ipkts Ierrs Opkts Oerrs Coll
lo0  32976  <Link>                       0    0     0     0     0
lo0  32976  127       127.0.0.1          0    0     0     0     0
en0  1500   <Link>    00:50:da:c8:61:92 21    0     2     0     0
en0  1500   10        10.0.0.100        21    0     2     0     0

To display information about the routing table, use netstat -rn; the resulting display looks like this:

Routing tables

Internet:
Destination Gateway    Flags Refs Use Mtu Interface
default     10.0.0.1   UGS   0    0   -   en0
10          10.0.0.100 U     1    0   -   en0
10.0.0.100  10.0.0.100 UH    0    0   -   lo0
127.0.0.1   127.0.0.1  UH    0    0   -   lo0

The table shows that the default route to the gateway was configured (10.0.0.1).

Running the Internet daemons

If a host is a server, it invokes the appropriate daemon to satisfy a client's requests. A TCP/IP server typically runs the inetd daemon, also known as the Internet super-server. You can start inetd in your machine's rc.local file; see the description of /etc/rc.d/rc.sysinit in the Controlling How Neutrino Starts chapter in this guide.


Caution: Running inetd lets outside users try to connect to your machine and thus is a potential security issue if you don't configure it properly.

The inetd daemon listens for connections on some well-known ports, as defined in /etc/inetd.conf, in the TCP/IP network. On receiving a request, it runs the corresponding server daemon. For example, if a client requests a remote login by invoking rlogin, then inetd starts rlogind (remote login daemon) to satisfy the request. In most instances, responses to client requests are handled this way.

You use the super-server configuration file /etc/inetd.conf to specify the daemons that inetd can start.


Note: As shipped in the Neutrino distribution, the file contains commented-out descriptions of all currently shipped Neutrino TCP/IP daemons and some nonstandard pidin services. You need to edit inetd.conf and uncomment the descriptions of the ones you want to use.

When it starts, inetd reads its configuration information from this configuration file. It includes these commonly used daemons:

ftpd
File transfer.
rlogind
Remote login.
rshd
Remote shell.
telnetd
Remote terminal session.
tftpd
DARPA trivial file transfer.

Note:
  • Remember that you shouldn't manually start the daemon processes listed in this file; they expect to be started by inetd.
  • Running rshd or rlogind can open up your machine to the world. Use the /etc/hosts.equiv or ~/.rhosts files (or both) to identify trusted users, but be very careful.

You may also find other resident daemons that can run independently of inetd — see the Utilities Reference for descriptions:

bootpd
Internet boot protocol server.
dhcpd
Dynamic Host Configuration Protocol daemon.
lpd
Line printer daemon (see Printing).
mrouted
Distance-Vector Multicast Routing Protocol (DVMRP) daemon.
named
Internet domain name server
ntpd
Network Time Protocol daemon.
routed
RIP and RIPv2 routing protocol daemon
rwhod
System status database.
slinger
Tiny HTTP web server.
snmpd
SNMP agent.
nfsd
NFS server.

These daemons listen on their own TCP ports and manage their own transactions. They usually start when the computer boots and then run continuously, although to conserve system resources, you can have inetd start bootpd only when a boot request arrives.

Running multiple instances of the TCP/IP stack

If your system has more than one Network Interface Card, you may need to run multiple instances of the TCP/IP stack.

If the NICs are the same type, you have to specify their PCI indexes (which you can determine by using the pci -vvv command) when you start io-pkt. You can use stack instance numbers and prefixes to identify the instances of the stack. For example, let's start two stacks using the fictitious devnp-abc100 driver:

io-pkt-v4-hc -d abc100 pci=0x0
io-pkt-v4-hc -i2 -d abc100 pci=0x1 -ptcpip prefix=/sock2

In the second command line:

TCP/IP applications that wish to use the second stack must specify the SOCK environment variable. If you don't specify SOCK, the command uses the first TCP/IP stack. For example:

If you're using mount, you can add the stack instance number to the name of the manager. For example, to load lsm-pf-v4.so into the second instance of the stack, type:

mount -Tio-pkt2 lsm-pf-v4.so

Dynamically assigned TCP/IP parameters

When you add a host to the network or connect your host to the Internet, you need to assign an IP address to your host and set some other configuration parameters. There are a few common mechanisms for doing this:

Along with your IP address, the servers implementing these protocols can supply your gateway, netmask, name servers, and even your printer in the case of a corporate network. Users don't need to manually configure their host to use the network.

Neutrino also implements another autoconfiguration protocol called AutoIP (zeroconf IETF draft). This autoconfiguration protocol is used to assign link-local IP addresses to hosts in a small network. It uses a peer-negotiation scheme to determine the link-local IP address to use instead of relying on a central server.

Using PPPoE

PPPoE stands for Point-to-Point Protocol over Ethernet. It's a method of encapsulating your data for transmission over a bridged Ethernet topology.

PPPoE is a specification for connecting users on an Ethernet network to the Internet through a broadband connection, such as a single DSL line, wireless device, or cable modem. Using PPPoE and a broadband modem, LAN users can gain individual authenticated access to high-speed data networks.

By combining Ethernet and the Point-to-Point Protocol (PPP), PPPoE provides an efficient way to create a separate connection to a remote server for each user. Access, billing, and choice of service are managed on a per-user basis, rather than a per-site basis. It has the advantage that neither the telephone company nor the Internet service provider (ISP) needs to provide any special support.

Unlike dialup connections, DSL and cable modem connections are always on. Since a number of different users are sharing the same physical connection to the remote service provider, a way is needed to keep track of which user traffic should go to where, and which user should be billed. PPPoE lets each user-remote site session learn each other's network addresses (during an initial exchange called discovery). Once a session is established between an individual user and the remote site (for example, an Internet service provider), the session can be monitored for billing purposes. Many apartment houses, hotels, and corporations are now providing shared Internet access over DSL lines using Ethernet and PPPoE.

A PPPoE connection is composed of a client and a server. Both the client and server work over any Ethernet-like interface. It's used to hand out IP addresses to the clients, based on the user (and computer if desired), as opposed to computer-only authentication. The PPPoE server creates a point-to-point connection for each client.

Establishing a PPPoE session

Use the pppoectl utilitiy to negotiate a PPPoE session. The io-pkt-* stack provides PPP-to-Ethernet services. Start io-pkt* with the appropriate driver. For example:

io-pkt-v6-hc -del900

Starting a point-to-point connection over PPPoE session

Use pppoectl to configure and initiate the PPPoE session. Here's an example of the commands you use to bring up a PPPoE connection:

  1. Make sure the Ethernet interface is up (or else it won't send any packets):
    ifconfig ne0 up
  2. Let pppoe0 use ne0 as its Ethernet interface:
    pppoectl -e ne0 pppoe0
  3. Configure authentication:
    pppoectl pppoe0 \
       myauthproto=pap \
       myauthname=XXXXX \
       myauthsecret=YYYYY \
       hisauthproto=none
  4. Configure the pppoe0 interface itself. These addresses are magic, meaning we don't care about either address, so we let the remote PPP choose them:
    ifconfig pppoe0 0.0.0.0 0.0.0.1 netmask 0xffffffff up

You can use ifwatchd to spawn scripts when the IP address is configured.


Note: If PPPoE has problems connecting to certain sites on the Internet, see PPPOE and Path MTU Discovery in the Neutrino technotes.

Using DHCP

A TCP/IP host uses the DHCP (Dynamic Host Configuration Protocol) to obtain its configuration parameters (IP address, gateway, name servers, and so on) from a DHCP server that contains the configuration parameters of all the hosts on the network.

The Neutrino DHCP client, dhcp.client, obtains these parameters and configures your host for you to use the Internet or local network.

If your DHCP server supplies options (configuration parameters) that dhcp.client doesn't know how to apply, dhcp.client passes them to a script that it executes. You can use this script to apply any options you want to use outside of those that dhcp.client sets for you. For more information, see the entry for dhcp.client in the Utilities Reference.

Using AutoIP

AutoIP is a module that you must mount into io-pkt*. It is used for quick configuration of hosts on a small network. AutoIP assigns a link-local IP address from the 169.254/16 network to its interface if no other host is using this address. The advantage of using AutoIP is that you don't need a central configuration server. The hosts negotiate among themselves which IP addresses are free to use, and monitor for conflicts.

It's common to have a host employ both DHCP and AutoIP at the same time. When the host is first connected to the network, it doesn't know if a DHCP server is present or not. If you start dhcp.client with the -a option (apply IP address as an alias), then both a link-local IP address and DHCP IP address can be assigned to your interface at the same time. If the DHCP server isn't present, dhcp.client times out, leaving the link-local IP address active. If a DHCP server becomes available later, dhcp.client can be restarted and a DHCP IP address applied without interfering with any TCP/IP connections currently using the link-local IP address.

Having both a DHCP-assigned address and a link-local address active at the same time lets you communicate with hosts that have link-local IP addresses and those that have regular IP addresses. For more information, see lsm-autoip.so and dhcp.client in the Utilities Reference.

Troubleshooting

If you're having trouble with your TCP/IP network (i.e. you can't send packets over the network), you need to use several utilities for troubleshooting. These utilities query hosts, servers, and the gateways to fetch diagnostic information to locate faults. Some of the typical queries are:

Are io-pkt* and the drivers running?

As mentioned before, io-pkt* is the framework used to connect drivers and protocols. In order to troubleshoot this, use the pidin command:

$ pidin -P io-pkt-v4 mem

The output should be something like this:

   pid tid name               prio STATE            code  data        stack
126996   1 sbin/io-pkt-v4-hc   21o SIGWAITINFO      872K  904K  8192(516K)*
126996   2 sbin/io-pkt-v4-hc   21o RECEIVE          872K  904K  8192(132K)
126996   3 sbin/io-pkt-v4-hc   21r RECEIVE          872K  904K  4096(132K)
126996   4 sbin/io-pkt-v4-hc   21o RECEIVE          872K  904K  4096(132K)
126996   5 sbin/io-pkt-v4-hc   20o RECEIVE          872K  904K  4096(132K)
126996   6 sbin/io-pkt-v4-hc    9o RECEIVE          872K  904K  4096(132K)
          libc.so.3          @b0300000             444K   16K
          devnp-shim.so      @b8200000              28K  8192
          devn-epic.so       @b8209000              40K  4096
          lsm-qnet.so        @b8214000             168K   36K

You should see a shared object for a network driver (in this case the “shim” driver, devnp-shim.so that lets io-pkt support the legacy io-net driver, devn-epic.so). You can also use the pidin ar and ifconfig commands to get more information about how the networking is configured.

What is the name server information?

Use the following command to get the name server information:

getconf _CS_RESOLVE

If you aren't using the configuration string, type:

cat /etc/resolv.conf

How do I map hostnames to IP addresses?

The /etc/hosts file contains information regarding the known hosts on the network. For each host, a single line should be present with the following information:

internet_address  official_host_name  aliases

Display this file by using the following command:

cat /etc/hosts

How do I get the network status?

Use the following netstat commands to get the network status:

netstat -in
List the interfaces, including the MAC and IP addresses that they've been configured with.
netstat -rn
Display the network routing tables that determine how the stack can reach another host. If there's no route to another host, you get a “no route to host” error.
netstat -an
List information about TCP/IP connections to or from your system. This includes the state of the connections or the amount of data pending on the connections. It also provides the IP addresses and ports of the local and remote ends of the connections.

For more information about netstat, see the Utilities Reference.

How do I make sure I'm connected to other hosts?

Use the ping utility to determine if you're connected to other hosts. For example:

ping isp.com

On success, ping displays something like this:

PING isp.com (10.0.0.1): 56 data bytes
64 bytes from 10.0.0.1: icmp_seq=0 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=1 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=5 ttl=255 time=0 ms
64 bytes from 10.0.0.1: icmp_seq=6 ttl=255 time=0 ms

This report continues until you terminate ping, for example, by pressing Ctrl-C.

How do I display information about an interface controller?

Use the nicinfo command:

/usr/sbin/nicinfo device

Note: If you aren't logged in as root, you have to specify the full path to nicinfo.

This utility displays information about the given network interface connection, or /dev/io-net/en0 if you don't specify one. The information includes the number of packets transmitted and received, collisions, and other errors, as follows:

3COM (90xC) 10BASE-T/100BASE-TX Ethernet Controller
  Physical Node ID ................. 000103 E8433F
  Current Physical Node ID ......... 000103 E8433F
  Media Rate ....................... 10.00 Mb/s half-duplex UTP
  MTU .............................. 1514
  Lan .............................. 0
  I/O Port Range ................... 0xA800 -> 0xA87F
  Hardware Interrupt ............... 0x7
  Promiscuous ...................... Disabled
  Multicast ........................ Enabled

  Total Packets Txd OK ............. 1585370
  Total Packets Txd Bad ............ 9
  Total Packets Rxd OK ............. 11492102
  Total Rx Errors .................. 0

  Total Bytes Txd .................. 102023380
  Total Bytes Rxd .................. 2252658488

  Tx Collision Errors .............. 39598
  Tx Collisions Errors (aborted) ... 0
  Carrier Sense Lost on Tx ......... 0
  FIFO Underruns During Tx ......... 0
  Tx deferred ...................... 99673
  Out of Window Collisions ......... 0
  FIFO Overruns During Rx .......... 0
  Alignment errors ................. 0
  CRC errors ....................... 0.