📅  最后修改于: 2023-12-03 15:00:13.183000             🧑  作者: Mango
在计算机网络中,IP地址、子网掩码和默认网关是非常重要的概念。在某些情况下,我们需要编写一个C程序来查找IP地址、子网掩码和默认网关,以便更好地了解网络配置和状态。
获取本地IP地址是一个相对简单的过程,可以使用系统调用来完成。以下是一个使用C程序获得本地IP地址的示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("%s: %s\n", ifa->ifa_name, host);
}
}
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
}
这个程序首先使用系统调用getifaddrs()获取网络接口的地址和子网掩码。for循环用于遍历获取到的网络接口,并使用getnameinfo()获取网络接口的IP地址和子网掩码。最后,使用printf()打印IP地址和子网掩码。
要查找默认网关,我们需要读取操作系统的路由表。以下是一个使用C程序获得默认网关的示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define DEFAULT_GW "0.0.0.0"
int main(int argc, char *argv[])
{
int fd;
struct sockaddr_in *sin;
struct rtentry rt;
memset(&rt, 0, sizeof(rt));
rt.rt_dst.sa_family = AF_INET;
inet_pton(AF_INET, DEFAULT_GW, &(rt.rt_gateway));
fd = socket(AF_INET, SOCK_DGRAM, 0);
ioctl(fd, SIOCADDRT, &rt);
close(fd);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (ioctl(fd, SIOCDELRT, &rt) < 0) {
perror("SIOCDELRE error");
exit(EXIT_FAILURE);
}
close(fd);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(ioctl(fd, SIOCGWADDR, &rt) < 0) {
printf("ioctl failed:%d\n", errno);
exit(EXIT_FAILURE);
}
sin = (struct sockaddr_in *)&rt.rt_gateway;
printf("gateway:%s\n", inet_ntoa(sin->sin_addr));
return 0;
}
这个程序首先创建一个路由表项,随后将路由表项添加到系统路由表中。然后,通过SIOCGWADDR系统调用获取默认网关的IP地址。最后,使用printf()打印默认网关。
获取子网掩码需要读取操作系统配置。以下是一个使用C程序获得默认网关的子网掩码的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
void get_subnet_mask(char *ifname)
{
struct ifaddrs *ifaddr, *ifa;
struct sockaddr_in *sa;
char *addr = NULL;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs error");
exit(EXIT_FAILURE);
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (strcmp(ifa->ifa_name, ifname) != 0)
continue;
if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
continue;
sa = (struct sockaddr_in *)ifa->ifa_netmask;
addr = inet_ntoa(sa->sin_addr);
printf("subnet mask: %s\n", addr);
}
freeifaddrs(ifaddr);
}
int main(int argc, char *argv[])
{
char *ifname = "eth0";
get_subnet_mask(ifname);
return 0;
}
这个程序遍历获取到的网络接口,查找指定接口的子网掩码。然后,使用inet_ntoa()函数将子网掩码的二进制表示转换为点分十进制表示,并使用printf()打印子网掩码。
上面的程序展示了如何使用C程序查找IP地址、子网掩码和默认网关。这些信息可以用于诊断网络问题,找出网络配置问题,以及进行网络编程时需要的信息。