📜  C程序查找IP地址,子网掩码和默认网关(1)

📅  最后修改于: 2023-12-03 15:00:13.183000             🧑  作者: Mango

C程序查找IP地址,子网掩码和默认网关

在计算机网络中,IP地址、子网掩码和默认网关是非常重要的概念。在某些情况下,我们需要编写一个C程序来查找IP地址、子网掩码和默认网关,以便更好地了解网络配置和状态。

获取本地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地址、子网掩码和默认网关。这些信息可以用于诊断网络问题,找出网络配置问题,以及进行网络编程时需要的信息。