Network Exploration

Avahi

Avahi implements Zeroconf for Fedora and other systems.

The Avahi service is avahi-daemon (package avahi). It expects the firewall to permit multicast traffic for group 224.0.0.251 on port 5353. To start the daemon:

-> systemctl start avahi-daemon.service
-> systemctl status avahi-daemon.service

… Joining mDNS multicast group on interface em1.IPv4 with address 192.168.1.2.

… Server startup complete. Host name is desktop.local. Local service cookie is 3669703634.

The configuration file is /etc/avahi/avahi-daemon.conf with man page avahi-daemon.conf.

The daemon publishes local services corresponding to service files under directory /etc/avahi/services (man page avahi.service). File /usr/share/avahi/service-types lists service types. To register a new service, create a service file for it. To unregister an existing service, rename the extension of the corresponding service file (or delete the file). For example:

-> cd /etc/avahi/services
-> mv ssh.service ssh.service.off

avahi-daemon monitors its services directory and automatically adjusts its list of local services to advertise.

Alternatively, to register a service, use avahi-publish-service (package avahi-tools). For example:

-> avahi-publish-service 'My FTP Server' _ftp._tcp 21 &

The service disappears when avahi-daemon stops, and restarting the daemon appears to be only way to unregister the service.

To browse Zeroconf services available on the LAN, use GUI avahi-discover (package avahi-ui-tools) or CLI avahi-browse (package avahi-tools). For example:

-> avahi-browse --terminate --all
+    em1 IPv4 gogo [00:26:b9:a0:a2:cc]                      Workstation          local
+    em1 IPv4 desktop [00:0f:1f:73:94:f2]                   Workstation          local
+    em1 IPv4 mt-daapd                                      iTunes Audio Access  local
+    em1 IPv4 mt-daapd                                      Web Site             local

You can browse for specific types of services and retrieve underlying details:

-> avahi-browse --terminate --resolve _daap._tcp
+    em1 IPv4 mt-daapd                                      iTunes Audio Access  local
=    em1 IPv4 mt-daapd                                      iTunes Audio Access  local
   hostname = [gogo.local]
   address = [192.168.1.3]
   port = [3689]
   txt = ["Database ID=beddab1edeadbea7" "txtvers=1"]

Avahi provides additional tools to manage link-local addressing and name resolution: avahi-autoipd, avahi-dnsconfd, avahi-resolve, avahi-set-host-name, avahi-autoipd. And there are a couple of tools for browsing specific services: avahi-bookmarks, bssh. All of these tools have man pages.

Link Layer Discovery Protocol (LLDP)

Switches, routers, access points, and other Ethernet devices can announce their presence and identity over a LAN by means of LLDP messages (IEEE 802.1AB). Each such message is a single Ethernet frame providing at least four mandatory TLV (type ID, length, value) fields: chassis ID, port ID, time to live, end-of-message. Optional fields supply additional information, such as system descriptions and capabilities.

The destination address for an LLDP frame is a special multicast address (01:80:c2:00:00:0e), which switches and such do not forward. Thus a computer connected by Ethernet cable to a switch will see LLDP messages from at most itself and that switch.

The LLDP-agent daemon lldpad sends and receives LLDP messages on behalf of a host computer, and its companion lldptool instructs and interrogates the daemon (package lldpad).

To start the LLDP agent:

-> systemctl start lldpad
-> systemctl --full status lldpad
lldpad.service - Link Layer Discovery Protocol Agent Daemon.
   Loaded: loaded (/usr/lib/systemd/system/lldpad.service; disabled)
   Active: active (running) since Wed 2014-09-10 16:12:55 EDT; 43min ago

-> lldptool ping
2292

To receive and transmit LLDP messages over interface p2p1, say:

-> lldptool -i p2p1 set-lldp adminStatus=rxtx
adminStatus = rxtx

The other values for adminStatus are rx, tx, and disabled.

To check the admin status:

-> lldptool -i p2p1 get-lldp adminStatus
adminStatus=rxtx

To see your link partner (neighbor):

-> lldptool -i p2p1 get-tlv -n
Chassis ID TLV
	MAC: 00:25:84:cf:43:e4
Port ID TLV
	Ifname: e1
Time to Live TLV
	120
End of LLDPDU TLV

This partner, a Cisco switch (I think), reveals only the mandatory information about itself. (It seems that the adminStatus needs to be rxtx for this command to work.)

To see what info you are sending:

-> lldptool -i p2p1 get-tlv
Chassis ID TLV
	MAC: 60:a4:4c:ce:63:8f
Port ID TLV
	MAC: 60:a4:4c:ce:63:8f
Time to Live TLV
	120
Port Description TLV
	Interface   2 as p2p1
End of LLDPDU TLV

By default, lldpad transmits only the required fields. But you can instruct it to say more by enabling various TLV identifiers, like so:

-> lldptool -i p2p1 set-tlv enableTx=yes -V portDesc
enableTx = yes
-> lldptool -i p2p1 set-tlv enableTx=yes -V sysName > /dev/null
-> lldptool -i p2p1 set-tlv enableTx=yes -V sysDesc > /dev/null

Run lldptool help for the list of identifiers.

Here's a chatty host:

-> lldptool -i p2p1 get-tlv
Chassis ID TLV
	MAC: 60:a4:4c:ce:63:8f
Port ID TLV
	MAC: 60:a4:4c:ce:63:8f
Time to Live TLV
	120
Port Description TLV
	Interface   2 as p2p1
System Name TLV
	desktop.home
System Description TLV
	Linux desktop.home 3.15.10-201.fc20.x86_64 #1 SMP Wed Aug 27 21:10:06 UTC 2014 x86_64
System Capabilities TLV
	System capabilities:  Station Only
	Enabled capabilities: Station Only
Management Address TLV
	IPv4: 192.168.1.4
	Ifindex: 2
MAC/PHY Configuration Status TLV
	Auto-negotiation supported and enabled
	PMD auto-negotiation capabilities: 0x8f37
	MAU type: 100 BaseTXFD
Link Aggregation TLV
	Aggregation not capable
	Currently not aggregated
	Aggregated Port ID: 0
Maximum Frame Size TLV
	1518
End of LLDPDU TLV

To review stats:

-> lldptool -i p2p1 stat
Total Frames Transmitted        = 8
Total Discarded Frames Received = 0
Total Error Frames Received     = 0
Total Frames Received           = 4
Total Discarded TLVs            = 0
Total Unrecognized TLVs         = 0
Total Ageouts                   = 0

You can capture LLDP packets by specifying Ethernet type 0x88cc to your sniffer; for example:

-> tshark -i p2p1 -f "ether proto 0x88cc" -td -c4

    1   0.000000 Cisco_cf:43:e5 -> LLDP_Multicast LLDP Chassis Id = 00:25:84:cf:43:e4 Port Id = e1 TTL = 120 
1   2  29.988068 Cisco_cf:43:e5 -> LLDP_Multicast LLDP Chassis Id = 00:25:84:cf:43:e4 Port Id = e1 TTL = 120 
2   3  30.018586 Cisco_cf:43:e5 -> LLDP_Multicast LLDP Chassis Id = 00:25:84:cf:43:e4 Port Id = e1 TTL = 120 
3   4  29.972628 Cisco_cf:43:e5 -> LLDP_Multicast LLDP Chassis Id = 00:25:84:cf:43:e4 Port Id = e1 TTL = 120 

Here, tshark substitutes "LLDP_Multicast" for MAC address 01:80:c2:00:00:0e and reports the mandatory fields. The connected switch sends LLDP packets at 30-second intervals.

LAN Neighborhood

Here are some tools to explore the LAN.

To learn a little about the LAN's gateway at 10.201.14.1:

-> nmap -T4 -F -n -sV --traceroute 10.201.14.1

PORT     STATE    SERVICE     VERSION
22/tcp   open     ssh         OpenSSH 5.8p1 Debian 1ubuntu3 (Ubuntu Linux; protocol 2.0)
53/tcp   open     domain
1720/tcp filtered H.323/Q.931
3128/tcp open     http-proxy  Squid http proxy 2.7.STABLE9
3306/tcp open     mysql       MySQL 5.1.54-1ubuntu4
8000/tcp open     http        Apache httpd 2.2.17
Service Info: Host: gateway; OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 143/tcp)
HOP RTT      ADDRESS
1   3.80 ms  192.168.1.1
2   13.58 ms 10.201.14.1

If your computer and its gateway are on the same LAN, you can see its MAC address like so:

-> ip neigh | grep 10.201.14.1
10.201.14.1 dev vlan1 lladdr 00:25:90:70:54:f2 STALE

You can use arping (package iputils) to find the MAC address of the station on the LAN assigned a given IP address. This network, for example, has a host at 192.168.1.2 but not at 192.168.1.5:

-> arping -c1 -I p2p1 192.168.1.2
ARPING 192.168.1.2 from 192.168.1.4 p2p1
Unicast reply from 192.168.1.2 [00:0F:1F:73:94:F2]  0.633ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
-> echo $?
0
-> arping -c2 -I p2p1 192.168.1.5
ARPING 192.168.1.5 from 192.168.1.4 p2p1
Sent 2 probes (2 broadcast(s))
Received 0 response(s)
-> echo $?
1

The IP address 192.168.1.4 identifies the inquisitive station, and p2p1 identifies its network interface to the LAN.

arping provides an easy test to see if an IP address is free. Option -D puts arping into "duplicate address detection mode," which ostensibly just reverses the exit codes: one implies that the address is taken; zero implies no claimant speaks up.

-> arping -q -D -c1 -I p2p1 192.168.1.2; echo $?
1
-> arping -q -D -c1 -I p2p1 192.168.1.5; echo $?
0

arping broadcasts its request on the LAN (via link-layer address ff:ff:ff:ff:ff:ff), and listens for a unicast response from a neighbor. You can watch the action on a separate terminal:

-> tcpdump -q -e -n -t -i p2p1 arp

60:a4:4c:ce:63:8f > Broadcast, ARP, … Request who-has 192.168.1.2 (Broadcast) tell 192.168.1.4, …
00:0f:1f:73:94:f2 > 60:a4:4c:ce:63:8f, ARP, … Reply 192.168.1.2 is-at 00:0f:1f:73:94:f2, …
60:a4:4c:ce:63:8f > Broadcast, ARP, … Request who-has 192.168.1.5 (Broadcast) tell 192.168.1.4, …
60:a4:4c:ce:63:8f > Broadcast, ARP, … Request who-has 192.168.1.5 (Broadcast) tell 192.168.1.4, …

MAC address 60:a4:4c:ce:63:8f belongs to the inquisitive station.

Speed Tests

You can measure your Internet connection's speed from your web browser using embedded graphical speed meters like Ookla, Speak Easy, and thinkbroadband. These meters measure the time it takes to exchange files then report the download and upload rates. Presumably: Each rate is the ratio of file size to transfer time or an average of ratios. The numerator is controlled by the meter and is thus a sharp figure. The denominator reflects factors other than line speed alone, like IP routes followed, server load, client load, browser speed, and transfer protocol. Although meters cannot deliver a pure measure of line speed because of such factors, they do provide a useful proxy for practical exchange rates.

To measure download speed from a shell, use wget or curl to grab a big file from some willing server, and monitor the transfer rate reported. For example:

-> wget -O /dev/null http://speedtest.newark.linode.com/100MB-newark.bin
104,857,600 … in 64s    

2014-08-24 17:47:13 (1.56 MB/s) - ‘/dev/null’ saved [104857600/104857600]

Whether MB connotes 1000 or 1024 is not immediately apparent, but you can let some arithmetic clarify if you care:

-> echo 'scale=2; print (104857600/64)/1000^2, " MB/s\n"'  | bc
1.63 MB/s
-> echo 'scale=2; print (104857600/64)/1024^2, " MiB/s\n"' | bc
1.56 MiB/s

For curl:

-> curl -o /dev/null http://speedtest.newark.linode.com/100MB-newark.bin
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  100M  100  100M    0     0  1710k      0  0:00:59  0:00:59 --:--:-- 1666k
-> echo 'scale=2; print (104857600/59)/1000^2, " MB/s\n"'  | bc
1.77 MB/s
-> echo 'scale=2; print (104857600/59)/1024^2, " MiB/s\n"' | bc
1.69 MiB/s

For additional test files and server locations, see Linode.com (multiple cities) or Thinkbroadband.com (multiple sizes). For really big files, maybe grab the ISO image of a GNU/Linux distribution DVD.

To measure upload speed from a shell, you'll need a remote machine willing to receive your data, and you'll likely need an account on that machine. You can use scp or sftp to upload a test file. You can use dd to make a test file:

-> dd if=/dev/zero of=testfile count=100 bs=1MB 
100+0 records in
100+0 records out
100000000 bytes (100 MB) copied, 0.0242027 s, 4.1 GB/s

With scp:

-> scp testfile rnb@willing.receiver.net:/dev/null
testfile … 95MB 606.6KB/s   02:41
-> echo 'scale=2; print (100000000/161)/1000, " KB/s\n"'  | bc
621.11 KB/s
-> echo 'scale=2; print (100000000/161)/1024, " KiB/s\n"' | bc
606.56 KiB/s

With sftp:

-> echo "put testfile" | sftp rnb@willing.receiver.net -b

testfile … 95MB 495.7KB/s   03:17 
-> echo 'scale=2; print (100000000/197)/1000, " KB/s\n"'  | bc
507.61 KB/s
-> echo 'scale=2; print (100000000/197)/1024, " KiB/s\n"' | bc
495.71 KiB/s

With curl using SCP:

-> curl --upload-file testfile --user rnb scp://willing.receiver.net:/dev/null
Enter host password for user 'rnb':
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0 95.3M      0   525k --:--:--  0:03:05 --:--:--  525k

-> echo 'scale=2; print (100000000/185)/1000, " KB/s\n"'  | bc
540.54 KB/s
-> echo 'scale=2; print (100000000/185)/1024, " KiB/s\n"' | bc
527.87 KiB/s

With curl using SFTP

-> curl --upload-file testfile --user rnb sftp://willing.receiver.net:/dev/null

-> echo 'scale=2; print (100000000/716)/1000, " KB/s\n"'  | bc
139.66 KB/s

Finally, if you upload an actual file in lieu of using /dev/null, watch any quota on your remote account and remember to delete test files, local and remote.

Tips/thoughts: Test when home machine is not loaded with competing network activity. Test with the protocol you're most interested in. Use multiple servers when available. Note the units reported, particularly bytes versus bits: MBs or Mbs, KBs or Kbs. And note the base for K (and M): 1000 or 1024.

You can use wget to measure bandwidth directly from a router running Tomato firmware. First, start the SSH service on the router. (Navigate to Administration → Admin Access.) Then connect to the router as user root and run wget from that shell. Tomato's version of wget does not show progress. Instead, monitor transfer rates from Tomato's real-time bandwidth screen. (Navigate to Bandwidth/Real-Time.)

Zeroconf

Zeroconf—short for Zero-configuration networking technology.

Overview

Zeroconf automates configuration of network services shared among computers, printers, and other devices connected to a LAN. With Zeroconf, any host offering a service can advertise its wares to all takers on the LAN, and any computer can easily discover published services and connect to them. Here are some concrete examples.

By and large, Zeroconf catalogs available network services, and it presents each service as a descriptive name intended for users. In working its magic, it ultimately translates the descriptive name into the IP address of the service's host and the port number of the server application on that host because client applications require the IP address and port number. And that's the quintessence of zero configuration—providing names to people and numbers to applications. Zeroconf recognizes the dynamic assignment of IP addresses on a typical LAN as well as the coming and going of computers and devices. It smoothly handles the variability. Moreover, its service-centric design seamlessly accommodates relocation of a named service from one host to another, whatever their IP addresses.

The technology offers another, less-prominent feature. For a LAN lacking a DHCP server, Zeroconf can assign an IP address and a hostname to a device joining the network. It selects an IP address from the link-local range 169.254.0.0/16 (for IPv4) and uses local for the (pseudo) domain. Zeroconf takes care of complementary name resolution as well. Although IP assignment is not a compelling feature for a LAN behind a router that provides DHCP, it does lend a helping hand for an ad-hoc or isolated network.

Zeroconf itself is not and application, a library, or an API; it is not software. Rather, it is a protocol suite with multiple implementations. More specifically, it comprises three protocols—one for service discovery, another for name resolution, and a third for link-local addresses. Zeroconf has a decentralized infrastructure based on multicast messaging. It eschews a central, authoritative server tracking resources. Instead, Zeroconf hosts join a common multicast group and exchange all announcements, queries, and responses via that group. Each participant then retains its own set of records and keeps them fresh by listening for updates or asking for updates.

Avahi implements Zeroconf for Linux, while Bonjour does the job for Apple operating systems. Both deploy the same three underlying protocols for the Zeroconf stack. As a consequence, Avahi and Bonjour are compatible: Linux and Apple systems transparently share their Zeroconf services on the LAN. In contrast, Microsoft Windows uses two other protocols for service discovery and name resolution, and these are not compatible with the corresponding protocols of Avahi and Bonjour. Thus Windows systems and Avahi/Bonjour systems typically require explicit configuration to share network services with each other. For example, a Bonjour-enabled printer will not appear automatically in the Windows add-printer wizard. Instead, the user must give the print queue's IP address and port number to the wizard.

Assorted Details

Here are some applications that use Zerconf to locate services on the LAN.

These applications require package avahi (but for what I don't yet know): dia, seahorse, totem.

Zerconf puts the limelight on services. Applications query the network for just those services they are interested in. For example, Rhythmbox and Banshee look for music servers (type _daap._tcp), web browsers take note of advertised sites (_http._tcp or _https._tcp), and CUPS probes for printers (_ipp._tcp, _pdl-datastream._tcp, _printer._tcp). But first and foremost, applications seek services, not hosts, and they present their findings to users for ultimate selection. The host sponsoring the service is effectively secondary; a client resolves the address and port only when it's time to connect. In this way, the hosting device or even the services itself can freely move about the network.

Avahi and Bonjour use DNS Service Discovery (DNS-SD), Multicast DNS (mDNS) name resolution, and IPv4 Link-Local addressing (IPv4LL). Windows operating systems use Simple Service Discovery Protocol (SSDP), Link-local Multicast Name Resolution (LLMNR), and IPv4 Link-Local addressing (IPv4LL). Although quite similar, mDNS and LLMNR nevertheless do not inter-operate. The two service-discovery protocols just plain differ; DNS-SD uses DNS while LLMR uses HTTP.

mDNSResponder, an open-source component of Bonjour, implements both local and wide-area service discovery. It's built into Apple's OS X and iOS, naturally. Bonjour Print Services for Windows is mDNSResponder restricted to printer discovery, and iTunes for Windows silently installs its mDNSResponder to enable music sharing. Some other Windows applications install their version of mDNSResponder, too, such as Pidgin, Safari, and Skype. Zerconf/Bonjour-enabled devices, like printers, perhaps use mDNSResponder as well.

Both Windows and Apple operating systems implement IPv4LL, and Avahi implements IPv4LL for Linux (in avahi-autoip). Microsoft refers to IPv4LL as Automatic Private IP Addressing (APIPA). APIPA came first, dominated the market as a de facto standard, and subsequently became the IETF standard (RFC 3927). Other names are auto-IP and Internet Protocol Automatic Configuration (IPAC). IPv6 has self-assignment of link-local addresses built in.

For the record: SSDP is part of Universal Plug and Play (UPnP). There is a third service-discovery protocol adding its acronym to the alphabet soup, and that is IETF's Service Location Protocol (SLP). It has gained little purchase.