File: ip_range.h

package info (click to toggle)
libreswan 5.2-2.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 81,632 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (150 lines) | stat: -rw-r--r-- 4,709 bytes parent folder | download
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
/* address range, for libreswan
 *
 * header file for Libreswan library functions
 * Copyright (C) 1998, 1999, 2000  Henry Spencer.
 * Copyright (C) 1999, 2000, 2001  Richard Guy Briggs
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <https://www.gnu.org/licenses/lgpl-2.1.txt>.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
 * License for more details.
 *
 */

#ifndef IP_RANGE_H
#define IP_RANGE_H

#include "err.h"
#include "ip_address.h"
#include "ip_subnet.h"
#include "ip_version.h"

typedef struct {
	bool is_set;
	enum ip_version version;
	struct ip_bytes lo;
	struct ip_bytes hi;
} ip_range;

#define PRI_RANGE "<range-%s:IPv%d["PRI_IP_BYTES"]->["PRI_IP_BYTES"]>"
#define pri_range(R)					\
		((R)->is_set ? "set" : "unset"),	\
		(R)->version,				\
		pri_ip_bytes((R)->lo),			\
		pri_ip_bytes((R)->hi)

void pexpect_range(const ip_range *r, where_t where);
#define prange(R) pexpect_range(R, HERE)

/* caller knows best */
ip_range range_from_raw(where_t where, const struct ip_info *afi,
			const struct ip_bytes start,
			const struct ip_bytes end);

ip_range range_from_address(const ip_address subnet);
ip_range range_from_subnet(const ip_subnet subnet);

err_t addresses_to_nonzero_range(const ip_address start, const ip_address end,
				 ip_range *dst) MUST_USE_RESULT;

err_t range_to_subnet(const ip_range range, ip_subnet *subnet) MUST_USE_RESULT;

err_t ttorange_num(shunk_t input, const struct ip_info *afi, ip_range *dst) MUST_USE_RESULT;

/* comma/space separated list */

typedef struct {
	unsigned len;
	ip_range *list;
} ip_ranges;

extern const ip_ranges empty_ip_ranges;

diag_t ttoranges_num(shunk_t input, const char *delims,
		     const struct ip_info *afi,
		     ip_ranges *output) MUST_USE_RESULT;

size_t jam_ranges(struct jambuf *buf, ip_ranges ranges);

/*
 * Formatting
 */

typedef struct {
	char buf[sizeof(address_buf) + 1/*"-"*/ + sizeof(address_buf)];
} range_buf;

size_t jam_range(struct jambuf *buf, const ip_range *range);
const char *str_range(const ip_range *range, range_buf *buf);

/*
 * Magic values.
 *
 * XXX: While the headers call the all-zero address "ANY" (INADDR_ANY,
 * IN6ADDR_ANY_INIT), the headers also refer to the IPv6 value as
 * unspecified (for instance IN6_IS_ADDR_UNSPECIFIED()) leaving the
 * term "unspecified" underspecified.
 *
 * Consequently an AF_UNSPEC address (i.e., uninitialized or unset),
 * is identified by *_unset().
 */

extern const ip_range unset_range;

bool range_is_unset(const ip_range *r);			/* handles NULL */
const struct ip_info *range_type(const ip_range *r);	/* handles NULL */
const struct ip_info *range_info(const ip_range r);

bool range_is_zero(ip_range range);	/* ::-ffff... or 0.0.0.0-0.0.0.0 */
bool range_is_all(const ip_range r);	/* ::-:: or 0.0.0.0-0.0.0.0 */
bool range_is_cidr(ip_range r);		/* prefix/host=0..prefix/host=-1 */

bool range_eq_address(const ip_range range, const ip_address address);
bool range_eq_subnet(const ip_range range, const ip_subnet subnet);
bool range_eq_range(const ip_range l, const ip_range r);

bool address_in_range(const ip_address address, const ip_range range);
bool subnet_in_range(const ip_subnet subnet, const ip_range range);
bool range_in_range(const ip_range inner, const ip_range outer);

bool range_overlaps_range(const ip_range l, const ip_range r);

/*
 * range_host_len: Calculate the number of significant bits in the
 * size of the range.  floor(log2(|high-low| + 1)).
 *
 * If RANGE is CIDR then this returns the number of HOST IDENTIFIER
 * bits.
 */

int range_host_len(const ip_range range); /* <0 when non-CIDR */
int range_prefix_len(const ip_range range); /* <0 when non-CIDR */

/*
 * range_size: the number of IP addresses within an ip_range.
 *
 * Special return values:
 *   0 indicates that the range isn't of IPv4 or IPv6 addresses.
 *   UINTMAX_MAX indicates that the range size is UINTMAX_MAX or more
 */
uintmax_t range_size(const ip_range r);

/*
 * operations
 */

ip_address range_start(const ip_range range); /* floor */
ip_address range_end(const ip_range range); /* ceiling */

err_t range_offset_to_address(const ip_range range, uintmax_t offset,
			      ip_address *address) MUST_USE_RESULT;

err_t address_to_range_offset(const ip_range range, const ip_address address,
			      uintmax_t *offset) MUST_USE_RESULT;

#endif