前言
因为要实现类似ifconfig工具的作用,所以我们先要了解下argc和argv,接触linux系统,我们往往就需要用命令行的方式来编译和执行程序。那么在命令行方式下,此时这两个参数就很有作用了,能够非常方便地帮助我们实现一些功能。
argc和argc的含义
- argc为argument count的缩写,代表参数的个数
- argv为argument vector的缩写,可以理解成参数序列,表示传入main函数的参数序列或指针
如何理解
如何理解这两个参数,下面用举例说明:
代码
int main(int argc, char **argv)
{
printf("The value of argc is %d\n", argc);
printf("The values of argv are:\n");
for(int i = 0; i < argc; ++i)
printf("argv[%d] is %s\n", i, argv[i]);
}
执行命令:
sudo ./ifconfig_1.o ens33 up
执行结果:
The value of argc is 3
The values of argv are:
argv[0] is ./ifconfig_1.o
argv[1] is ens33
argv[2] is up
从这个输出结果就可以清晰地看出argc和argv的含义。argc就是参数的个数,就是命令行中以空格分隔的参数的个数,argv就是各个以空格分隔的参数字符串。
当然本ifconfig的配置功能也是使用此方法进行传参
完成的功能
通过可执行文件控制ens33网络接口的开启与关闭
代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/if.h>
#include <string.h>
#define INTERFACE "ens33"
int main(int argc, char **argv)
{
int fd;
struct ifreq buf[5]; //这个结构定义在/usr/include/net/if.h,用来配置和获取ip地址,掩码,MTU等接口信息的。 ifreq用来保存某个接口的信息
struct ifconf ifc; //ifconf通常是用来保存所有接口信息的
int ret = 0,i=0,j=0;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t) buf;
#if 1
printf("The value of argc is %d\n", argc);
printf("The values of argv are:\n");
for(int i = 0; i < argc; ++i)
printf("argv[%d] is %s\n", i, argv[i]);
#endif
if ((fd = socket(AF_INET, SOCK_DGRAM, 0))<0)
{
perror("socket" );
exit(1);
}
else
ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);
if(ret)
{
printf("get if config info failed");
return -1;
}
for (i=(ifc.ifc_len/sizeof (struct ifreq)); i>0; i--)
{
if((strcmp(argv[1],"ens33")==0 && strcmp(buf[j].ifr_name,"ens33")==0)||i == 1)
{
printf("------ens33网卡-------\n");
if(strcmp(argv[2],"up")==0)
{
printf("------ens33网卡 up-------\n");
strncpy(buf[j].ifr_name, INTERFACE, 5);
buf[j].ifr_flags |= IFF_UP;
ret = ioctl(fd, SIOCSIFFLAGS, (char*)&buf[j]);
if(ret)
continue;
}
else
{
printf("------ens33网卡 down -------\n");
strncpy(buf[j].ifr_name, INTERFACE, 5);
buf[j].ifr_flags &= ~IFF_UP;
ret = ioctl(fd, SIOCSIFFLAGS, (char*)&buf[j]);
if(ret)
continue;
}
}
j++;
}
close(fd);
return 0;
}
编译命令:
gcc ifconfig_1.c -o ifconfig_1.o
运行及结果
-
运行前使用通用工具ifconfig看下接口情况:
$ ifconfig ens33: flags=67<UP,BROADCAST,RUNNING> mtu 1500 inet 192.168.101.137 netmask 255.255.255.0 broadcast 192.168.101.255 inet6 fe80::ad50:e67b:b1bb:6fc5 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:24:11:8b txqueuelen 1000 (Ethernet) RX packets 32575 bytes 7985352 (7.9 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 22382 bytes 4418878 (4.4 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 1343 bytes 125873 (125.8 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1343 bytes 125873 (125.8 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ```
-
运行命令:
bash sudo ./ifconfig_1.o ens33 down
再使用ifconfig看下接口情况:$ ifconfig lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 1315 bytes 123629 (123.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1315 bytes 123629 (123.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ```
-
运行命令:
bash sudo ./ifconfig_1.o ens33 up
再使用ifconfig看下接口情况:$ ifconfig ens33: flags=67<UP,BROADCAST,RUNNING> mtu 1500 inet 192.168.101.137 netmask 255.255.255.0 broadcast 192.168.101.255 inet6 fe80::ad50:e67b:b1bb:6fc5 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:24:11:8b txqueuelen 1000 (Ethernet) RX packets 32575 bytes 7985352 (7.9 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 22382 bytes 4418878 (4.4 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 1343 bytes 125873 (125.8 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1343 bytes 125873 (125.8 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ```
结果
成功使用ifconfig_1.o可执行文件完成了接口的开启与关闭
注意
旨在用简单的代码框架完成所需目标,其余功能需自己更改添加,并且此例程只适用于本人,没有做到公共功能,框架清楚即可。