[Toybox] [CLEANUP] Ifconfig commit 919
Rob Landley
rob at landley.net
Sun Jun 2 19:12:17 PDT 2013
Commit 919:
http://landley.net/hg/toybox/rev/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 0.0.0.0 to an interface,
it's a
broadcast address.)
And then the big todo item this patch: in ifconfig_main(), introduce
IFREQ_OFFSZ()
and poke(), and use them it to move another ~dozen command line option
handlers
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
fields
are 0).
For the 'set one field, call an ioctl' ones, we need four pieces of
information:
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
have
to be packed into "on". Let's look more closely at #1:
The original action was setting flags via an
ioctl(SIOCGIFFLAGS/SIOCSIFFLAGS)
sandwich with ifre.ifr_flags twiddling in between.
Then we overloaded the "off" field to indicate a different ioctl to
call,
eating the next command line argument (*argv++) as a network address
assigned
to ifre.ifr_flags. This was indicated by "(off & 0xFFFFFF00) == 0x8900"
which
is never a valid flag combination. (All the ioctl macros we're using
start
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
this
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
value.
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
together
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.
(There
isn't an IFF_FLAG for 0x80000000 so no combiantion of flags can be
negative.)
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
long
(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
bytes.)
This brings us down under 700 lines (688).
More information about the Toybox
mailing list