[Toybox] [CLEANUP] Ifconfig commit 919

Rob Landley rob at landley.net
Sun Jun 2 19:12:17 PDT 2013

Commit 919:


Starting with a couple of side items, I inlined the last instance of  
set_flags(), and
refactored bits of get_device_info(). (Reordered a couple of lines but  
no significant
code changes there.)

I made readconf() use xsocket(), cleaned up the size finding loop, and  
removed a NOP
errno assignment. I also removed hasaddr, and instead just checked if  
the address
field has any nonzero bits. (You can't assign to an interface,  
it's a
broadcast address.)

And then the big todo item this patch: in ifconfig_main(), introduce  
and poke(), and use them it to move another ~dozen command line option  
into the table.

Most of the collated option handlers just set one field in ifre and call
an ioctl. The SIOCSIFMAP ones need a corresponding SIOCGIFMAP call first
(S for set, G for get), and two of them are actually NOPs (so both  
are 0).

For the 'set one field, call an ioctl' ones, we need four pieces of

   1) A way to indicate of this new category of action
   2) Offset of field in ifre.
   3) Size of field in ifre.
   4) ioctl to call

We already hijacked "off" to store #4 in commit 906, but the first 3  
to be packed into "on". Let's look more closely at #1:

The original action was setting flags via an  
sandwich with ifre.ifr_flags twiddling in between.

Then we overloaded the "off" field to indicate a different ioctl to  
eating the next command line argument (*argv++) as a network address  
to ifre.ifr_flags. This was indicated by "(off & 0xFFFFFF00) == 0x8900"  
is never a valid flag combination. (All the ioctl macros we're using  
with 0x89, because the old _IO(type,nr) macros had 0x89 as the type for
"socket" ioctls. See "man 2 ioctl_list" for details.)

The new action consumes *argv as an unsigned long and assigns it
to an arbitrary field of ifre, then calls the ioctl. We can indicate  
by putting a negative value in "on", because there's no IFF_FLAG macro
that sets the top bit so no combination of flags will give a negative  

As for the other 2 pieces of information, the offset's never going to be
bigger than 64k and the size is at most 8, so we can bit shift them  
then negate the result.

The IFREQ_OFFSZ() macro combines a field's offset and size into the  
same int
(size << 16 + offset), and then negates it to signal how to handle it.  
isn't an IFF_FLAG for 0x80000000 so no combiantion of flags can be  

The new table entries have IFREQ_OFFSZ() in "on" and the IOCTL to call  
in "off".
If "on" is less than zero, we convert the next argument to an unsigned  
(I.E. strtoul(*argv)). Then we use the size and offset with the "poke()"
function, which writes a value to a location at a power of two size.
(In theory you could memcpy it, but for big endian machines memcpy
2 bytes from the start of an int into a short will give you the wrong  

This brings us down under 700 lines (688).

More information about the Toybox mailing list