Tuesday, April 12, 2011

Listing All Network Devices on Linux: finding how

A continuation of my previous post. (thanks for the help from hly).

int main(int argc, char **argv)
  char **argv is the same as char * argv[]

To find how to list all network devices, use the ifconfig source code, starting with the "ifconfig.c" file.

Goal: find the code that generates the "Iface" devices (left-most column of below).

$ ifconfig -s
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500 0         0      0      0 0             0      0      0      0 BMU
lo        16436 0      9359      0      0 0          9359      0      0      0 LRU
vmnet1     1500 0         0      0      0 0          1122      0      0      0 BMRU
vmnet8     1500 0         0      0      0 0          1122      0      0      0 BMRU
wlan0      1500 0    275975      0      0 0        223090      0      0      0 BMRU

Inside "ifconfig.c", I searched for "-s" and got
263     else if (!strcmp(*argv, "-s"))
264         ife_short = 1;

So then I searched for "ife_short", and found it inside "if_print()", which:
1. prints out the top row of text.
-. Since we don't have an ifname specified (like "eth0" or "vmnet8"), we can't just simply lookup_interface(ifname) to get the ife and use
-. do_if_fetch(ife) to check that the ife interface/device is still good (it uses if_fetch())
-. if so, print that ife with ife_print_short(), the column we want is printf("%-5.5s ", ptr->name);
103 static int if_print(char *ifname)
 104 {
 105     int res;
 106 
 107     if (ife_short)
 108         printf(_("Iface   MTU Met    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX     -OVR Flg\n"));
 109 
 110     if (!ifname) {
 111         res = for_all_interfaces(do_if_print, &opt_a);
 112     } else {
 113         struct interface *ife;
 114 
 115         ife = lookup_interface(ifname); //ife means "interface"
 116         res = do_if_fetch(ife);
 117         if (res >= 0)
 118             ife_print(ife);
 119     }
 120     return res;
 121 }

2. We'll instead do "for_all_interfaces()", which gets all the interfaces (see lib/interface.c)
128 int for_all_interfaces(int (*doit) (struct interface *, void *), void *cookie)
129 {
130     struct interface *ife;
131 
132     if (!int_list && (if_readlist() < 0))
133         return -1;
134     for (ife = int_list; ife; ife = ife->next) {
135         int err = doit(ife, cookie);
136         if (err)
137             return err;
138     }
139     return 0;
140 }

Stuck. Victor told me to look at if_readlist(). "It seems that this function is iterating over the return array and feeding each item to a callback."

to-do ask:
1. Is my above resoning correct?
2. If so, how does for_all_interfaces() work? lib/interface.c Look at if_readlist()
3. How do I make this so I can test it? (I don't want it to screw up my ifconfig, test it in the directory (+m ifconfig.c and then ./ doesn't work))
4. is getting interface from IP addresses helpful at all? with the getifaddrs(): from stack overflow question and from IBM.

No comments:

Post a Comment