1 | /*************************************** 2 | $Revision: 1.16 $ 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 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 | #include <glib.h> 37 | #include <erroutines.h> 38 | 39 | #include <sys/types.h> 40 | 41 | /*+ the key type (for ascii keys - tells what it was before it was 42 | converted into prefixes in smart_conv() +*/ 43 | 44 | typedef enum { 45 | IPK_UNDEF = 0, 46 | IPK_RANGE, 47 | IPK_PREFIX, 48 | IPK_IP 49 | } ip_keytype_t; 50 | 51 | /*+ the space type +*/ 52 | typedef enum { 53 | IP_V4 = 1, 54 | IP_V6 55 | } ip_space_t; 56 | 57 | 58 | typedef unsigned int ip_limb_t; /* the limb must be at least 32 bit wide */ 59 | #ifdef _LINUX 60 | typedef u_int64_t ip_v6word_t; 61 | #else 62 | typedef uint64_t ip_v6word_t; 63 | #endif 64 | /* should use 64bit for ipv6: 65 | u_int64_t (bsd,linux) 66 | uint64_t (solaris) 67 | */ 68 | #define IPLIMBNUM (16/sizeof(ip_limb_t)) 69 | 70 | /*+ address structure +*/ 71 | typedef struct { 72 | ip_limb_t words[IPLIMBNUM]; /*+ 32/128 bit ip addr. SUBJECT TO CHANGE +*/ 73 | 74 | ip_space_t space; /*+ MUST NOT BE char ! prefixes are compared with 75 | memcmp, so there may be absolutely no unitialised 76 | bytes +*/ 77 | } ip_addr_internal_t; 78 | 79 | /*+ prefix structure +*/ 80 | typedef struct { 81 | unsigned bits; /*+ length in bits. +*/ 82 | ip_addr_internal_t ip; /*+ the IP of the prefix +*/ 83 | } ip_prefix_internal_t; 84 | 85 | /*+ range structure +*/ 86 | typedef struct { 87 | ip_addr_internal_t begin; /*+ IP where the range begins. +*/ 88 | ip_addr_internal_t end; /*+ IP where it ends +*/ 89 | } ip_range_internal_t; 90 | 91 | #if 0/* #ifndef IP_IMPL -- set this to see accesses to structure members */ 92 | /* hide the internals */ 93 | typedef struct {char a[sizeof(ip_addr_internal_t)];} ip_addr_t; 94 | typedef struct {char a[sizeof(ip_range_internal_t)];} ip_range_t; 95 | typedef struct {char a[sizeof(ip_prefix_internal_t)];} ip_prefix_t; 96 | #else 97 | typedef ip_addr_internal_t ip_addr_t; 98 | typedef ip_range_internal_t ip_range_t; 99 | typedef ip_prefix_internal_t ip_prefix_t; 100 | #endif 101 | 102 | 103 | /*+ 104 | stores size/span of an allocation 105 | SUBJECT TO CHANGE: will be bigger for IPv6 106 | +*/ 107 | typedef unsigned int ip_rangesize_t; 108 | 109 | /*+ the length of a string that should be able to hold a prefix / range 110 | when used with b2a functions. 111 | +*/ 112 | #define IP_ADDRSTR_MAX 20 /* XXX watch out for IPv6 !! */ 113 | #define IP_PREFSTR_MAX 24 114 | #define IP_RANGSTR_MAX 48 115 | 116 | /*+ 117 | IP expansion mode - for use with t2b functions, they control 118 | whether the input is supposed to be fully expanded or contain shortcuts 119 | (eg. enabling saying 0/0 instead 0.0.0.0/0) 120 | +*/ 121 | typedef enum { 122 | IP_PLAIN = 1, 123 | IP_EXPN 124 | } ip_exp_t; 125 | 126 | /* prototypes */ 127 | /* text to binary */ 128 | er_ret_t IP_addr_t2b(ip_addr_t *ipptr, char *addr, ip_exp_t expf); 129 | er_ret_t IP_pref_t2b(ip_prefix_t *prefptr, char *prefstr, ip_exp_t expf); 130 | er_ret_t IP_rang_t2b(ip_range_t *rangptr, char *rangstr, ip_exp_t expf); 131 | er_ret_t IP_revd_t2b(ip_prefix_t *prefptr, char *prefstr, ip_exp_t expf); 132 | /* convenience (or call it backward compatibility) macros */ 133 | 134 | /*+ the e2b macros assume fully expanded text +*/ 135 | #define IP_addr_e2b(a,b) IP_addr_t2b(a,b,IP_PLAIN) 136 | #define IP_pref_e2b(a,b) IP_pref_t2b(a,b,IP_PLAIN) 137 | #define IP_rang_e2b(a,b) IP_rang_t2b(a,b,IP_PLAIN) 138 | #define IP_revd_e2b(a,b) IP_revd_t2b(a,b,IP_PLAIN) 139 | 140 | /*+ the a2b macros will fully expand an address. 141 | The details depend on the individual functions. +*/ 142 | #define IP_addr_a2b(a,b) IP_addr_t2b(a,b,IP_EXPN) 143 | #define IP_pref_a2b(a,b) IP_pref_t2b(a,b,IP_EXPN) 144 | #define IP_rang_a2b(a,b) IP_rang_t2b(a,b,IP_EXPN) 145 | #define IP_revd_a2b(a,b) IP_revd_t2b(a,b,IP_EXPN) 146 | 147 | /* text fragments to binary */ 148 | er_ret_t IP_addr_f2b_v4(ip_addr_t *addrptr, char *adrstr); 149 | er_ret_t IP_rang_f2b_v4(ip_range_t *rangptr, char *beginstr, char *endstr); 150 | er_ret_t IP_pref_f2b_v4(ip_prefix_t *prefptr, char *prefixstr, 151 | char *lengthstr); 152 | er_ret_t IP_addr_f2b_v6(ip_addr_t *addrptr, char *msbstr, char *lsbstr ); 153 | er_ret_t IP_pref_f2b_v6(ip_prefix_t *prefptr, char *msbstr, char *lsbstr, 154 | char *lengthstr); 155 | 156 | er_ret_t IP_addr_b2a(ip_addr_t *binaddr, char *ascaddr, int strmax ); 157 | er_ret_t IP_pref_b2a(ip_prefix_t *prefptr, char *ascaddr, int strmax); 158 | er_ret_t IP_rang_b2a(ip_range_t *rangptr, char *ascaddr, int strmax); 159 | er_ret_t IP_rang_classful(ip_range_t *rangptr, ip_addr_t *addrptr); 160 | er_ret_t IP_pref_2_rang( ip_range_t *rangptr, ip_prefix_t *prefptr ); 161 | 162 | /* utility functions: testers/converters */ 163 | int IP_addr_bit_get(ip_addr_t *binaddr, int bitnum); 164 | void IP_addr_bit_set(ip_addr_t *binaddr, int bitnum, int bitval); 165 | int IP_addr_cmp(ip_addr_t *ptra, ip_addr_t *ptrb, int len); 166 | int IP_sizebits(ip_space_t spc_id); 167 | void IP_pref_bit_fix( ip_prefix_t *prefix ); 168 | int IP_addr_in_pref(ip_addr_t *ptra, ip_prefix_t *prefix); 169 | int IP_addr_in_rang(ip_addr_t *ptra, ip_range_t *rangptr); 170 | er_ret_t IP_smart_conv(char *key, int justcheck, int encomp, 171 | GList **preflist, ip_exp_t expf, ip_keytype_t *keytype); 172 | er_ret_t IP_smart_range(char *key, ip_range_t *rangptr, ip_exp_t expf, 173 | ip_keytype_t *keytype); 174 | 175 | 176 | ip_rangesize_t IP_rang_span( ip_range_t *rangptr ); 177 | er_ret_t IP_addr_s2b(ip_addr_t *addrptr, void *addr_in, int addr_len); 178 | 179 | /* accessor functions */ 180 | unsigned IP_addr_b2_space(ip_addr_t *addrptr); 181 | unsigned IP_pref_b2_space(ip_prefix_t *prefix); 182 | unsigned IP_rang_b2_space(ip_range_t *myrang); 183 | 184 | unsigned IP_addr_b2v4_addr(ip_addr_t *addrptr); 185 | ip_v6word_t IP_addr_b2v6_hi(ip_addr_t *addrptr); 186 | ip_v6word_t IP_addr_b2v6_lo(ip_addr_t *addrptr); 187 | 188 | unsigned IP_pref_b2_space(ip_prefix_t *prefix); 189 | unsigned IP_pref_b2_len(ip_prefix_t *prefix); 190 | #define IP_pref_b2v4_len(prefix) IP_pref_b2_len(prefix) 191 | #define IP_pref_b2v6_len(prefix) IP_pref_b2_len(prefix) 192 | 193 | unsigned IP_pref_b2v4_addr(ip_prefix_t *prefix); 194 | void IP_addr_b2v4(ip_addr_t *addrptr, unsigned *address); 195 | void IP_pref_b2v4(ip_prefix_t *prefptr, 196 | unsigned int *prefix, 197 | unsigned int *prefix_length); 198 | #define IP_revd_b2v4(a,b,c) IP_pref_b2v4(a,b,c) 199 | void IP_pref_b2v6(ip_prefix_t *prefptr, 200 | ip_v6word_t *high, 201 | ip_v6word_t *low, 202 | unsigned int *prefix_length); 203 | #define IP_revd_b2v6(a,b,c,d) IP_pref_b2v6(a,b,c,d) 204 | void IP_rang_b2v4(ip_range_t *myrang, 205 | unsigned *begin, 206 | unsigned *end); 207 | 208 | /******** constructing from raw values **********/ 209 | er_ret_t IP_addr_v4_mk(ip_addr_t *addrptr, unsigned addrval); 210 | er_ret_t IP_addr_v6_mk(ip_addr_t *addrptr, 211 | ip_v6word_t high, ip_v6word_t low); 212 | er_ret_t IP_pref_v4_mk(ip_prefix_t *prefix, 213 | unsigned prefval, unsigned preflen); 214 | er_ret_t IP_rang_v4_mk(ip_range_t *rangptr, 215 | unsigned addrbegin, unsigned addrend); 216 | /* a2v4 functions to convert the ascii to binary, and 217 | then set the raw values at the pointers provided. */ 218 | er_ret_t IP_pref_a2v4(char *avalue, ip_prefix_t *pref, 219 | unsigned *prefix, unsigned *prefix_length); 220 | er_ret_t IP_pref_a2v6(char *avalue, ip_prefix_t *pref, 221 | ip_v6word_t *high, ip_v6word_t *low, 222 | unsigned *prefix_length); 223 | er_ret_t IP_revd_a2v4(char *avalue, ip_prefix_t *pref, 224 | unsigned int *prefix, unsigned int *prefix_length); 225 | er_ret_t IP_addr_a2v4(char *avalue,ip_addr_t *ipaddr, unsigned int *address); 226 | er_ret_t IP_rang_a2v4(char *rangstr, ip_range_t *myrang, 227 | unsigned int *begin_in, unsigned int *end_in); 228 | 229 | /* decompose/find encompasssing prefix */ 230 | void IP_rang_encomp(ip_range_t *rangptr); 231 | unsigned IP_rang_decomp(ip_range_t *rangptr, GList **preflist); 232 | 233 | /* 234 | this is to define a constant struct for comparisons. 235 | */ 236 | #ifdef IP_IMPL 237 | const ip_addr_t IP_ADDR_UNSPEC={{0,0,0,0},0}; /* unlikely to be real :-) 238 | as there is no space 0 239 | bonus: it's a natural state after 240 | initializing to 0 */ 241 | #else 242 | extern ip_addr_t IP_ADDR_UNSPEC; 243 | #endif 244 | 245 | #endif /* _IP_H */