[Toybox] Finishing ifconfig cleanup!
Rob Landley
rob at landley.net
Fri Nov 29 22:49:27 PST 2013
This is really 1129 through 1133, but let's focus on:
http://landley.net/hg/toybox/rev/1133
The last post didn't mention the "try to compile, fix the obvious build
breaks, debug a weird thing..." part where get_addrinfo() was copying
addresses with the wrong size and the wrong offset because
rp->ai_addr->sa_data is "struct sockaddr", not the actual struct
in_addr or struct in6_addr. wheee.
Both of them have "family" and "port". sockaddr_in6 says family is an
unsigned short int (2 bytes ala LP64), and then port is __be16 (2
bytes). Meanwhile sockaddr_in says family is __kernel_sa_family_t
(which is also 2 bytes but you have to go digging to confirm it), and
then sin_port is __be16.
EXTRA FUN: the ipv6 one has a third field before the address, __be32
flowinfo. whatever that is, adds 4 bytes to the offset. So for ipv4
it's offset 4, size 4, and for ipv6 it's offset 8 size 16. The ipv4
sockaddr makes a big deal about struct sockaddr fitting in 16 bytes for
all sockaddr types, and the ipv6 one doesn't. (But infiniband didn't
get extra space to let the ioctl set its address correctly, because
Intel shares the "do not care" attribute with honey badgers,
apparently.)
Right. I'm just going to do byte offsets here. I'm aware it's cheating,
but it works with just one codepath and should be ok on all Linux
targets, and whoever laid out the ipv6 structures needs to be punished.
Next day: I screwed up and missed that I did a lib/lib.c atolx_range()
function that this is using now, so check _that_ in so this builds
again for people other than me. (That was commit 1131.)
Clean up the sockaddr nonsense described above so it's not using
sa_data out of the ai_addr field (which skips "family" but not "port",
so the extra level of dereferencing serves no useful purpose. Just add
the 4 bytes manually as described above; that's now how I coded it the
first time but as usual writing up documentation makes me change the
code to be something easier to explain. :)
Redoing the help text at the top, and... what the heck are "trailers"
and "dynamic"? The ubuntu ifconfig man page doesn't mention them. Let's
see, they set IFF_NOTRAILERS and IFF_DYNAMIC which are... only
mentioned once in the kernel source, the syscall passes them through in
The Great Unmasking and then nothing else ever uses those flags. what?
Let's see, include/uapi/linux/if.h #defines them, and using my "git
history back to 1991" tree, annotate says IFF_DYNAMIC was added by
Linux 2.1.127 (commit c10fbfad61d6 in the big tree) in 1998 with
comment "/* dialup device with changing addresses */", as a flag passed
through in net/core/dev.c but never used by anything else. And it still
isn't.
IFF_NOTRAILERS is from 1993, Linux 0.99.10 (commit 54c93c05f69e in the
big tree) which was "the big switch-over version" from Ross Biro's
net-1 to Fred van Kempen's net-2. "fsync() isn't just a stub any more,
and System V IPC is also showing up." so yeah, pretty early on. Once
again, the commit introducing it added the #define to the header and
the flag to the syscall mask, and that's it. No code ever used it for
anything.
So I'm yanking them both. The kernel does nothing with these flags, and
never has.
Next up: what do "outfill", "keepalive", and "metric" do? Let's see,
OUTFILL and KEEPALIVE are both from linux 1.3.61 in 1996 (commit
76086e13f472) which added:
+CONFIG_SLIP_SMART
+ Adds additional capabilities to the SLIP driver to support the
RELCOM
+ line fill and keepalive monitoring. Ideal on poor quality
analogue lines.
So just _deeply_ relevant in 2013. I could either yank it, or say
something like "obsolete SLIP analog dialup line quality monitoring".
Either way...
And metric was added to sockios.h in 1993 also by commit 54c93c05f69e
(linux 0.99.10 again), with the informative comment "get metric" and
"set metric". So it sets dev->metric in struct ifnet which had the
comment "/* routing metric (not used) */". Great. That one IS still
documented in ifconfig's man page but it just says "This parameter sets
the interface metric." without ever hinting at what that MEANS. Because
in Linux, it means nothing. The field can be set and read back, but is
never used.
Sigh. Alas, it's a prominent part of the ifconfig output and removing
it might break stuff.
Speaking of "Sigh", I want to document that to use promisc these days
you have to throw a switch into hub mode, and the easy way to do that
is to fill up its ARP table and force it to degrade to broadcast. I.E.
set your interface to a random mac address and send a packet (ping the
gateway or something), and repeat a couple thousand times. The switch
will have too many mac addresses to store in its tiny little brain and
will degrade to sending all packets to all interfaces, I.E. hub mode.
If you DON'T do that, promisc mode is useless on modern hardware
because the switch only sends you packets for your hardware address.
(There might also be some arp magic to request a copy of everything,
but if so I don't know it and it doesn't happen automatically the way
normal arp does.)
But that entire digression is waaaay to long for toybox help text.
Ok, group obsolete fields. Think of adding a config option but A) they
can't currently edit help text much, B) it wouldn't save much space.
Possibly somebody should send a patch upstream to yank trailers and
dynamic (and for that matter metric). But meanwhile?
Ifconfig cleanup: done.
Rob
More information about the Toybox
mailing list