Ticket #17901: test_loopback_interface.c

File test_loopback_interface.c, 2.2 KB (added by teor, 4 years ago)

Test for OpenVZ 127.0.0.1 on non-loopback interface

Line 
1/* Test whether loopback addresses and flags are configured in a
2 * standards-conforming manner.
3 * teor, 2016, CC-0 (Public Domain) */
4
5#include <arpa/inet.h>
6#include <assert.h>
7#include <ifaddrs.h>
8#include <net/if.h>
9#include <netinet/in.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <unistd.h>
14
15int
16main(int argc, char** argv) {
17  (void)argc;
18  (void)argv;
19
20  struct ifaddrs *ifap = NULL;
21  int rv = 0;
22  rv = getifaddrs(&ifap);
23  assert(ifap != NULL);
24
25  struct ifaddrs *ifa = ifap;
26  while (ifa != NULL) {
27    int loopback_flag = ifa->ifa_flags & IFF_LOOPBACK;
28    int loopback_addr = 0;
29
30    int af = ifa->ifa_addr->sa_family;
31
32#define UNKNOWN_AF_FMT "unknown family %d"
33
34    int addr_strlen = strlen(UNKNOWN_AF_FMT) + 1 + 20 /* 64 bit %d INT_MAX*/;
35    if (af == AF_INET6) {
36      addr_strlen = INET6_ADDRSTRLEN;
37    } else if (af == AF_INET) {
38      addr_strlen = INET_ADDRSTRLEN;
39    }
40
41    char *addr_str = malloc(addr_strlen);
42    assert(addr_str != NULL);
43
44    if (af == AF_INET6) {
45      struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)ifa->ifa_addr;
46      uint32_t *addr32 = (uint32_t *)&addr_in6->sin6_addr.s6_addr;
47      /* Check if IPv6 address is ::1 */
48      loopback_addr = (addr32[0] == 0 && addr32[1] == 0 && addr32[2] == 0
49                       && ntohl(addr32[3]) == 1);
50      const char *res = inet_ntop(af, &addr_in6->sin6_addr, addr_str,
51                                  addr_strlen);
52      assert(res != NULL);
53      assert(res == addr_str);
54    } else if (af == AF_INET) {
55      struct sockaddr_in *addr_in = (struct sockaddr_in *)ifa->ifa_addr;
56      /* Check if IPv4 address is 127.0.0.0/8 */
57      loopback_addr = ((ntohl(addr_in->sin_addr.s_addr) & 0xff000000)
58                       == (INADDR_LOOPBACK & 0xff000000));
59      const char *res = inet_ntop(af, &addr_in->sin_addr, addr_str,
60                                  addr_strlen);
61      assert(res != NULL);
62      assert(res == addr_str);
63    } else {
64      snprintf(addr_str, addr_strlen, UNKNOWN_AF_FMT, af);
65    }
66   
67    if (loopback_flag || loopback_addr) {
68      printf("%10s %30s loopback %1sflag %1saddr\n", ifa->ifa_name,
69             addr_str, loopback_flag ? "" : "~", loopback_addr ? "" : "~");
70    }
71
72    free(addr_str);
73    ifa = ifa->ifa_next;
74  }
75
76  freeifaddrs(ifap);
77   
78  return 0;
79}