一个简单的C程序,模拟了ifconfig命令的功能,包括设置指定网络接口的IP地址、MAC地址和MTU
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// 显示网络接口信息
void show_interface_info(char *ifname)
{
int sockfd;
struct ifreq ifr;
struct sockaddr_in *sin;
char ipaddr[INET_ADDRSTRLEN];
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
return;
}
// 获取网络接口信息
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
printf("%s: HWaddr %02x:%02x:%02x:%02x:%02x:%02x\n", ifname,
(unsigned char)ifr.ifr_hwaddr.sa_data[0], (unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2], (unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4], (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
if (ioctl(sockfd, SIOCGIFMTU, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
printf(" MTU:%d\n", ifr.ifr_mtu);
if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
sin = (struct sockaddr_in *)&ifr.ifr_addr;
inet_ntop(AF_INET, &sin->sin_addr, ipaddr, sizeof(ipaddr));
printf(" inet addr:%s\n", ipaddr);
// 关闭socket
close(sockfd);
}
// 设置网络接口IP地址
void set_interface_ip(char *ifname, char *ipaddr)
{
int sockfd;
struct ifreq ifr;
struct sockaddr_in sin;
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
return;
}
// 设置网络接口IP地址
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
sin.sin_family = AF_INET;
inet_pton(AF_INET, ipaddr, &sin.sin_addr);
memcpy(&ifr.ifr_addr, &sin, sizeof(sin));
if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
// 关闭socket
close(sockfd);
}
// 设置网络接口MAC地址
void set_interface_mac(char *ifname, char *macaddr)
{
int sockfd;
struct ifreq ifr;
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
return;
}
// 设置网络接口MAC地址
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
ifr.ifr_hwaddr.sa_family = 1;
sscanf(macaddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&ifr.ifr_hwaddr.sa_data[0], &ifr.ifr_hwaddr.sa_data[1],
&ifr.ifr_hwaddr.sa_data[2], &ifr.ifr_hwaddr.sa_data[3],
&ifr.ifr_hwaddr.sa_data[4], &ifr.ifr_hwaddr.sa_data[5]);
if (ioctl(sockfd, SIOCSIFHWADDR, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
// 关闭socket
close(sockfd);
}
// 设置网络接口MTU
void set_interface_mtu(char *ifname, int mtu)
{
int sockfd;
struct ifreq ifr;
// 创建socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
return;
}
// 设置网络接口MTU
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ-1);
ifr.ifr_mtu = mtu;
if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) {
perror("ioctl");
close(sockfd);
return;
}
// 关闭socket
close(sockfd);
}
int main(int argc, char **argv)
{
// 显示指定网络接口的信息
if (argc > 1) {
show_interface_info(argv[1]);
}
// 设置指定网络接口的IP地址、MAC地址和MTU
if (argc > 2) {
if (strcmp(argv[2], "ip") == 0 && argc > 3) {
set_interface_ip(argv[1], argv[3]);
}
else if (strcmp(argv[2], "mac") == 0 && argc > 3) {
set_interface_mac(argv[1], argv[3]);
}
else if (strcmp(argv[2], "mtu") == 0 && argc > 3) {
set_interface_mtu(argv[1], atoi(argv[3]));
}
else {
printf("Usage: %s <interface> [ip <ipaddr>|mac <macaddr>|mtu <mtu>]\n", argv[0]);
}
}
// 显示所有网络接口的信息
else {
printf("Usage: %s <interface> [ip <ipaddr>|mac <macaddr>|mtu <mtu>]\n", argv[0]);
printf("Available interfaces:\n");
struct if_nameindex *if_nidxs, *p;
if_nidxs = if_nameindex();
if (if_nidxs == NULL) {
perror("if_nameindex");
return 1;
}
for (p = if_nidxs; p->if_index != 0 || p->if_name != NULL; p++) {
printf("%s\n", p->if_name);
}
if_freenameindex(if_nidxs);
}
return 0;
}