Sunday, September 24, 2006

 

linux ifconfig compact output - part 3

Modifying the source code for the purpose here,
changing the output a bit, should be easy.
printf() is what we should look for.

main() calls if_print();
if_print() calls for_all_interfaces(do_if_print) or ife_print(struct interface);
for_all_interfaces() is not defined in ifconfig.c, do_if_print is the callback;
do_if_print() not in ifconfig.c;
ife_print() not in ifconfig.c;
all three are in lib/interface.c;
do_if_print() calls ife_print();


ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:3B:F3:69
inet addr:10.27.11.106 Bcast:255.255.255.0 Mask:255.255.252.0
inet6 addr: fe80::20c:29ff:fe3b:f369/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:14026085 errors:7 dropped:11 overruns:0 frame:0
TX packets:8917277 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2957627992 (2.7 GiB) TX bytes:2694684505 (2.5 GiB)
Interrupt:17 Base address:0x1080


The words "Link", "encap", "HWaddr", tell us where to look
for the printf() calls.
Turns out the source code if very well organized.
It was easy to find where and what to modify.


ifconfig.c
main()
...
else if (!strcmp(*argv, "-s"))
ife_short = 1;

else if (!strcmp(*argv, "-c"))
ife_compact = 1;

else if (!strcmp(*argv, "-v"))
opt_v = 1;



So a variable ife_short is used for "short" output.
We follow that and use a variable "ife_compact"
for our "compact" output.


include/interface.h
...
extern int ife_short;
extern int ife_compact;

Here we follow the existing practice.



lib/interface.c
...
int ife_short;
int ife_compact;
...
void ife_print_compact(struct interface *ptr)
{
struct aftype *ap;
struct hwtype *hw;
int hf;
int can_compress = 0;
unsigned long long rx, tx, short_rx, short_tx;
const char *Rext = "b";
const char *Text = "b";

ap = get_afntype(ptr->addr.sa_family);
if (ap == NULL)
ap = get_afntype(0);

hf = ptr->type;

if (hf == ARPHRD_CSLIP || hf == ARPHRD_CSLIP6)
can_compress = 1;

hw = get_hwntype(hf);
if (hw == NULL)
hw = get_hwntype(-1);

printf(_("%s encap:%s "), ptr->name, hw->title);
if (hw->print != NULL && (! (hw_null_address(hw, ptr->hwaddr) && hw->suppress_null_addr) ))
printf(_("HWaddr:%s "), hw->print(ptr->hwaddr));
else
printf(_("HWaddr:null "));

#if HAVE_AFINET
if (ptr->has_ip) {
printf(_("%s:%s "), ap->name, ap->sprint(&ptr->addr, 1));
printf(_("Mask:%s "), ap->sprint(&ptr->netmask, 1));
}
#endif

if (ptr->flags & IFF_UP) printf(_("UP "));
if (ptr->flags & IFF_RUNNING) printf(_("RUNNING "));
printf(_("MTU:%d"), ptr->mtu);
printf("\n");
}

...
void ife_print(struct interface *i)
{
if (ife_short)
ife_print_short(i);
else if (ife_compact)
ife_print_compact(i);
else
ife_print_long(i);
}



Now we need to recompile.
I didnt find the rpmbuild option to just recompile.
"-ba" is not what we need. It would extract the source files
and over-write our changes.

What I did was to compile "manually".

cd lib
make
cd ..
make ifconfig

cc -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -DHAVE_SELINUX -D_GNU_SOURCE -O2 -Wall -g -I. -idirafter ./include/ -Ilib -c -o ifconfig.o ifconfig.c
cc -lselinux -Llib -o ifconfig ifconfig.o -lnet-tools


The last two "cc" commands, are what "rpmbuild -ba ..." invoked.

Comments: Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?