Line data Source code
1 : /*
2 : * Prefix structure.
3 : * Copyright (C) 1998 Kunihiro Ishiguro
4 : *
5 : * This file is part of GNU Zebra.
6 : *
7 : * GNU Zebra is free software; you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the
9 : * Free Software Foundation; either version 2, or (at your option) any
10 : * later version.
11 : *
12 : * GNU Zebra is distributed in the hope that it will be useful, but
13 : * WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 : * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 : * 02111-1307, USA.
21 : */
22 :
23 : #ifndef _ZEBRA_PREFIX_H
24 : #define _ZEBRA_PREFIX_H
25 :
26 : #include "sockunion.h"
27 :
28 : /*
29 : * A struct prefix contains an address family, a prefix length, and an
30 : * address. This can represent either a 'network prefix' as defined
31 : * by CIDR, where the 'host bits' of the prefix are 0
32 : * (e.g. AF_INET:10.0.0.0/8), or an address and netmask
33 : * (e.g. AF_INET:10.0.0.9/8), such as might be configured on an
34 : * interface.
35 : */
36 :
37 : /* IPv4 and IPv6 unified prefix structure. */
38 : struct prefix
39 : {
40 : u_char family;
41 : u_char prefixlen;
42 : union
43 : {
44 : u_char prefix;
45 : struct in_addr prefix4;
46 : #ifdef HAVE_IPV6
47 : struct in6_addr prefix6;
48 : #endif /* HAVE_IPV6 */
49 : struct
50 : {
51 : struct in_addr id;
52 : struct in_addr adv_router;
53 : } lp;
54 : u_char val[8];
55 : } u __attribute__ ((aligned (8)));
56 : };
57 :
58 : /* IPv4 prefix structure. */
59 : struct prefix_ipv4
60 : {
61 : u_char family;
62 : u_char prefixlen;
63 : struct in_addr prefix __attribute__ ((aligned (8)));
64 : };
65 :
66 : /* IPv6 prefix structure. */
67 : #ifdef HAVE_IPV6
68 : struct prefix_ipv6
69 : {
70 : u_char family;
71 : u_char prefixlen;
72 : struct in6_addr prefix __attribute__ ((aligned (8)));
73 : };
74 : #endif /* HAVE_IPV6 */
75 :
76 : struct prefix_ls
77 : {
78 : u_char family;
79 : u_char prefixlen;
80 : struct in_addr id __attribute__ ((aligned (8)));
81 : struct in_addr adv_router;
82 : };
83 :
84 : /* Prefix for routing distinguisher. */
85 : struct prefix_rd
86 : {
87 : u_char family;
88 : u_char prefixlen;
89 : u_char val[8] __attribute__ ((aligned (8)));
90 : };
91 :
92 : /* helper to get type safety/avoid casts on calls
93 : * (w/o this, functions accepting all prefix types need casts on the caller
94 : * side, which strips type safety since the cast will accept any pointer
95 : * type.)
96 : */
97 : union prefix46ptr
98 : {
99 : struct prefix *p;
100 : struct prefix_ipv4 *p4;
101 : struct prefix_ipv6 *p6;
102 : } __attribute__ ((transparent_union));
103 :
104 : union prefix46constptr
105 : {
106 : const struct prefix *p;
107 : const struct prefix_ipv4 *p4;
108 : const struct prefix_ipv6 *p6;
109 : } __attribute__ ((transparent_union));
110 :
111 : #ifndef INET_ADDRSTRLEN
112 : #define INET_ADDRSTRLEN 16
113 : #endif /* INET_ADDRSTRLEN */
114 :
115 : #ifndef INET6_ADDRSTRLEN
116 : #define INET6_ADDRSTRLEN 46
117 : #endif /* INET6_ADDRSTRLEN */
118 :
119 : #ifndef INET6_BUFSIZ
120 : #define INET6_BUFSIZ 51
121 : #endif /* INET6_BUFSIZ */
122 :
123 : /* Max bit/byte length of IPv4 address. */
124 : #define IPV4_MAX_BYTELEN 4
125 : #define IPV4_MAX_BITLEN 32
126 : #define IPV4_MAX_PREFIXLEN 32
127 : #define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN)
128 : #define IPV4_ADDR_SAME(D,S) (memcmp ((D), (S), IPV4_MAX_BYTELEN) == 0)
129 : #define IPV4_ADDR_COPY(D,S) memcpy ((D), (S), IPV4_MAX_BYTELEN)
130 :
131 : #define IPV4_NET0(a) ((((u_int32_t) (a)) & 0xff000000) == 0x00000000)
132 : #define IPV4_NET127(a) ((((u_int32_t) (a)) & 0xff000000) == 0x7f000000)
133 : #define IPV4_LINKLOCAL(a) ((((u_int32_t) (a)) & 0xffff0000) == 0xa9fe0000)
134 : #define IPV4_CLASS_DE(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000)
135 :
136 : /* Max bit/byte length of IPv6 address. */
137 : #define IPV6_MAX_BYTELEN 16
138 : #define IPV6_MAX_BITLEN 128
139 : #define IPV6_MAX_PREFIXLEN 128
140 : #define IPV6_ADDR_CMP(D,S) memcmp ((D), (S), IPV6_MAX_BYTELEN)
141 : #define IPV6_ADDR_SAME(D,S) (memcmp ((D), (S), IPV6_MAX_BYTELEN) == 0)
142 : #define IPV6_ADDR_COPY(D,S) memcpy ((D), (S), IPV6_MAX_BYTELEN)
143 :
144 : /* Count prefix size from mask length */
145 : #define PSIZE(a) (((a) + 7) / (8))
146 :
147 : /* Prefix's family member. */
148 : #define PREFIX_FAMILY(p) ((p)->family)
149 :
150 : /* Prototypes. */
151 : extern int afi2family (afi_t);
152 : extern afi_t family2afi (int);
153 :
154 : /* Check bit of the prefix. */
155 : extern unsigned int prefix_bit (const u_char *prefix, const u_char prefixlen);
156 : extern unsigned int prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen);
157 :
158 : extern struct prefix *prefix_new (void);
159 : extern void prefix_free (struct prefix *);
160 : extern const char *prefix_family_str (const struct prefix *);
161 : extern int prefix_blen (const struct prefix *);
162 : extern int str2prefix (const char *, struct prefix *);
163 : extern int prefix2str (const struct prefix *, char *, int);
164 : extern int prefix_match (const struct prefix *, const struct prefix *);
165 : extern int prefix_same (const struct prefix *, const struct prefix *);
166 : extern int prefix_cmp (const struct prefix *, const struct prefix *);
167 : extern int prefix_common_bits (const struct prefix *, const struct prefix *);
168 : extern void prefix_copy (struct prefix *dest, const struct prefix *src);
169 : extern void apply_mask (struct prefix *);
170 :
171 : extern struct prefix *sockunion2prefix (const union sockunion *dest,
172 : const union sockunion *mask);
173 : extern struct prefix *sockunion2hostprefix (const union sockunion *);
174 : extern void prefix2sockunion (const struct prefix *, union sockunion *);
175 :
176 : extern struct prefix_ipv4 *prefix_ipv4_new (void);
177 : extern void prefix_ipv4_free (struct prefix_ipv4 *);
178 : extern int str2prefix_ipv4 (const char *, struct prefix_ipv4 *);
179 : extern void apply_mask_ipv4 (struct prefix_ipv4 *);
180 :
181 : #define PREFIX_COPY_IPV4(DST, SRC) \
182 : *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC));
183 :
184 : extern int prefix_ipv4_any (const struct prefix_ipv4 *);
185 : extern void apply_classful_mask_ipv4 (struct prefix_ipv4 *);
186 :
187 : extern u_char ip_masklen (struct in_addr);
188 : extern void masklen2ip (const int, struct in_addr *);
189 : /* returns the network portion of the host address */
190 : extern in_addr_t ipv4_network_addr (in_addr_t hostaddr, int masklen);
191 : /* given the address of a host on a network and the network mask length,
192 : * calculate the broadcast address for that network;
193 : * special treatment for /31: returns the address of the other host
194 : * on the network by flipping the host bit */
195 : extern in_addr_t ipv4_broadcast_addr (in_addr_t hostaddr, int masklen);
196 :
197 : extern int netmask_str2prefix_str (const char *, const char *, char *);
198 :
199 : #ifdef HAVE_IPV6
200 : extern struct prefix_ipv6 *prefix_ipv6_new (void);
201 : extern void prefix_ipv6_free (struct prefix_ipv6 *);
202 : extern int str2prefix_ipv6 (const char *, struct prefix_ipv6 *);
203 : extern void apply_mask_ipv6 (struct prefix_ipv6 *);
204 :
205 : #define PREFIX_COPY_IPV6(DST, SRC) \
206 : *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC));
207 :
208 : extern int ip6_masklen (struct in6_addr);
209 : extern void masklen2ip6 (const int, struct in6_addr *);
210 :
211 : extern void str2in6_addr (const char *, struct in6_addr *);
212 : extern const char *inet6_ntoa (struct in6_addr);
213 :
214 : #endif /* HAVE_IPV6 */
215 :
216 : extern int all_digit (const char *);
217 :
218 0 : static inline int ipv4_martian (struct in_addr *addr)
219 : {
220 0 : in_addr_t ip = addr->s_addr;
221 :
222 0 : if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_DE(ip)) {
223 0 : return 1;
224 : }
225 0 : return 0;
226 : }
227 :
228 : #endif /* _ZEBRA_PREFIX_H */
|