Statistics
| Branch: | Revision:

iof-bird-daemon / lib / net.h @ 04632fd7

History | View | Annotate | Download (7.13 KB)

1
/*
2
 *        BIRD Internet Routing Daemon -- Network addresses
3
 *
4
 *        (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
5
 *        (c) 2015 CZ.NIC z.s.p.o.
6
 *
7
 *        Can be freely distributed and used under the terms of the GNU GPL.
8
 */
9

    
10
#ifndef _BIRD_NET_H_
11
#define _BIRD_NET_H_
12

    
13
#include "lib/ip.h"
14

    
15

    
16
#define NET_IP4                1
17
#define NET_IP6                2
18
#define NET_VPN4        3
19
#define NET_VPN6        4
20
#define NET_MAX                5
21

    
22
typedef struct net_addr {
23
  u8 type;
24
  u8 pxlen;
25
  u16 length;
26
  u8 data[16];
27
  u64 align[0];
28
} net_addr;
29

    
30
typedef struct net_addr_ip4 {
31
  u8 type;
32
  u8 pxlen;
33
  u16 length;
34
  ip4_addr prefix;
35
} net_addr_ip4;
36

    
37
typedef struct net_addr_ip6 {
38
  u8 type;
39
  u8 pxlen;
40
  u16 length;
41
  ip6_addr prefix;
42
} net_addr_ip6;
43

    
44
typedef struct net_addr_vpn4 {
45
  u8 type;
46
  u8 pxlen;
47
  u16 length;
48
  ip4_addr prefix;
49
  u64 rd;
50
} net_addr_vpn4;
51

    
52
typedef struct net_addr_vpn6 {
53
  u8 type;
54
  u8 pxlen;
55
  u16 length;
56
  ip6_addr prefix;
57
  u64 rd;
58
} net_addr_vpn6;
59

    
60

    
61
typedef union net_addr_union {
62
  net_addr n;
63
  net_addr_ip4 ip4;
64
  net_addr_ip6 ip6;
65
  net_addr_vpn4 vpn4;
66
  net_addr_vpn6 vpn6;
67
} net_addr_union;
68

    
69

    
70
extern const u16 net_addr_length[];
71
extern const u8  net_max_prefix_length[];
72
extern const u16 net_max_text_length[];
73

    
74
#define NET_MAX_TEXT_LENGTH        65
75

    
76

    
77
#define NET_ADDR_IP4(prefix,pxlen) \
78
  ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
79

    
80
#define NET_ADDR_IP6(prefix,pxlen) \
81
  ((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
82

    
83
#define NET_ADDR_VPN4(prefix,pxlen,rd) \
84
  ((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
85

    
86
#define NET_ADDR_VPN6(prefix,pxlen,rd) \
87
  ((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, rd })
88

    
89

    
90
static inline void net_fill_ip4(net_addr *a, ip4_addr prefix, uint pxlen)
91
{ *(net_addr_ip4 *)a = NET_ADDR_IP4(prefix, pxlen); }
92

    
93
static inline void net_fill_ip6(net_addr *a, ip6_addr prefix, uint pxlen)
94
{ *(net_addr_ip6 *)a = NET_ADDR_IP6(prefix, pxlen); }
95

    
96
static inline void net_fill_vpn4(net_addr *a, ip4_addr prefix, uint pxlen, u64 rd)
97
{ *(net_addr_vpn4 *)a = NET_ADDR_VPN4(prefix, pxlen, rd); }
98

    
99
static inline void net_fill_vpn6(net_addr *a, ip6_addr prefix, uint pxlen, u64 rd)
100
{ *(net_addr_vpn6 *)a = NET_ADDR_VPN6(prefix, pxlen, rd); }
101

    
102
static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen)
103
{
104
  if (ipa_is_ip4(prefix))
105
    net_fill_ip4(a, ipa_to_ip4(prefix), pxlen);
106
  else
107
    net_fill_ip6(a, ipa_to_ip6(prefix), pxlen);
108
}
109

    
110
static inline void net_fill_ip_host(net_addr *a, ip_addr prefix)
111
{
112
  if (ipa_is_ip4(prefix))
113
    net_fill_ip4(a, ipa_to_ip4(prefix), IP4_MAX_PREFIX_LENGTH);
114
  else
115
    net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH);
116
}
117

    
118
static inline int net_is_ip(const net_addr *a)
119
{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
120

    
121

    
122
static inline ip4_addr net4_prefix(const net_addr *a)
123
{ return ((net_addr_ip4 *) a)->prefix; }
124

    
125
static inline ip6_addr net6_prefix(const net_addr *a)
126
{ return ((net_addr_ip6 *) a)->prefix; }
127

    
128
static inline ip_addr net_prefix(const net_addr *a)
129
{
130
  switch (a->type)
131
  {
132
  case NET_IP4:
133
  case NET_VPN4: return ipa_from_ip4(net4_prefix(a));
134
  case NET_IP6:
135
  case NET_VPN6: return ipa_from_ip6(net6_prefix(a));
136
  default: return IPA_NONE;
137
  }
138
}
139

    
140
static inline uint net4_pxlen(const net_addr *a)
141
{ return a->pxlen; }
142

    
143
static inline uint net6_pxlen(const net_addr *a)
144
{ return a->pxlen; }
145

    
146
static inline uint net_pxlen(const net_addr *a)
147
{ return a->pxlen; }
148

    
149
ip_addr net_pxmask(const net_addr *a);
150

    
151

    
152
static inline int net_equal(const net_addr *a, const net_addr *b)
153
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
154

    
155
static inline int net_equal_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
156
{ return !memcmp(a, b, sizeof(net_addr_ip4)); }
157

    
158
static inline int net_equal_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
159
{ return !memcmp(a, b, sizeof(net_addr_ip6)); }
160

    
161
static inline int net_equal_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
162
{ return !memcmp(a, b, sizeof(net_addr_vpn4)); }
163

    
164
static inline int net_equal_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
165
{ return !memcmp(a, b, sizeof(net_addr_vpn6)); }
166

    
167

    
168
static inline int net_zero_ip4(const net_addr_ip4 *a)
169
{ return !a->pxlen && ip4_zero(a->prefix); }
170

    
171
static inline int net_zero_ip6(const net_addr_ip6 *a)
172
{ return !a->pxlen && ip6_zero(a->prefix); }
173

    
174
static inline int net_zero_vpn4(const net_addr_vpn4 *a)
175
{ return !a->pxlen && ip4_zero(a->prefix) && !a->rd; }
176

    
177
static inline int net_zero_vpn6(const net_addr_vpn6 *a)
178
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
179

    
180

    
181
static inline int net_compare_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
182
{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
183

    
184
static inline int net_compare_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
185
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
186

    
187
static inline int net_compare_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
188
{ return u64_cmp(a->rd, b->rd) ?: ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
189

    
190
static inline int net_compare_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
191
{ return u64_cmp(a->rd, b->rd) ?: ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
192

    
193
int net_compare(const net_addr *a, const net_addr *b);
194

    
195

    
196
static inline void net_copy(net_addr *dst, const net_addr *src)
197
{ memcpy(dst, src, src->length); }
198

    
199
static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src)
200
{ memcpy(dst, src, sizeof(net_addr_ip4)); }
201

    
202
static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src)
203
{ memcpy(dst, src, sizeof(net_addr_ip6)); }
204

    
205
static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src)
206
{ memcpy(dst, src, sizeof(net_addr_vpn4)); }
207

    
208
static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
209
{ memcpy(dst, src, sizeof(net_addr_vpn6)); }
210

    
211

    
212
static inline u32 net_hash_ip4(const net_addr_ip4 *n)
213
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
214

    
215
static inline u32 net_hash_ip6(const net_addr_ip6 *n)
216
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
217

    
218
/* XXXX */
219
static inline u32 u64_hash(u64 a)
220
{ return u32_hash(a); }
221

    
222
static inline u32 net_hash_vpn4(const net_addr_vpn4 *n)
223
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
224

    
225
static inline u32 net_hash_vpn6(const net_addr_vpn6 *n)
226
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
227

    
228

    
229
static inline int net_validate_ip4(const net_addr_ip4 *n)
230
{
231
  return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
232
    ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
233
}
234

    
235
static inline int net_validate_ip6(const net_addr_ip6 *n)
236
{
237
  return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
238
    ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
239
}
240

    
241
int net_validate(const net_addr *N);
242

    
243

    
244
static inline void net_normalize_ip4(net_addr_ip4 *n)
245
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
246

    
247
static inline void net_normalize_ip6(net_addr_ip6 *n)
248
{ n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); }
249

    
250
void net_normalize(net_addr *N);
251

    
252

    
253
int net_classify(const net_addr *N);
254
int net_format(const net_addr *N, char *buf, int buflen);
255

    
256

    
257
int ipa_in_netX(const ip_addr A, const net_addr *N);
258
int net_in_netX(const net_addr *A, const net_addr *N);
259

    
260

    
261
#endif