int main(int argc, char **argv)
{
……
argc--;
argv++;
while (argc
&& *argv[0] == '-') {
……
}
打开内核支持的所有协议的套接字,主要是一个循环调用socket的过程
if ((skfd = sockets_open(0))
< 0) {
perror("socket");
exit(1);
}
if (argc == 0) {
int err = if_print((char *) NULL);
(void) close(skfd);
exit(err < 0);
}
spp = argv;
safe_strncpy(ifr.ifr_name,
*spp++, IFNAMSIZ);
if (*spp == (char *) NULL)
{
int err = if_print(ifr.ifr_name);
(void) close(skfd);
exit(err < 0);
}
if ((ap = get_aftype(*spp))
!= NULL)
spp++;
else
ap = get_aftype(DFLT_AF);
if (ap) {
addr_family = ap->af;
skfd = ap->fd;
}
while (*spp != (char *) NULL)
{
}
switch
(ap->af) {
……
r = ioctl(fd, SIOCSIFADDR,
&ifr);
……
}
在主函数中判断argc,如果仅仅是输入了ifconfig而没有任何参数,则输出全部网卡信息
if (argc == 0) {
int err = if_print((char *) NULL);
(void) close(skfd);
exit(err < 0);
}
函数if_print 定义在ifconfig.c中,用来输出网卡地址等信息:
static int if_print(char *ifname)
{
int res;
if
(ife_short)
//如果是以省略模式输出
printf(_("Iface
MTU Met
RX-OK RX-ERR RX-DRP RX-OVR
TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
if (!ifname)
{
//如果ifname==NULL,则表示输出全部网卡的信息
res = for_all_interfaces(do_if_print,
&opt_a);
} else {
//否则仅仅输出ifname的。
struct interface *ife;
ife = lookup_interface(ifname);
res = do_if_fetch(ife);
if (res >= 0)
ife_print(ife);
}
return res;
}
这里,又涉及到两个函数的调用:for_all_interfaces和lookup_interface。先来看for_all_interfaces
函数在interface.c中实现:
参数int (*doit) (struct interface *, void
*)是一个指向函数的指针,为实际的功能函数,在上层函数中传递过来的是do_if_print
int for_all_interfaces(int (*doit) (struct interface *, void *),
void *cookie)
{
struct interface *ife;
if (!int_list
&& (if_readlist() <
0))
return -1;
for (ife = int_list; ife; ife
= ife->next) {
int err = doit(ife, cookie);
//调用函数do_if_print实现
if (err)
return
err; |