summary refs log tree commit diff
path: root/posix/tst-rfc3484-3.c
blob: 701f534bb168e745e82954186e4a706a759928fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <stdbool.h>
#include <stdio.h>
#include <ifaddrs.h>

/* Internal definitions used in the libc code.  */
#define __getservbyname_r getservbyname_r
#define __socket socket
#define __getsockname getsockname
#define __inet_aton inet_aton
#define __gethostbyaddr_r gethostbyaddr_r
#define __gethostbyname2_r gethostbyname2_r

void
attribute_hidden
__check_pf (bool *p1, bool *p2, struct in6addrinfo **in6ai, size_t *in6ailen)
{
  *p1 = *p2 = true;
  *in6ai = NULL;
  *in6ailen = 0;
}

void
attribute_hidden
__free_in6ai (struct in6addrinfo *ai)
{
}

void
attribute_hidden
__check_native (uint32_t a1_index, int *a1_native,
		uint32_t a2_index, int *a2_native)
{
}

int
attribute_hidden
__idna_to_ascii_lz (const char *input, char **output, int flags)
{
  return 0;
}

int
attribute_hidden
__idna_to_unicode_lzlz (const char *input, char **output, int flags)
{
  *output = NULL;
  return 0;
}

void
attribute_hidden
_res_hconf_init (void)
{
}

#include "../sysdeps/posix/getaddrinfo.c"

service_user *__nss_hosts_database attribute_hidden;


/* This is the beginning of the real test code.  The above defines
   (among other things) the function rfc3484_sort.  */


#if __BYTE_ORDER == __BIG_ENDIAN
# define h(n) n
#else
# define h(n) __bswap_constant_32 (n)
#endif

struct sockaddr_in addrs[] =
{
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a86d1d) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a85d03) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a82c3d) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a86002) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a802f3) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a80810) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xa0a85e02) } },
  { .sin_family = AF_INET, .sin_addr = { h (0xac162311) } },
  { .sin_family = AF_INET, .sin_addr = { h (0x0a324572) } }
};
#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
static struct addrinfo ais[naddrs];
static struct sort_result results[naddrs];
static size_t order[naddrs];

static const int expected[naddrs] =
  {
    8, 0, 1, 2, 3, 4, 5, 6, 7
  };

static const struct scopeentry new_scopes[] =
  {
    { { { 169, 254, 0, 0 } }, h (0xffff0000), 2 },
    { { { 127, 0, 0, 0 } }, h (0xff000000), 2 },
    { { { 10, 0, 0, 0 } }, h (0xff000000), 5 },
    { { { 192, 168, 0, 0 } }, h(0xffff0000), 5 },
    { { { 0, 0, 0, 0 } }, h (0x00000000), 14 }
  };


ssize_t
__getline (char **lineptr, size_t *n, FILE *s)
{
  *lineptr = NULL;
  *n = 0;
  return 0;
}


static int
do_test (void)
{
  labels = default_labels;
  precedence = default_precedence;
  scopes= new_scopes;

  struct sockaddr_in so;
  so.sin_family = AF_INET;
  so.sin_addr.s_addr = h (0x0aa85f19);
  /* Clear the rest of the structure to avoid warnings.  */
  memset (so.sin_zero, '\0', sizeof (so.sin_zero));

  for (int i = 0; i < naddrs; ++i)
    {
      ais[i].ai_family = AF_INET;
      ais[i].ai_addr = (struct sockaddr *) &addrs[i];
      results[i].dest_addr = &ais[i];
      results[i].got_source_addr = true;
      memcpy(&results[i].source_addr, &so, sizeof (so));
      results[i].source_addr_len = sizeof (so);
      results[i].source_addr_flags = 0;
      results[i].prefixlen = 8;
      results[i].index = 0;

      order[i] = i;
    }

  struct sort_result_combo combo = { .results = results, .nresults = naddrs };
  qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);

  int result = 0;
  for (int i = 0; i < naddrs; ++i)
    {
      struct in_addr addr = ((struct sockaddr_in *) (results[order[i]].dest_addr->ai_addr))->sin_addr;

      int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
			 sizeof (struct in_addr));
      printf ("[%d] = %s: %s\n", i, inet_ntoa (addr), here ? "FAIL" : "OK");
      result |= here;
    }

  return result;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"