1 | /*************************************** 2 | $Revision: 1.5 $ 3 | 4 | Radix payload (rp) - user level functions for storing data in radix trees 5 | 6 | rp_convert = conversion helpers for RX_asc_node and UD module. 7 | 8 | Status: NOT REVIEWED, TESTED 9 | 10 | Design and implementation by: Marek Bukowy 11 | 12 | ******************/ /****************** 13 | Copyright (c) 1999 RIPE NCC 14 | 15 | All Rights Reserved 16 | 17 | Permission to use, copy, modify, and distribute this software and its 18 | documentation for any purpose and without fee is hereby granted, 19 | provided that the above copyright notice appear in all copies and that 20 | both that copyright notice and this permission notice appear in 21 | supporting documentation, and that the name of the author not be 22 | used in advertising or publicity pertaining to distribution of the 23 | software without specific, written prior permission. 24 | 25 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 26 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 27 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 28 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 29 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 30 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 | ***************************************/ 32 | 33 | #include <rp.h> 34 | #include <iproutines.h> 35 | #include <rxroutines.h> 36 | 37 | rx_fam_t RP_attr2fam( rp_attr_t type ) 38 | { 39 | switch( type ) { 40 | case A_RT: return RX_FAM_RT; 41 | case A_IN: return RX_FAM_IN; 42 | case A_DN: return RX_FAM_RT; 43 | case A_I6: return RX_FAM_RT; 44 | default: 45 | die; 46 | return -1; /* will never execute */ 47 | } 48 | } 49 | 50 | /* 51 | returns 1 if the given space may appear for a given attribute 52 | */ 53 | int RP_attr2spc(rp_attr_t type, ip_space_t space) 54 | { 55 | if ( space == IP_V4 ) { 56 | switch( type ) { 57 | case A_DN: 58 | case A_RT: 59 | case A_IN: 60 | return 1; 61 | default: 62 | /* FALLTHROUGH */ ; 63 | } 64 | } 65 | else if( space == IP_V6 ) { 66 | switch( type ) { 67 | case A_DN: 68 | case A_I6: 69 | return 1; 70 | default: 71 | /* FALLTHROUGH */ ; 72 | } 73 | } 74 | else { 75 | die; /* unknown space */ 76 | } 77 | 78 | return 0; 79 | } 80 | 81 | 82 | er_ret_t 83 | RP_asc2uni(char *astr, /*+ string prefix/range/IP/inaddr +*/ 84 | rp_attr_t attr, 85 | rp_uni_t *uni) /* destination pointer */ 86 | { 87 | er_ret_t conv; 88 | rx_fam_t fam_id = RP_attr2fam( attr ); 89 | switch( attr ) { 90 | case A_IN: 91 | conv = IP_rang_e2b(&(uni->u.in), astr); 92 | break; 93 | case A_RT: 94 | case A_I6: 95 | conv = IP_pref_e2b(&(uni->u.rt), astr); 96 | break; 97 | case A_DN: 98 | conv = IP_revd_e2b(&(uni->u.rt), astr); 99 | break; 100 | default: 101 | /* die; / * shouldn't have got here */ 102 | conv = IP_INVARG; 103 | } 104 | 105 | if( conv == IP_OK ) { 106 | uni->fam = fam_id; 107 | 108 | if( fam_id == RX_FAM_RT ) { 109 | uni->space = IP_pref_b2_space( &(uni->u.rt) ); 110 | } else { /* RX_FAM_IN */ 111 | uni->space = IP_rang_b2_space( &(uni->u.in) ); 112 | } 113 | } 114 | 115 | return conv; 116 | } 117 | 118 | 119 | 120 | /* Function to fill data for radix tree */ 121 | /* returns error if string is not valid, also for reverse domains */ 122 | er_ret_t 123 | RP_asc2pack(rp_upd_pack_t *pack, rp_attr_t type, char *string) 124 | { 125 | er_ret_t err; 126 | 127 | pack->type = type; 128 | 129 | ER_dbg_va(FAC_RP, ASP_RP_PACK_DET, 130 | "RP_asc2pack: converted attr %s: %s to pack at %08x", 131 | DF_get_attribute_code(type), string, pack ); 132 | 133 | 134 | err = RP_asc2uni(string, type, &(pack->uni) ); 135 | 136 | if( type == A_DN && err == IP_OK) { 137 | /* Check if it is an in-addr.arpa domain, set domain ptr only then */ 138 | pack->d.domain = string; 139 | } 140 | 141 | return err; 142 | } 143 | 144 | 145 | /* construct -K contents 146 | * 147 | * MT-NOTE: returns POITNER TO STATIC MEMORY !!! 148 | * 149 | * ASSUMES ONLY ONE UPDATE THREAD RUNNING. 150 | */ 151 | void rp_make_short(rp_upd_pack_t *pack, char **ptr, int *len) 152 | { 153 | #define STR_L 2048 154 | static char buf[STR_L]; 155 | char prefstr[IP_PREFSTR_MAX]; 156 | char rangstr[IP_RANGSTR_MAX]; 157 | 158 | switch( pack->type ) { 159 | case A_RT: 160 | dieif( IP_pref_b2a( &(pack->uni.u.rt), prefstr, IP_PREFSTR_MAX) != IP_OK ); 161 | snprintf(buf, STR_L, "route: \t%s\norigin: \t%s\n", prefstr, pack->d.origin); 162 | break; 163 | case A_I6: 164 | dieif( IP_pref_b2a( &(pack->uni.u.rt), prefstr, IP_PREFSTR_MAX) != IP_OK ); 165 | snprintf(buf, STR_L, "inet6num: \t%s\n", prefstr); 166 | break; 167 | case A_IN: 168 | dieif( IP_rang_b2a( &(pack->uni.u.in), rangstr, IP_RANGSTR_MAX) != IP_OK ); 169 | snprintf(buf, STR_L, "inetnum: \t%s\n", rangstr); 170 | break; 171 | case A_DN: 172 | snprintf(buf, STR_L, "domain: \t%s\n", pack->d.domain ); 173 | break; 174 | default: 175 | /* FALLTHROUGH */ 176 | ; 177 | } 178 | 179 | *ptr = buf; 180 | *len = strlen(buf); 181 | } 182 | 183 | /***************** set the values in rx_*_data thingies ***************/ 184 | void RP_pack_set_orig(rp_attr_t attr, rp_upd_pack_t *pack, char *origin) 185 | { 186 | pack->d.origin = origin; 187 | /* ignore attr */ 188 | } 189 | 190 | /* those are just interfacing to 191 | * functions to convert to IP binary format and retain raw values 192 | */ 193 | void RP_pack_set_type(rp_attr_t attr, rp_upd_pack_t *pack) 194 | { 195 | pack->type = attr; 196 | pack->uni.fam = RP_attr2fam( attr ); 197 | } 198 | 199 | void RP_pack_set_pref4(rp_attr_t attr, char *avalue, rp_upd_pack_t *pack, 200 | unsigned *prefix, unsigned *prefix_length) 201 | { 202 | IP_pref_a2v4(avalue, &(pack->uni.u.rt), prefix, prefix_length); 203 | pack->uni.space = IP_V4; 204 | RP_pack_set_type(attr, pack); 205 | } 206 | 207 | void RP_pack_set_revd(rp_attr_t attr, char *avalue, rp_upd_pack_t *pack) 208 | { 209 | dieif(IP_revd_e2b(&(pack->uni.u.rt), avalue) != IP_OK); /* assuming correctness checked */ 210 | pack->d.domain = avalue; 211 | pack->uni.space = IP_pref_b2_space( &(pack->uni.u.rt) ); 212 | RP_pack_set_type(attr, pack); 213 | } 214 | 215 | 216 | void RP_pack_set_pref6(rp_attr_t attr, char *avalue, rp_upd_pack_t *pack, 217 | ip_v6word_t *high, ip_v6word_t *low, unsigned *prefix_length) 218 | { 219 | IP_pref_a2v6(avalue, &(pack->uni.u.rt), high, low, prefix_length); 220 | pack->uni.space = IP_V6; 221 | RP_pack_set_type(attr, pack); 222 | } 223 | 224 | void RP_pack_set_rang(rp_attr_t attr, char *avalue, rp_upd_pack_t *pack, 225 | unsigned *begin_in, unsigned *end_in) 226 | { 227 | IP_rang_a2v4(avalue, (ip_range_t *) &(pack->uni.u.in), 228 | begin_in, end_in); 229 | pack->uni.space = IP_V4; 230 | RP_pack_set_type(attr, pack); 231 | } 232 | 233 | 234 | /***************************************************************************/ 235 | 236 | /***************************************************************************/