1    | /***************************************
2    |   $Revision: 1.24 $
3    | 
4    |   IP handling (ip). iproutines.h  - header file for conversions routines.
5    |                                     defines data structures for IP module.
6    | 
7    |   Status: NOT REVUED, TESTED
8    | 
9    |   Design and implementation by: Marek Bukowy
10   | 
11   |   ******************/ /******************
12   |   Copyright (c) 1999,2000,2001,2002               RIPE NCC
13   |  
14   |   All Rights Reserved
15   |   
16   |   Permission to use, copy, modify, and distribute this software and its
17   |   documentation for any purpose and without fee is hereby granted,
18   |   provided that the above copyright notice appear in all copies and that
19   |   both that copyright notice and this permission notice appear in
20   |   supporting documentation, and that the name of the author not be
21   |   used in advertising or publicity pertaining to distribution of the
22   |   software without specific, written prior permission.
23   |   
24   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
26   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
27   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30   |   ***************************************/
31   | 
32   | 
33   | #ifndef _IP_H
34   | #define _IP_H
35   | 
36   | /* NOTE: some #include calls are further down in the file */ 
37   | 
38   | #include <sys/types.h>
39   | #include <glib.h>
40   | 
41   | #include <inet6def.h>
42   | 
43   | /*+ the key type (for ascii keys - tells what it was before it was 
44   |     converted into prefixes in smart_conv() +*/
45   | 
46   | typedef enum {
47   |   IPK_UNDEF = 0,
48   |   IPK_RANGE,
49   |   IPK_PREFIX,
50   |   IPK_IP
51   | } ip_keytype_t;
52   | 
53   | /*+ the space type +*/
54   | typedef enum {
55   |   IP_V4 = 1,
56   |   IP_V6
57   | } ip_space_t;  
58   | 
59   | 
60   | typedef unsigned int   ip_limb_t; /* the limb must be at least 32 bit wide */
61   | typedef uint64_t       ip_v6word_t;
62   | /* should use 64bit for ipv6:   
63   |    u_int64_t (bsd,linux)
64   |    uint64_t (solaris)
65   | */
66   | #define IPLIMBNUM (16/sizeof(ip_limb_t))
67   | 
68   | /*+ address structure +*/
69   | typedef struct {
70   |   ip_limb_t  words[IPLIMBNUM];    /*+ 32/128 bit ip addr. SUBJECT TO CHANGE +*/
71   |                              
72   |   ip_space_t space;       /*+ MUST NOT BE char ! prefixes are compared with 
73   | 			    memcmp, so there may be absolutely no unitialised 
74   | 			    bytes  +*/
75   | } ip_addr_internal_t;
76   | 
77   | /*+ prefix structure +*/
78   | typedef struct {
79   |   unsigned                bits;		/*+ length in bits. +*/
80   |   ip_addr_internal_t      ip;	        /*+ the IP of the prefix +*/        
81   | } ip_prefix_internal_t;
82   |  
83   | /*+ range structure +*/
84   | typedef struct {
85   |   ip_addr_internal_t         begin;        /*+ IP where the range begins. +*/
86   |   ip_addr_internal_t         end;          /*+ IP where it ends +*/
87   | } ip_range_internal_t;
88   | 
89   | #if 0/* #ifndef IP_IMPL  -- set this to see accesses to structure members */
90   | /* hide the internals */
91   | typedef struct {char a[sizeof(ip_addr_internal_t)];}    ip_addr_t;
92   | typedef struct {char a[sizeof(ip_range_internal_t)];}   ip_range_t;
93   | typedef struct {char a[sizeof(ip_prefix_internal_t)];}  ip_prefix_t;
94   | #else
95   | typedef ip_addr_internal_t   ip_addr_t;
96   | typedef ip_range_internal_t  ip_range_t;
97   | typedef ip_prefix_internal_t ip_prefix_t;
98   | #endif 
99   | 
100  | 
101  | /*+ 
102  |   stores size/span of an allocation 
103  |   SUBJECT TO CHANGE: will be bigger for IPv6 
104  |   +*/
105  | typedef unsigned int  ip_rangesize_t; 
106  | 
107  | /*+  the length of a string that should be able to hold a prefix / range
108  |     when used with b2a functions.
109  | +*/
110  | #define IP_ADDRSTR_MAX 48
111  | #define IP_PREFSTR_MAX 64
112  | #define IP_RANGSTR_MAX 128
113  | 
114  | /*+ 
115  |   IP expansion mode - for use with t2b functions, they control
116  |   whether the input is supposed to be fully expanded or contain shortcuts
117  |   (eg. enabling saying 0/0 instead 0.0.0.0/0)
118  |   +*/
119  | typedef enum {
120  |   IP_PLAIN = 1,
121  |   IP_EXPN
122  | } ip_exp_t;
123  | 
124  | #include <erroutines.h>
125  | 
126  | #ifdef __cplusplus
127  | extern "C" {
128  | #endif
129  |  
130  | 
131  | 
132  | /* prototypes */
133  | /* text to binary */
134  | er_ret_t IP_addr_t2b(ip_addr_t *ipptr, const char *addr, ip_exp_t expf);
135  | er_ret_t IP_pref_t2b(ip_prefix_t *prefptr, const char *prefstr, ip_exp_t expf);
136  | er_ret_t IP_rang_t2b(ip_range_t *rangptr, const char *rangstr, ip_exp_t expf);
137  | er_ret_t IP_revd_t2b(ip_prefix_t *prefptr, const char *prefstr, ip_exp_t expf);
138  | /* convenience (or call it backward compatibility) macros */
139  | 
140  | /*+ the e2b macros assume fully expanded text  +*/
141  | #define IP_addr_e2b(a,b) IP_addr_t2b(a,b,IP_PLAIN)
142  | #define IP_pref_e2b(a,b) IP_pref_t2b(a,b,IP_PLAIN)
143  | #define IP_rang_e2b(a,b) IP_rang_t2b(a,b,IP_PLAIN)
144  | #define IP_revd_e2b(a,b) IP_revd_t2b(a,b,IP_PLAIN)
145  | 
146  | /*+ the a2b macros will fully expand an address. 
147  |   The details depend on the individual functions. +*/
148  | #define IP_addr_a2b(a,b) IP_addr_t2b(a,b,IP_EXPN)
149  | #define IP_pref_a2b(a,b) IP_pref_t2b(a,b,IP_EXPN)
150  | #define IP_rang_a2b(a,b) IP_rang_t2b(a,b,IP_EXPN)
151  | #define IP_revd_a2b(a,b) IP_revd_t2b(a,b,IP_EXPN)
152  | 
153  | /* text fragments to binary */
154  | er_ret_t IP_addr_f2b_v4(ip_addr_t *addrptr, const char *adrstr);
155  | er_ret_t IP_rang_f2b_v4(ip_range_t *rangptr, const char *beginstr,  const char *endstr);
156  | er_ret_t IP_pref_f2b_v4(ip_prefix_t *prefptr, const char *prefixstr, 
157  | 			const char *lengthstr);
158  | er_ret_t IP_addr_f2b_v6(ip_addr_t *addrptr, const char *msbstr, const char *lsbstr );
159  | er_ret_t IP_pref_f2b_v6(ip_prefix_t *prefptr, const char *msbstr, const char *lsbstr, 
160  | 			const char *lengthstr);
161  | 
162  | er_ret_t IP_addr_b2a(ip_addr_t *binaddr, char *ascaddr, unsigned strmax );
163  | er_ret_t IP_pref_b2a(ip_prefix_t *prefptr, char *ascaddr, unsigned strmax);
164  | er_ret_t IP_rang_b2a(ip_range_t *rangptr, char *ascaddr, unsigned strmax);
165  | er_ret_t IP_rang_classful(ip_range_t *rangptr, ip_addr_t *addrptr);
166  | er_ret_t IP_pref_2_rang( ip_range_t *rangptr, ip_prefix_t *prefptr );
167  |   
168  | /* utility functions: testers/converters */
169  | int  IP_addr_bit_get(ip_addr_t *binaddr, unsigned bitnum);
170  | void IP_addr_bit_set(ip_addr_t *binaddr, unsigned bitnum, unsigned bitval);
171  | int  IP_addr_cmp(ip_addr_t *ptra, ip_addr_t *ptrb, unsigned len);
172  | unsigned  IP_sizebits(ip_space_t spc_id);
173  | void IP_pref_bit_fix( ip_prefix_t *prefix );
174  | int IP_addr_in_pref(ip_addr_t *ptra, ip_prefix_t *prefix);
175  | int IP_addr_in_rang(ip_addr_t *ptra, ip_range_t *rangptr);
176  | er_ret_t IP_smart_conv(char *key, int justcheck, int encomp, 
177  | 		       GList **preflist, ip_exp_t expf, ip_keytype_t *keytype);
178  | er_ret_t IP_smart_range(char *key, ip_range_t *rangptr, ip_exp_t expf, 
179  | 			ip_keytype_t *keytype);
180  | 
181  | 
182  | ip_rangesize_t IP_rang_span( ip_range_t *rangptr );
183  | er_ret_t IP_addr_s2b(ip_addr_t *addrptr, void *addr_in, int addr_len);
184  | 
185  | /* accessor functions */
186  | unsigned IP_addr_b2_space(ip_addr_t *addrptr);
187  | unsigned IP_pref_b2_space(ip_prefix_t *prefix);
188  | unsigned IP_rang_b2_space(ip_range_t *myrang);
189  | 
190  | unsigned IP_addr_b2v4_addr(ip_addr_t *addrptr);
191  | ip_v6word_t IP_addr_b2v6_hi(ip_addr_t *addrptr); 
192  | ip_v6word_t IP_addr_b2v6_lo(ip_addr_t *addrptr);
193  | 
194  | unsigned IP_pref_b2_space(ip_prefix_t *prefix);
195  | unsigned IP_pref_b2_len(ip_prefix_t *prefix);
196  | #define IP_pref_b2v4_len(prefix) IP_pref_b2_len(prefix)
197  | #define IP_pref_b2v6_len(prefix) IP_pref_b2_len(prefix)
198  | 
199  | unsigned IP_pref_b2v4_addr(ip_prefix_t *prefix);
200  | void IP_addr_b2v4(ip_addr_t *addrptr, unsigned *address);
201  | void IP_pref_b2v4(ip_prefix_t *prefptr, 
202  | 		   unsigned int *prefix, 
203  | 		   unsigned int *prefix_length);
204  | #define IP_revd_b2v4(a,b,c) IP_pref_b2v4(a,b,c)
205  | void IP_pref_b2v6(ip_prefix_t *prefptr, 
206  | 		  ip_v6word_t *high, 
207  | 		  ip_v6word_t *low, 
208  | 		  unsigned int *prefix_length);
209  | #define IP_revd_b2v6(a,b,c,d) IP_pref_b2v6(a,b,c,d)
210  | void IP_rang_b2v4(ip_range_t *myrang,
211  | 		  unsigned *begin, 
212  | 		  unsigned *end);
213  | 
214  | /******** constructing from raw values **********/
215  | er_ret_t IP_addr_v4_mk(ip_addr_t *addrptr, unsigned addrval);
216  | er_ret_t IP_addr_v6_mk(ip_addr_t *addrptr,
217  | 		       ip_v6word_t high, ip_v6word_t low);
218  | er_ret_t IP_pref_v4_mk(ip_prefix_t *prefix,
219  | 		       unsigned prefval, unsigned preflen);
220  | er_ret_t IP_rang_v4_mk(ip_range_t *rangptr, 
221  | 		       unsigned addrbegin, unsigned addrend);
222  | /* a2v4 functions to convert the ascii to binary, and
223  |   then set the raw values at the pointers provided. */
224  | er_ret_t IP_pref_a2v4(const char *avalue, ip_prefix_t *pref,
225  | 		      unsigned *prefix, unsigned *prefix_length);
226  | er_ret_t IP_pref_a2v6(const char *avalue, ip_prefix_t *pref,
227  | 		      ip_v6word_t *high, ip_v6word_t  *low,
228  | 		      unsigned *prefix_length);
229  | er_ret_t IP_revd_a2v4(const char *avalue, ip_prefix_t *pref,
230  | 		      unsigned int *prefix, unsigned int *prefix_length);
231  | er_ret_t IP_addr_a2v4(const char *avalue,ip_addr_t *ipaddr, unsigned int *address);
232  | er_ret_t IP_rang_a2v4(const char *rangstr, ip_range_t *myrang,
233  | 		      unsigned int *begin_in, unsigned int *end_in);
234  | 
235  | /* decompose/find encompasssing prefix */
236  | void IP_rang_encomp(ip_range_t *rangptr);
237  | unsigned IP_rang_decomp(ip_range_t *rangptr, GList **preflist);
238  | 
239  | #ifdef __cplusplus
240  | }
241  | #endif
242  | 
243  | /*
244  |   this is to define a constant struct for comparisons.
245  | */
246  | #ifdef IP_IMPL
247  | const ip_addr_t IP_ADDR_UNSPEC={{0,0,0,0},0}; /* unlikely to be real :-)
248  | 					       as there is no space 0 
249  | 					       bonus: it's a natural state after 
250  | 					       initializing to 0 */
251  |  
252  | 
253  | 
254  | 
255  | #else
256  | extern ip_addr_t IP_ADDR_UNSPEC;
257  | #endif
258  | 
259  | #endif /* _IP_H */