Statistics
| Branch: | Revision:

iof-bird-daemon / lib / net.h @ fe9f1a6d

History | View | Annotate | Download (5.47 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
  u64 align[0];
28
  u32 space[4];
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

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

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

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

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

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

    
150

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

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

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

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

    
163

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

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

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

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

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

    
179

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

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

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

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

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

    
196

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

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

    
203
void net_normalize(net_addr *N);
204

    
205
int net_validate(const net_addr *N);
206
int net_classify(const net_addr *N);
207
char * net_format(const net_addr *N, char *buf, int buflen);
208

    
209

    
210

    
211
#endif
212

    
213

    
214