Statistics
| Branch: | Revision:

iof-bird-daemon / lib / net.h @ 5e173e9f

History | View | Annotate | Download (6.73 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

    
73
#define NET_ADDR_IP4(prefix,pxlen) \
74
  ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
75

    
76
#define NET_ADDR_IP6(prefix,pxlen) \
77
  ((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
78

    
79
#define NET_ADDR_VPN4(prefix,pxlen,rd) \
80
  ((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
81

    
82
#define NET_ADDR_VPN6(prefix,pxlen,rd) \
83
  ((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, rd })
84

    
85

    
86
static inline void net_fill_ip4(net_addr *a, ip4_addr prefix, uint pxlen)
87
{ *(net_addr_ip4 *)a = NET_ADDR_IP4(prefix, pxlen); }
88

    
89
static inline void net_fill_ip6(net_addr *a, ip6_addr prefix, uint pxlen)
90
{ *(net_addr_ip6 *)a = NET_ADDR_IP6(prefix, pxlen); }
91

    
92
static inline void net_fill_vpn4(net_addr *a, ip4_addr prefix, uint pxlen, u64 rd)
93
{ *(net_addr_vpn4 *)a = NET_ADDR_VPN4(prefix, pxlen, rd); }
94

    
95
static inline void net_fill_vpn6(net_addr *a, ip6_addr prefix, uint pxlen, u64 rd)
96
{ *(net_addr_vpn6 *)a = NET_ADDR_VPN6(prefix, pxlen, rd); }
97

    
98
static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen)
99
{
100
  if (ipa_is_ip4(prefix))
101
    net_fill_ip4(a, ipa_to_ip4(prefix), pxlen);
102
  else
103
    net_fill_ip6(a, ipa_to_ip6(prefix), pxlen);
104
}
105

    
106
static inline ip4_addr net4_prefix(const net_addr *a)
107
{ return ((net_addr_ip4 *) a)->prefix; }
108

    
109
static inline ip6_addr net6_prefix(const net_addr *a)
110
{ return ((net_addr_ip6 *) a)->prefix; }
111

    
112
static inline ip_addr net_prefix(const net_addr *a)
113
{
114
  switch (a->type)
115
  {
116
  case NET_IP4:
117
  case NET_VPN4: return ipa_from_ip4(net4_prefix(a));
118
  case NET_IP6:
119
  case NET_VPN6: return ipa_from_ip6(net6_prefix(a));
120
  default: return IPA_NONE;
121
  }
122
}
123

    
124
static inline uint net4_pxlen(const net_addr *a)
125
{ return a->pxlen; }
126

    
127
static inline uint net6_pxlen(const net_addr *a)
128
{ return a->pxlen; }
129

    
130
static inline uint net_pxlen(const net_addr *a)
131
{ return a->pxlen; }
132

    
133
ip_addr net_pxmask(const net_addr *a);
134

    
135

    
136
static inline int net_equal(const net_addr *a, const net_addr *b)
137
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
138

    
139
static inline int net_equal_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
140
{ return !memcmp(a, b, sizeof(net_addr_ip4)); }
141

    
142
static inline int net_equal_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
143
{ return !memcmp(a, b, sizeof(net_addr_ip6)); }
144

    
145
static inline int net_equal_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
146
{ return !memcmp(a, b, sizeof(net_addr_vpn4)); }
147

    
148
static inline int net_equal_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
149
{ return !memcmp(a, b, sizeof(net_addr_vpn6)); }
150

    
151

    
152
static inline int net_zero_ip4(const net_addr_ip4 *a)
153
{ return !a->pxlen && ip4_zero(a->prefix); }
154

    
155
static inline int net_zero_ip6(const net_addr_ip6 *a)
156
{ return !a->pxlen && ip6_zero(a->prefix); }
157

    
158
static inline int net_zero_vpn4(const net_addr_vpn4 *a)
159
{ return !a->pxlen && ip4_zero(a->prefix) && !a->rd; }
160

    
161
static inline int net_zero_vpn6(const net_addr_vpn6 *a)
162
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
163

    
164

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

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

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

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

    
177
int net_compare(const net_addr *a, const net_addr *b);
178

    
179

    
180
static inline void net_copy(net_addr *dst, const net_addr *src)
181
{ memcpy(dst, src, src->length); }
182

    
183
static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src)
184
{ memcpy(dst, src, sizeof(net_addr_ip4)); }
185

    
186
static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src)
187
{ memcpy(dst, src, sizeof(net_addr_ip6)); }
188

    
189
static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src)
190
{ memcpy(dst, src, sizeof(net_addr_vpn4)); }
191

    
192
static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
193
{ memcpy(dst, src, sizeof(net_addr_vpn6)); }
194

    
195

    
196
static inline u32 net_hash_ip4(const net_addr_ip4 *n)
197
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
198

    
199
static inline u32 net_hash_ip6(const net_addr_ip6 *n)
200
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
201

    
202
/* XXXX */
203
static inline u32 u64_hash(u32 a)
204
{ return u32_hash(a); }
205

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

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

    
212

    
213
static inline int net_validate_ip4(const net_addr_ip4 *n)
214
{
215
  return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
216
    ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
217
}
218

    
219
static inline int net_validate_ip6(const net_addr_ip6 *n)
220
{
221
  return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
222
    ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
223
}
224

    
225
int net_validate(const net_addr *N);
226

    
227

    
228
static inline void net_normalize_ip4(net_addr_ip4 *n)
229
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
230

    
231
static inline void net_normalize_ip6(net_addr_ip6 *n)
232
{ n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); }
233

    
234
void net_normalize(net_addr *N);
235

    
236

    
237
int net_classify(const net_addr *N);
238
int net_format(const net_addr *N, char *buf, int buflen);
239

    
240

    
241
int ipa_in_netX(const ip_addr A, const net_addr *N);
242
int net_in_netX(const net_addr *A, const net_addr *N);
243

    
244

    
245
#endif
246

    
247

    
248