]>
Commit | Line | Data |
---|---|---|
fe9f1a6d OZ |
1 | |
2 | #include "nest/bird.h" | |
3 | #include "lib/ip.h" | |
4 | #include "lib/net.h" | |
5 | ||
d7661fbe | 6 | |
f4a60a9b OZ |
7 | const char * const net_label[] = { |
8 | [NET_IP4] = "ipv4", | |
9 | [NET_IP6] = "ipv6", | |
10 | [NET_VPN4] = "vpn4", | |
286e2011 OZ |
11 | [NET_VPN6] = "vpn6", |
12 | [NET_ROA4] = "roa4", | |
13 | [NET_ROA6] = "roa6", | |
f4a60a9b OZ |
14 | }; |
15 | ||
fe9f1a6d OZ |
16 | const u16 net_addr_length[] = { |
17 | [NET_IP4] = sizeof(net_addr_ip4), | |
18 | [NET_IP6] = sizeof(net_addr_ip6), | |
19 | [NET_VPN4] = sizeof(net_addr_vpn4), | |
de9b87f5 PT |
20 | [NET_VPN6] = sizeof(net_addr_vpn6), |
21 | [NET_ROA4] = sizeof(net_addr_roa4), | |
22 | [NET_ROA6] = sizeof(net_addr_roa6) | |
9b136840 | 23 | }; |
fe9f1a6d | 24 | |
d7661fbe JMM |
25 | const u8 net_max_prefix_length[] = { |
26 | [NET_IP4] = IP4_MAX_PREFIX_LENGTH, | |
27 | [NET_IP6] = IP6_MAX_PREFIX_LENGTH, | |
28 | [NET_VPN4] = IP4_MAX_PREFIX_LENGTH, | |
de9b87f5 PT |
29 | [NET_VPN6] = IP6_MAX_PREFIX_LENGTH, |
30 | [NET_ROA4] = IP4_MAX_PREFIX_LENGTH, | |
31 | [NET_ROA6] = IP6_MAX_PREFIX_LENGTH | |
d7661fbe JMM |
32 | }; |
33 | ||
7fd4143e JMM |
34 | const u16 net_max_text_length[] = { |
35 | [NET_IP4] = 18, /* "255.255.255.255/32" */ | |
36 | [NET_IP6] = 43, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */ | |
37 | [NET_VPN4] = 40, /* "4294967296:4294967296 255.255.255.255/32" */ | |
38 | [NET_VPN6] = 65, /* "4294967296:4294967296 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */ | |
286e2011 OZ |
39 | [NET_ROA4] = 34, /* "255.255.255.255/32-32 AS4294967295" */ |
40 | [NET_ROA6] = 60, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128-128 AS4294967295" */ | |
7fd4143e JMM |
41 | }; |
42 | ||
d7661fbe | 43 | |
9b136840 | 44 | int |
fe9f1a6d OZ |
45 | net_format(const net_addr *N, char *buf, int buflen) |
46 | { | |
47 | net_addr_union *n = (void *) N; | |
48 | ||
fe9f1a6d OZ |
49 | switch (n->n.type) |
50 | { | |
51 | case NET_IP4: | |
e691d16a | 52 | return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen); |
fe9f1a6d | 53 | case NET_IP6: |
e691d16a | 54 | return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen); |
fe9f1a6d | 55 | case NET_VPN4: |
e691d16a | 56 | return bsnprintf(buf, buflen, "%u:%u %I4/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen); |
fe9f1a6d | 57 | case NET_VPN6: |
e691d16a | 58 | return bsnprintf(buf, buflen, "%u:%u %I6/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen); |
de9b87f5 | 59 | case NET_ROA4: |
f9d729ab | 60 | return bsnprintf(buf, buflen, "%I4/%u-%u AS%u", n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn); |
de9b87f5 | 61 | case NET_ROA6: |
f9d729ab | 62 | return bsnprintf(buf, buflen, "%I6/%u-%u AS%u", n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn); |
fe9f1a6d | 63 | } |
9b136840 JMM |
64 | |
65 | return 0; | |
66 | } | |
67 | ||
9b136840 JMM |
68 | ip_addr |
69 | net_pxmask(const net_addr *a) | |
70 | { | |
71 | switch (a->type) | |
72 | { | |
73 | case NET_IP4: | |
74 | case NET_VPN4: | |
de9b87f5 | 75 | case NET_ROA4: |
9b136840 JMM |
76 | return ipa_from_ip4(ip4_mkmask(net4_pxlen(a))); |
77 | ||
78 | case NET_IP6: | |
79 | case NET_VPN6: | |
de9b87f5 | 80 | case NET_ROA6: |
9b136840 JMM |
81 | return ipa_from_ip6(ip6_mkmask(net6_pxlen(a))); |
82 | ||
83 | default: | |
84 | return IPA_NONE; | |
85 | } | |
86 | } | |
87 | ||
5e173e9f JMM |
88 | int |
89 | net_compare(const net_addr *a, const net_addr *b) | |
9b136840 | 90 | { |
5e173e9f JMM |
91 | if (a->type != b->type) |
92 | return uint_cmp(a->type, b->type); | |
9b136840 | 93 | |
5e173e9f JMM |
94 | switch (a->type) |
95 | { | |
96 | case NET_IP4: | |
97 | return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b); | |
98 | case NET_IP6: | |
99 | return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b); | |
100 | case NET_VPN4: | |
101 | return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b); | |
102 | case NET_VPN6: | |
103 | return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b); | |
de9b87f5 PT |
104 | case NET_ROA4: |
105 | return net_compare_roa4((const net_addr_roa4 *) a, (const net_addr_roa4 *) b); | |
106 | case NET_ROA6: | |
107 | return net_compare_roa6((const net_addr_roa6 *) a, (const net_addr_roa6 *) b); | |
5e173e9f JMM |
108 | } |
109 | return 0; | |
9b136840 JMM |
110 | } |
111 | ||
d15b0b0a OZ |
112 | #define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a) |
113 | ||
114 | u32 | |
115 | net_hash(const net_addr *n) | |
116 | { | |
117 | switch (n->type) | |
118 | { | |
119 | case NET_IP4: return NET_HASH(n, ip4); | |
120 | case NET_IP6: return NET_HASH(n, ip6); | |
121 | case NET_VPN4: return NET_HASH(n, vpn4); | |
122 | case NET_VPN6: return NET_HASH(n, vpn6); | |
123 | case NET_ROA4: return NET_HASH(n, roa4); | |
124 | case NET_ROA6: return NET_HASH(n, roa6); | |
125 | default: bug("invalid type"); | |
126 | } | |
127 | } | |
128 | ||
129 | ||
9b136840 JMM |
130 | int |
131 | net_validate(const net_addr *N) | |
132 | { | |
5e173e9f | 133 | switch (N->type) |
9b136840 JMM |
134 | { |
135 | case NET_IP4: | |
136 | case NET_VPN4: | |
de9b87f5 | 137 | case NET_ROA4: |
9b136840 JMM |
138 | return net_validate_ip4((net_addr_ip4 *) N); |
139 | ||
140 | case NET_IP6: | |
141 | case NET_VPN6: | |
de9b87f5 | 142 | case NET_ROA6: |
9b136840 JMM |
143 | return net_validate_ip6((net_addr_ip6 *) N); |
144 | ||
145 | default: | |
146 | return 0; | |
147 | } | |
fe9f1a6d OZ |
148 | } |
149 | ||
aedd3a6b JMM |
150 | void |
151 | net_normalize(net_addr *N) | |
152 | { | |
153 | net_addr_union *n = (void *) N; | |
154 | ||
155 | switch (n->n.type) | |
156 | { | |
157 | case NET_IP4: | |
158 | case NET_VPN4: | |
de9b87f5 | 159 | case NET_ROA4: |
aedd3a6b JMM |
160 | return net_normalize_ip4(&n->ip4); |
161 | ||
162 | case NET_IP6: | |
163 | case NET_VPN6: | |
de9b87f5 | 164 | case NET_ROA6: |
aedd3a6b JMM |
165 | return net_normalize_ip6(&n->ip6); |
166 | } | |
167 | } | |
168 | ||
fe9f1a6d OZ |
169 | int |
170 | net_classify(const net_addr *N) | |
171 | { | |
172 | net_addr_union *n = (void *) N; | |
173 | ||
174 | switch (n->n.type) | |
175 | { | |
176 | case NET_IP4: | |
177 | case NET_VPN4: | |
de9b87f5 | 178 | case NET_ROA4: |
fe9f1a6d OZ |
179 | return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix); |
180 | ||
181 | case NET_IP6: | |
182 | case NET_VPN6: | |
de9b87f5 | 183 | case NET_ROA6: |
9b136840 | 184 | return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix); |
fe9f1a6d | 185 | } |
9b136840 | 186 | |
0bf95f99 | 187 | return IADDR_INVALID; |
fe9f1a6d | 188 | } |
aedd3a6b JMM |
189 | |
190 | int | |
0bf95f99 | 191 | ipa_in_netX(const ip_addr a, const net_addr *n) |
aedd3a6b | 192 | { |
0bf95f99 | 193 | switch (n->type) |
aedd3a6b JMM |
194 | { |
195 | case NET_IP4: | |
196 | case NET_VPN4: | |
de9b87f5 | 197 | case NET_ROA4: |
0bf95f99 OZ |
198 | if (!ipa_is_ip4(a)) return 0; |
199 | return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)), | |
200 | ip4_mkmask(net4_pxlen(n)))); | |
aedd3a6b JMM |
201 | |
202 | case NET_IP6: | |
203 | case NET_VPN6: | |
de9b87f5 | 204 | case NET_ROA6: |
0bf95f99 OZ |
205 | if (ipa_is_ip4(a)) return 0; |
206 | return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)), | |
207 | ip6_mkmask(net6_pxlen(n)))); | |
aedd3a6b | 208 | |
0bf95f99 OZ |
209 | default: |
210 | return 0; | |
211 | } | |
aedd3a6b JMM |
212 | } |
213 | ||
214 | int | |
0bf95f99 | 215 | net_in_netX(const net_addr *a, const net_addr *n) |
aedd3a6b | 216 | { |
0bf95f99 | 217 | if (a->type != n->type) |
aedd3a6b JMM |
218 | return 0; |
219 | ||
0bf95f99 | 220 | return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n); |
aedd3a6b | 221 | } |