Rethtool: How I Learned to Stop Worrying and Love the ioctl

Posted: Sat, 17 December 2011 | permalink | 2 Comments

Damn those unshaven yaks

I’m trying to write a Nagios plugin for work that will comprehensively monitor network interfaces and make sure they’re up, passing traffic, all those sorts of things. Of course, I’m doing it all in Ruby, because that’s how I roll.

So, I need to Know Things about the interface. Everyone does that with ethtool. Right? Sure, if your eyeballs are parsing it. But have you ever tried to machine parse it? To put it as eloquently as possible:

# ethtool eth0
Settings for eth0:
 Supported ports: [ TP MII ]
 Supported link modes:   10baseT/Half 10baseT/Full 
                         100baseT/Half 100baseT/Full 
                         1000baseT/Half 1000baseT/Full 
 Supports auto-negotiation: Yes
 Advertised link modes:  10baseT/Half 10baseT/Full 
                         100baseT/Half 100baseT/Full 
                         1000baseT/Half 1000baseT/Full 
 Advertised pause frame use: No
 Advertised auto-negotiation: Yes
 Link partner advertised link modes:  10baseT/Half 10baseT/Full 
                                      100baseT/Half 100baseT/Full 
                                      1000baseT/Half 1000baseT/Full 
 Link partner advertised pause frame use: No
 Link partner advertised auto-negotiation: Yes
 Speed: 1000Mb/s
 Duplex: Full
 Port: MII
 PHYAD: 0
 Transceiver: internal
 Auto-negotiation: on
 Supports Wake-on: pumbg
 Wake-on: g
 Current message level: 0x00000033 (51)
 Link detected: yes

Parse that, bitch!

Or… perhaps not.

At any rate, I decided that it would be most advantageous if I went straight to the source and twiddle the ioctl until it did my bidding.

And thus, about 5 hours later, was Rethtool born.

Once I worked out a less-than-entirely-crackful way of dealing with C structs in Ruby (after a bit of digging around, I went with the appallingly-undocumented-but-sufficiently-featureful CStruct), and after I finally worked out I was passing the wrong damned struct to ioctl(SIOCETHTOOL) (speaking of appallingly-undocumented: fuck you, ioctl, and all your twisty-passages children), it was smooth sailing.

So, if you’re one of the eight or so people on earth who will ever need to get at the grubby internals of your network interfaces using Ruby (and can’t do it via some sysfs magic), Rethtool is for you.


2 Comments

From: Ben Hutchings
2011-12-17 17:41

I am the current maintainer of the ethtool command and effective maintainer for the ethtool interface in the kernel.

I agree that the output of ethtool is unsuitable for machine parsing. But I’m also sure that many scripts do parse it, so I have to be pretty conservative about changing it.

All interface ioctls are sent using struct ifreq (how else are you going to specify the interface name?) but I’m not sure where this is documented. I’ve been gradually improving the definitions of the ethtool operations; if there are any gaps you run into then please send queries or corrections to netdev@vger.kernel.org.

By the way, there are ethtool bindings for some other languages already.

From: Matt Palmer
2011-12-17 18:01

Ben,

I agree that changing the default output of ethtool is probably going to make a lot of scripts rather unhappy. A --machine-readable option, to provide a trivially-parseable output format would be backwards-compatible and no doubt greatly appreciated by many, if you had a mind to do some hacking.

The lack of documentation wasn’t intended to be a SIOCETHTOOL-specific complaint; I don’t think I’ve ever come across an ioctl, network-related or otherwise, that didn’t require a lot of grovelling around in dark corners to work out how to use.

Post a comment

All comments are held for moderation; markdown formatting accepted.

This is a honeypot form. Do not use this form unless you want to get your IP address blacklisted. Use the second form below for comments.
Name: (required)
E-mail: (required, not published)
Website: (optional)
Name: (required)
E-mail: (required, not published)
Website: (optional)