1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "testutil.h"
18#include "apr_general.h"
19#include "apr_network_io.h"
20#include "apr_errno.h"
21
22static void test_bad_input(abts_case *tc, void *data)
23{
24    struct {
25        const char *ipstr;
26        const char *mask;
27        apr_status_t expected_rv;
28    } testcases[] =
29    {
30        /* so we have a few good inputs in here; sue me */
31        {"my.host.name",       NULL,               APR_EINVAL}
32        ,{"127.0.0.256",       NULL,               APR_EBADIP}
33        ,{"127.0.0.1",         NULL,               APR_SUCCESS}
34        ,{"127.0.0.1",         "32",               APR_SUCCESS}
35        ,{"127.0.0.1",         "1",                APR_SUCCESS}
36        ,{"127.0.0.1",         "15",               APR_SUCCESS}
37        ,{"127.0.0.1",         "-1",               APR_EBADMASK}
38        ,{"127.0.0.1",         "0",                APR_EBADMASK}
39        ,{"127.0.0.1",         "33",               APR_EBADMASK}
40        ,{"127.0.0.1",         "255.0.0.0",        APR_SUCCESS}
41        ,{"127.0.0.1",         "255.0",            APR_EBADMASK}
42        ,{"127.0.0.1",         "255.255.256.0",    APR_EBADMASK}
43        ,{"127.0.0.1",         "abc",              APR_EBADMASK}
44        ,{"127",               NULL,               APR_SUCCESS}
45        ,{"127.0.0.1.2",       NULL,               APR_EBADIP}
46        ,{"127.0.0.1.2",       "8",                APR_EBADIP}
47        ,{"127",               "255.0.0.0",        APR_EBADIP} /* either EBADIP or EBADMASK seems fine */
48#if APR_HAVE_IPV6
49        ,{"::1",               NULL,               APR_SUCCESS}
50        ,{"::1",               "20",               APR_SUCCESS}
51        ,{"::ffff:9.67.113.15", NULL,              APR_EBADIP} /* yes, this is goodness */
52        ,{"fe80::",            "16",               APR_SUCCESS}
53        ,{"fe80::",            "255.0.0.0",        APR_EBADMASK}
54        ,{"fe80::1",           "0",                APR_EBADMASK}
55        ,{"fe80::1",           "-1",               APR_EBADMASK}
56        ,{"fe80::1",           "1",                APR_SUCCESS}
57        ,{"fe80::1",           "33",               APR_SUCCESS}
58        ,{"fe80::1",           "128",              APR_SUCCESS}
59        ,{"fe80::1",           "129",              APR_EBADMASK}
60#else
61        /* do some IPv6 stuff and verify that it fails with APR_EBADIP */
62        ,{"::ffff:9.67.113.15", NULL,              APR_EBADIP}
63#endif
64    };
65    int i;
66    apr_ipsubnet_t *ipsub;
67    apr_status_t rv;
68
69    for (i = 0; i < (sizeof testcases / sizeof testcases[0]); i++) {
70        rv = apr_ipsubnet_create(&ipsub, testcases[i].ipstr, testcases[i].mask, p);
71        ABTS_INT_EQUAL(tc, testcases[i].expected_rv, rv);
72    }
73}
74
75static void test_singleton_subnets(abts_case *tc, void *data)
76{
77    const char *v4addrs[] = {
78        "127.0.0.1", "129.42.18.99", "63.161.155.20", "207.46.230.229", "64.208.42.36",
79        "198.144.203.195", "192.18.97.241", "198.137.240.91", "62.156.179.119",
80        "204.177.92.181"
81    };
82    apr_ipsubnet_t *ipsub;
83    apr_sockaddr_t *sa;
84    apr_status_t rv;
85    int i, j, rc;
86
87    for (i = 0; i < sizeof v4addrs / sizeof v4addrs[0]; i++) {
88        rv = apr_ipsubnet_create(&ipsub, v4addrs[i], NULL, p);
89        ABTS_TRUE(tc, rv == APR_SUCCESS);
90        for (j = 0; j < sizeof v4addrs / sizeof v4addrs[0]; j++) {
91            rv = apr_sockaddr_info_get(&sa, v4addrs[j], APR_INET, 0, 0, p);
92            ABTS_TRUE(tc, rv == APR_SUCCESS);
93            rc = apr_ipsubnet_test(ipsub, sa);
94            if (!strcmp(v4addrs[i], v4addrs[j])) {
95                ABTS_TRUE(tc, rc != 0);
96            }
97            else {
98                ABTS_TRUE(tc, rc == 0);
99            }
100        }
101    }
102
103    /* same for v6? */
104}
105
106static void test_interesting_subnets(abts_case *tc, void *data)
107{
108    struct {
109        const char *ipstr, *mask;
110        int family;
111        char *in_subnet, *not_in_subnet;
112    } testcases[] =
113    {
114         {"9.67",             NULL,            APR_INET,  "9.67.113.15",         "10.1.2.3"}
115        ,{"9.67.0.0",         "16",            APR_INET,  "9.67.113.15",         "10.1.2.3"}
116        ,{"9.67.0.0",         "255.255.0.0",   APR_INET,  "9.67.113.15",         "10.1.2.3"}
117        ,{"9.67.113.99",      "16",            APR_INET,  "9.67.113.15",         "10.1.2.3"}
118        ,{"9.67.113.99",      "255.255.255.0", APR_INET,  "9.67.113.15",         "10.1.2.3"}
119        ,{"127",              NULL,            APR_INET,  "127.0.0.1",           "10.1.2.3"}
120        ,{"127.0.0.1",        "8",             APR_INET,  "127.0.0.1",           "10.1.2.3"}
121#if APR_HAVE_IPV6
122        ,{"38.0.0.0",         "8",             APR_INET6, "::ffff:38.1.1.1",     "2600::1"} /* PR 54047 */
123        ,{"fe80::",           "8",             APR_INET6, "fe80::1",             "ff01::1"}
124        ,{"ff01::",           "8",             APR_INET6, "ff01::1",             "fe80::1"}
125        ,{"3FFE:8160::",      "28",            APR_INET6, "3ffE:816e:abcd:1234::1", "3ffe:8170::1"}
126        ,{"127.0.0.1",        NULL,            APR_INET6, "::ffff:127.0.0.1",    "fe80::1"}
127        ,{"127.0.0.1",        "8",             APR_INET6, "::ffff:127.0.0.1",    "fe80::1"}
128#endif
129    };
130    apr_ipsubnet_t *ipsub;
131    apr_sockaddr_t *sa;
132    apr_status_t rv;
133    int i, rc;
134
135    for (i = 0; i < sizeof testcases / sizeof testcases[0]; i++) {
136        rv = apr_ipsubnet_create(&ipsub, testcases[i].ipstr, testcases[i].mask, p);
137        ABTS_TRUE(tc, rv == APR_SUCCESS);
138        rv = apr_sockaddr_info_get(&sa, testcases[i].in_subnet, testcases[i].family, 0, 0, p);
139        ABTS_TRUE(tc, rv == APR_SUCCESS);
140        ABTS_TRUE(tc, sa != NULL);
141        if (!sa) continue;
142        rc = apr_ipsubnet_test(ipsub, sa);
143        ABTS_TRUE(tc, rc != 0);
144        rv = apr_sockaddr_info_get(&sa, testcases[i].not_in_subnet, testcases[i].family, 0, 0, p);
145        ABTS_TRUE(tc, rv == APR_SUCCESS);
146        rc = apr_ipsubnet_test(ipsub, sa);
147        ABTS_TRUE(tc, rc == 0);
148    }
149}
150
151static void test_badmask_str(abts_case *tc, void *data)
152{
153    char buf[128];
154
155    ABTS_STR_EQUAL(tc, apr_strerror(APR_EBADMASK, buf, sizeof buf),
156                      "The specified network mask is invalid.");
157}
158
159static void test_badip_str(abts_case *tc, void *data)
160{
161    char buf[128];
162
163    ABTS_STR_EQUAL(tc, apr_strerror(APR_EBADIP, buf, sizeof buf),
164                      "The specified IP address is invalid.");
165}
166
167abts_suite *testipsub(abts_suite *suite)
168{
169    suite = ADD_SUITE(suite)
170
171    abts_run_test(suite, test_bad_input, NULL);
172    abts_run_test(suite, test_singleton_subnets, NULL);
173    abts_run_test(suite, test_interesting_subnets, NULL);
174    abts_run_test(suite, test_badmask_str, NULL);
175    abts_run_test(suite, test_badip_str, NULL);
176    return suite;
177}
178
179