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 */