Sep 252013
 

If you suspect a networking problem, how do you go about diagnosing that problem?

As in all problem solving, the process involves gathering information and performing tests. To adequately perform some of the tests, you need to prepare in advance – by obtaining copies of tools, creating a USB stick with the tools on, finding out how to use the tools, etc. You cannot expect to be able to perform anything useful without investing in that preparation time.

As an alternative to preparing a USB stick full of tools, it may be preferable to prepare a netbook with the tools on – at the very least swapping a network connection to a known working netbook will tell you whether the problem is in the computer or in the network!

Get The MAC Man!

The MAC address of the network connection is probably the single most important bit of information to get your hands on. Because it is the key for obtaining lots of other information – whether dhcp requests are being seen, whether the Ethernet switch can see that MAC address on any of it’s ports … or the expected port, etc. If you report a network issue without the MAC address of the machine in question, someone will bang their head on the desk. If you are locked out of the machine because the network “isn’t working”, and so are unable to run the usual tools to get at the MAC address, report that as a fault.

Obtaining the MAC address varies according to the operating system you want to get it from, and the method you choose to use to get it. I have chosen to document a command-line method; if this makes you unhappy, please feel free to document the graphical way, and I’ll add a link to it. In some cases, you will be choosing which MAC address is relevant to the active network card. If in any doubt, get all the MAC addresses, and suggest which one you think is the active network card; if it turns out you have guessed wrong, at least the right one will be in the list somewhere!

Windows

Start a command line, and run ipconfig :-

C:\Users\msm>ipconfig/all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : w7
   Primary Dns Suffix  . . . . . . . :
   Node Type . . . . . . . . . . . . : Peer-Peer
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : single-names.port.ac.uk
                                       iso.port.ac.uk
                                       eps.is.port.ac.uk

Ethernet adapter Local Area Connection:

   Connection-specific DNS Suffix  . : inside.zonky.org
   Description . . . . . . . . . . . : Intel(R) PRO/1000 MT Desktop Adapter
   Physical Address. . . . . . . . . : 08-00-27-84-0A-B4
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   IPv4 Address. . . . . . . . . . . : 10.0.2.15(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Lease Obtained. . . . . . . . . . : 15 September 2013 12:02:40
   Lease Expires . . . . . . . . . . : 16 September 2013 12:02:40
   Default Gateway . . . . . . . . . : 10.0.2.2
   DHCP Server . . . . . . . . . . . : 10.0.2.2
   DNS Servers . . . . . . . . . . . : 10.0.0.26
   NetBIOS over Tcpip. . . . . . . . : Enabled

Tunnel adapter Local Area Connection* 9:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Teredo Tunneling Pseudo-Interface
   Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   IPv6 Address. . . . . . . . . . . : 2001:0:9d38:953c:2c67:1675:f5ff:fdf0(Pre
erred)
   Link-local IPv6 Address . . . . . : fe80::2c67:1675:f5ff:fdf0%11(Preferred)
   Default Gateway . . . . . . . . . : ::
   NetBIOS over Tcpip. . . . . . . . : Disabled

Tunnel adapter isatap.inside.zonky.org:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : inside.zonky.org
   Description . . . . . . . . . . . : Microsoft ISATAP Adapter #2
   Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes

Windows is being “helpful” here and listing all of the network adapters it knows of. Including the ones that are not plugged in. To find the address we want, we look for the “Ethernet adapter Local Area Connection” section, and within that look for the “Physical Address” which is given here as 08-00-27-84-0A-B4

Linux and OSX

Linux and OSX are pretty similar at this level – with the exception that linux calls Ethernet devices ethN (usually), and OSX calls ’em enN, the command and output is pretty much the same.

Again, start a command-line interface and run the command ifconfig :-

% ifconfig
eth0      Link encap:Ethernet  HWaddr 60:a4:4c:62:84:71  
          inet addr:10.0.0.28  Bcast:10.0.255.255  Mask:255.255.0.0
          inet6 addr: fe80::62a4:4cff:fe62:8471/64 Scope:Link
          inet6 addr: 2001:8b0:ca2c:dead::babe/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1492  Metric:1
          RX packets:170663945 errors:0 dropped:0 overruns:0 frame:0
          TX packets:183200664 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:122771869945 (114.3 GiB)  TX bytes:170314898179 (158.6 GiB)
          Interrupt:73 Base address:0x2000 

ib0       Link encap:UNSPEC  HWaddr 80-00-00-48-FE-80-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.255.0.1  Bcast:10.255.0.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:4bff:ff0c:e1c5/64 Scope:Link
          inet6 addr: 2001:8b0:ca2c:d00d::1/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:4096  Metric:1
          RX packets:6037892 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12155324 errors:0 dropped:3079 overruns:0 carrier:0
          collisions:0 txqueuelen:256 
          RX bytes:314594872 (300.0 MiB)  TX bytes:21890697854 (20.3 GiB)

ib1       Link encap:UNSPEC  HWaddr 80-00-00-49-FE-80-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.255.1.1  Bcast:10.255.1.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:4bff:ff0c:e1c6/64 Scope:Link
          inet6 addr: 2001:8b0:ca2c:d00f::1/64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:2044  Metric:1
          RX packets:4466937 errors:0 dropped:0 overruns:0 frame:0
          TX packets:429108 errors:0 dropped:47 overruns:0 carrier:0
          collisions:0 txqueuelen:256 
          RX bytes:232871358 (222.0 MiB)  TX bytes:17179018366 (15.9 GiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:65309 errors:0 dropped:0 overruns:0 frame:0
          TX packets:65309 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:4625183 (4.4 MiB)  TX bytes:4625183 (4.4 MiB)

This is an unusually complex configuration, but the MAC address can be picked out relatively easily. Just look for the ethN (here it’s “eth0”) and pick out the “HWaddr” which is 60:a4:4c:62:84:71 in this example.

Network Sniffing with Wireshark

Wireshark is a premium graded packet sniffer and packet analysis tool; it’s a tool that really justifies a complete book. But you can get quite a bit done with far less knowledge.

The absolute basic is how to capture packets. This should be fairly easy to accomplish from the graphical interface – it’s pretty much a case of picking a network interface to capture from, and clicking “Start”. Once you have captured 30 seconds or so of traffic, click the red cross, and save the result. All done.


Warning: Contains an enthusiastic American! 

Detailing exactly what you might see in a packet capture is definitely beyond the scope of this blog entry, but there are basically three different kinds of packets you should see :-

  1. Packets sent by your machine. Until you get to more advanced levels, these contain very little in the way of useful information.
  2. Packets sent to your machine. That is they are addressed specifically with your machine in mind. These are also to be ignored at this level.
  3. Finally packets sent out in broadcast mode – to every machine on the network.

The final category can tell you on which network you are … if you are connected to some kind of “special” private network, it is to be expected that an ordinary PC (or Mac) won’t work properly. If you look at enough examples of packet captures, it should eventually become evident what packets are broadcast ones, and what the contents of those packets mean :-

# tshark -i eth0.24 arp 
tshark: Lua: Error during loading:
 [string "/usr/share/wireshark/init.lua"]:45: dofile has been disabled
Running as user "root" and group "root". This could be dangerous.
Capturing on eth0.24
  0.000000 84:78:ac:19:64:41 -> Broadcast    ARP 60 Who has 148.197.24.2?  Tell 148.197.24.252

The packet in question is on the last line. It’s an ARP packet where a machine is asking if anyone knows the Ethernet address of 148.197.24.2 … which is a pretty good indication you are connected to that network.

A Better Ping

The standard ping tool is very useful, but it has a couple of one big disadvantages :-

  1. Machines with an aggressive firewall may not permit ICMP (i.e. ping) packets through. In which case they do not respond to standard pings.
  2. Because ping uses ICMP packets, it is subject to the lower priority that ICMP packets have … in the event of an overloaded network, routers and switches will prefer to drop ICMP to keep TCP and UDP packets flowing. This can result in a false impression of the network reliability.

Because of this, there have been a variety of different tools that accomplish the same sort of thing as ping by using either TCP or UDP (or even ICMP) packets. The latest and greatest of these tools is nping which is part of the nmap series of tools, and is available for just about every platform (including Windows). The default for nping is to send just 5 packets :-

# nping --tcp -p 22 10.0.0.28

Starting Nping 0.6.25 ( http://nmap.org/nping ) at 2013-09-23 20:56 BST
SENT (0.0058s) TCP 10.0.0.26:18384 > 10.0.0.28:22 S ttl=64 id=46091 iplen=40  seq=3907311816 win=1480 
RCVD (0.0062s) TCP 10.0.0.28:22 > 10.0.0.26:18384 SA ttl=64 id=0 iplen=44  seq=4059830626 win=14520 
SENT (1.0060s) TCP 10.0.0.26:18384 > 10.0.0.28:22 S ttl=64 id=46091 iplen=40  seq=3907311816 win=1480 
RCVD (1.0066s) TCP 10.0.0.28:22 > 10.0.0.26:18384 SA ttl=64 id=0 iplen=44  seq=4075461628 win=14520 
SENT (2.0070s) TCP 10.0.0.26:18384 > 10.0.0.28:22 S ttl=64 id=46091 iplen=40  seq=3907311816 win=1480 
RCVD (2.0075s) TCP 10.0.0.28:22 > 10.0.0.26:18384 SA ttl=64 id=0 iplen=44  seq=4091100198 win=14520 
SENT (3.0080s) TCP 10.0.0.26:18384 > 10.0.0.28:22 S ttl=64 id=46091 iplen=40  seq=3907311816 win=1480 
RCVD (3.0084s) TCP 10.0.0.28:22 > 10.0.0.26:18384 SA ttl=64 id=0 iplen=44  seq=4106740813 win=14520 
SENT (4.0090s) TCP 10.0.0.26:18384 > 10.0.0.28:22 S ttl=64 id=46091 iplen=40  seq=3907311816 win=1480 
RCVD (4.0094s) TCP 10.0.0.28:22 > 10.0.0.26:18384 SA ttl=64 id=0 iplen=44  seq=4122381613 win=14520 

Max rtt: 0.451ms | Min rtt: 0.259ms | Avg rtt: 0.342ms
Raw packets sent: 5 (200B) | Rcvd: 5 (230B) | Lost: 0 (0.00%)
Tx time: 4.00449s | Tx bytes/s: 49.94 | Tx pkts/s: 1.25
Rx time: 4.00476s | Rx bytes/s: 57.43 | Rx pkts/s: 1.25
Nping done: 1 IP address pinged in 4.01 seconds

The key information is displayed at the end … specifically the Max rtt (round trip time) which tells you how long it took for the slowest “conversation” to take place, and the “Lost” count of the number of packets lost. There are zillions of options to nping, but some of the most important include :-

Option Description
–tcp Use TCP probe mode, which is probably the preferred mode for testing
-p N Specify the destination port to probe. This can be either open (i.e. a service is running) or closed, but not firewalled.
–count N Tell nping how many packets to send. Increasing this can make the test much longer.
–delay Nms How long to wait between each packet. Always specify “ms” as a suffix to give you milliseconds. A delay of about 50ms is reasonable.

There’s a great deal more to nping than just this, but it’s a start.

How Fast? How Slow?

Does the network connection feel slow? Just how slow does it feel? Measure it

It is not uncommon to find that a network performance issue is actually a performance issue of some other kind. Measuring the network performance can tell you whether it really is the network, or something else. To do so, you need the right tool; measuring with the wrong tool can result in very inaccurate measurements.

Often people resort to using ftp to transfer large files back and forth, which works well enough in normal circumstances, but at higher network speeds you can find yourself measuring the speed of a slow hard disk rather than the network performance. So use the right tool – such as iperf which is available for all major platforms including Windows.

There is an additional tool available for Windows which offers a graphical interface, but I am describing the command-line interface. Partially because that’s the way I am, but partially because it is dead simple.

To run iperf you need to have the software installed on a client machine and a server machine. To run on a server, simply :-

$ iperf -p 32765 -s

Specifying the port number isn’t normally necessary, but I suggest choosing a random port around 32,000 to avoid conflicts. Just remember the port number you use! And on the client :-

% iperf -p 32765 -c polio
------------------------------------------------------------
Client connecting to polio, TCP port 5001
TCP window size: 23.4 KByte (default)
------------------------------------------------------------
[  3] local 10.0.0.28 port 36114 connected with 10.0.0.26 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   113 MBytes  95.0 Mbits/sec
% iperf -p 32765 -c 10.255.0.2
------------------------------------------------------------
Client connecting to 10.255.0.2, TCP port 5001
TCP window size: 28.8 KByte (default)
------------------------------------------------------------
[  3] local 10.255.0.1 port 43978 connected with 10.255.0.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  2.73 GBytes  2.35 Gbits/sec

I have admittedly cheated here by running two tests … to show what a normal 100Mbps ethernet speed should look like, and what something a bit quicker would look like. In the later case, I have used a slow InfiniBand connection that is only about 2.5 times quicker than 1000Mbps ethernet. Bear in mind that :-

  1. Ethernet signals work at 100Mbps or 1000Mbps (or faster for more esoteric Ethernet types), but you
    won’t get to that speed.

  2. You need to baseline a performance test to find out how quick normal speeds look like!
Aug 202013
 

Every so often I come across an old Linux box that doesn’t take kindly to being rebooted. Without console access, it is hard to see what is going on, but the Linux kernel gets stuck trying to mount the root file system. There are many possible fixes for this, but they all have one thing in common … a work-around has to be performed to get the box up and running.

The console gets stuck in a “mini-root” environment loaded when the initrd image is loaded and before the real root file system is mounted which means a lot of commands are not available, but lvm should be available. First of all, run lvm lvscan to get a list of the logical volumes that need activating :-

(initramfs) lvm lvscan
  inactive          '/dev/sys/root' [332.00 MiB] inherit
  inactive          '/dev/sys/usr' [8.38 GiB] inherit
  inactive          '/dev/sys/var' [2.79 GiB] inherit
  inactive          '/dev/sys/swap_1' [7.05 GiB] inherit
  inactive          '/dev/sys/tmp' [380.00 MiB] inherit
  inactive          '/dev/sys/home' [16.00 GiB] inherit
  inactive          '/dev/sys/opt' [24.00 GiB] inherit

For each volume group (the second column, middle word), run: lvm lvchange -ay ${volume-group-name}. In the case of my example :-

(initramfs) lvm vgchange -ay /dev/sys
  7 logical volume(s) in volume group "sys" now active

At which point you should be able to press ^D (or enter exit) to continue the boot process.

A slighter better work-around involves changing the Grub configuration to add a delay to the kernel parameters. This sections assumes that you are not using Grub Legacy!

Start by editing /etc/default/grub and changing the variable GRUB_CMDLINE_LINUX to include “rootdelay=20” :-

GRUB_CMDLINE_LINUX='console=tty0 console=ttyS0,19200n8 rootdelay=20'

Finalise by running update-grub. This adds a 20s delay to the boot process so is hardly an ideal solution.

Feb 222013
 

The Raspberry PI is a pretty cool device, but it is not the only small cheap computer around, and given that the PI is more hardware hacking orientated I thought I’d dig up some links for some of those other devices. Especially as I’ve got two Arduino projects on the go.

There’s actually a surprising number of devices out there; some running Linux and some running Android. And in a surprising variety of form factors; I’ve avoided looking at the simple boards – the point here is to look at devices that are different :-

  1. The Trim-Slice looks quite an interesting device, but all seems to have gone quiet since March 2012.
  2. The Giada Q11 is a similar device which is about the size of a VCR … or a 3.5″ external hard disk enclosure.
  3. The Cloud Client mini PC is a touch smaller being roughly the size of a double-CD case.
  4. The CuBox is more square than the rest and is roughly the same size as a mains plug.
  5. The Cotton Candy is an ARM in a USB stick; a cheaper option but possibly via Ebay is the U2, although most cheaper options don’t have quite the same features as the Cotton Candy.

This is not to imply that there are not others out there, nor that these are “better” in any way. I’ve not used any of them.

Feb 062013
 

If you have previously used Linux’s volume manager (LVM) to set up disk storage, you may want to know about how to grow a filesystem safely.

Which is probably the big feature of any decent volume manager because accurately predicting the size of filesystems is a black art, and the only alternative – to make the root filesystem contain all of the storage is a dumb idea.

It’s actually really easy and can be done non-disruptively. It is done in two parts – effectively growing the “disk” device and then growing the filesystem itself.

Extending The Volume

First identify the volume you need to extend. You can of course simply run lvscan which will show a list of the volumes, and if you have named them sensibly will allow you to pick out the volume to extend. But the simplest way is simply to run df to look at the filesystem you want to extend :-

/dev/mapper/ssd-opt         7.9G  5.5G  2.1G  73% /opt

The device (in the first column) is what we extend. Now to decide how much to grow the volume by; just for the case of this example, we’ll assume that 2Gbytes is a sensible amount to grow the volume by. The command needed is :-

lvextend --size +2G /dev/mapper/ssd-opt

And that’s it. No need to shut down the server, dismount the filesystem, etc. Of course we haven’t quite finished yet.

Growing The Filesystem

What we have done at this point is the equivalent of making the disk bigger. We also need to tell the filesystem it is sitting on a bigger disk, and to do so we need to know the type of the filesystem. The canonical place for checking that is the file /etc/fstab (actually it’s the filesystem itself but that is going too far) :-

# grep opt /etc/fstab
/dev/mapper/ssd-opt	/opt		ext4	noatime		0 3

It is probable that you are looking at growing an ext3, ext4, or xfs filesystem. If not you will have to look up the details yourself.

Growing ext3, or ext4 Filesystems

This is done with the resize2fs command :-

resize2fs /dev/mapper/ssd-opt

Several points :-

  1. Yes it can be done “online” whilst the filesystem is mounted (and applications are busy using it).
  2. You need to specify the device containing the filesystem to grow and not the mount point.
  3. There is no need to specify the size … the size will be determined from the size of the device underneath the filesystem.

Growing xfs Filesystems

This is done with the xfs_growfs command :-

# xfs_growfs /opt

Several points :-

  1. Yes, it can be done “online”. In fact you have to do it with the filesystem mounted.
  2. You need to specify the mountpoint of the filesystem and not the device. Irritatingly different from the above!
  3. There is no need to specify the size.

How Reliable Is This?

Very.

There is always the chance that something could go wrong especially if you are operating “at the edge” (say you have a filesystem that is unusually large – several petabytes). But I’ve done online filesystem resizing for years in countless circumstances without an issue.

I’ll quite happily do it on the most important systems during working hours without losing a moment’s thought. However I do work in a place that takes backups seriously!

Jan 112013
 

Customising keyboard maps in Linux is somewhat … confused with lots of different tools and layers to perform the same task. There are a number of tools for performing some form of keyboard mapping, but the most common ones have some disadvantages :-

  •  xkb (which is the modern X way), and xmodmap (which is deprecated but conveniently has a very simple syntax for dealing with a single key) both work fine for ordinary keys but cannot do anything with “unusual” keys not passed into X. Just look online for just how many people have trouble with multimedia keys not being recognised.
  • The PS/2-specific tools of dumpkeys, loadkeys, and setkeycodes which work fine, but are somewhat reluctant to help out with USB keyboards.
  • Plus the desktop environment you are using may well have its own idea of how the keyboard will be used (GNOME has a nasty tendency to grab the menu key away from me).

There is fortunately another way which is rather difficult to find information about. Which is the reason behind this posting of course.

This “other method” is to use the generic input system to perform the keyboard mapping which has certain advantages over other methods. Most of the information to do this came from a README file contained within the source code.

The Example Keyboard

To demonstrate keyboard mapping, it is helpful to have an example keyboard with custom mappings to play with. Many of the keyboards I use this for are rather complex with many mappings, but I also have a mini keyboard with relatively few mappings :-

Original Key new function
Esc Lock screen
`/~ Esc
Caps Lock Control
Insert Delete
Delete `/~

No great mystery as to why I want my keyboard mapped this way – I’m just fussy about keyboards.

The Basic “Tool”

In fact there is just one tool – /lib/udev/keymap – which performs all of the relevant tasks. Before it can do anything, it needs to be provided with the path of the relevant input device. This is easiest done from the console (rather than in X) as root. The easiest way of identifying the device is to unplug the keyboard, reboot the machine, and :-

# ls /dev/input/e* > /var/tmp/old.list
[Plug in keyboard]
# ls /dev/input/e* > /var/tmp/new.list
# diff /var/tmp/old.list /var/tmp/old.list
> /dev/input/event13
> /dev/input/event14

If you are lucky, there will be just one new input device. If not, you will have to try each one in turn. The first job is to record the keycode of each key to be customised in turn. To do this, it is necessary to run keymap with the input device and the “-i” option, and each keystroke will result in some output :-

# /lib/udev/keymap /dev/input/event13 -i
Press ESC to finish, or Control-C if this device is not your primary keyboard
scan code: 0x70029   key code: esc
# /lib/udev/keymap /dev/input/event13 -i
Press ESC to finish, or Control-C if this device is not your primary keyboard
scan code: 0x70035   key code: grave
scan code: 0x70039   key code: capslock
scan code: 0x70049   key code: insert
scan code: 0x7004C   key code: delete

A key can be mapped temporarily using keymap. But before that a list of possible key names is useful to have; there is one to be found in /usr/include/ :-

# grep KEY_ /usr/include/linux/input.h | less

The relevant name would be the part that follows the “KEY_” converted to lower-case.

# /lib/udev/keymap /dev/input/event13 0x70035 esc

But that is rather a temporary solution; it is better by far to create a file containing the necessary mappings to be automatically applied :-

# cat /tmp/custom-filco.map
0x70029 screenlock
#	Original: key code: esc
0x70035 esc
#	Original: key code: grave
0x70039 leftctrl
#	Original: key code: capslock
0x70049 delete
#	Original: key code: insert
0x7004C insert
#	Original: key code: delete

Making The Mappings Permanent

The first step is to obtain some details to uniquely (or as much as possible) identify the keyboard. Run :-

# udevadm info --export-db > /tmp/udev-db.txt

And look through the output for the input device you previously used. Look for a ID_VENDOR_ID and ID_MODEL_ID that you can use.

Next add a rule to /lib/udev/rules.d/95-keymap.rules along the lines of :-

ENV{ID_VENDOR_ID}=="04d9", ENV{ID_MODEL_ID}=="2011", RUN+="keymap $name custom-filco.map"

Once this is working you may want to add it to your version of custom-filco.map as a comment to preserve it for use after upgrades; alternatively you may wish to create a new file that will not get overwritten.

Before activating the new rule, remember to copy /tmp/custom-filco.map into /lib/keymaps/custom-filco.map. And again keep another copy in a safe place to preserve.

As to how to activate, a reboot is probably the simplest way.