Statistics
| Branch: | Revision:

iof-bird-daemon / lib / net.h @ 9b136840

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

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

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

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

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

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

    
61

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

    
70

    
71
extern const u16 net_addr_length[];
72

    
73

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

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

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

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

    
86

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

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

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

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

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

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

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

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

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

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

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

    
134
ip_addr net_pxmask(const net_addr *a);
135

    
136

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

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

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

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

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

    
152

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

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

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

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

    
165

    
166
static inline void net_copy(net_addr *dst, const net_addr *src)
167
{ memcpy(dst, src, src->length); }
168

    
169
static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src)
170
{ memcpy(dst, src, sizeof(net_addr_ip4)); }
171

    
172
static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src)
173
{ memcpy(dst, src, sizeof(net_addr_ip6)); }
174

    
175
static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src)
176
{ memcpy(dst, src, sizeof(net_addr_vpn4)); }
177

    
178
static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
179
{ memcpy(dst, src, sizeof(net_addr_vpn6)); }
180

    
181

    
182
static inline u32 net_hash_ip4(const net_addr_ip4 *n)
183
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
184

    
185
static inline u32 net_hash_ip6(const net_addr_ip6 *n)
186
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
187

    
188
/* XXXX */
189
static inline u32 u64_hash(u32 a)
190
{ return u32_hash(a); }
191

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

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

    
198

    
199
static inline void net_normalize_ip4(net_addr_ip4 *n)
200
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
201

    
202
static inline void net_normalize_ip6(net_addr_ip6 *n)
203
{ n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); }
204

    
205
void net_normalize(net_addr *N);
206

    
207
int net_validate(const net_addr *N);
208

    
209
int net_classify(const net_addr *N);
210
int net_format(const net_addr *N, char *buf, int buflen);
211

    
212

    
213
int ipa_in_netX(const ip_addr A, const net_addr *N);
214
int net_in_netX(const net_addr *A, const net_addr *N);
215

    
216

    
217
#endif
218

    
219

    
220