1 | /*************************************** 2 | $Revision: 1.11 $ 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,2000,2001,2002 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 "rip.h" 34 | 35 | /* return the family of tree to be used for the given attribute. 36 | die if not defined. 37 | */ 38 | rx_fam_t RP_attr2fam( rp_attr_t type ) 39 | { 40 | rx_fam_t res = DF_attrcode_radix_family( type ); 41 | 42 | dieif(res == -1); 43 | 44 | return res; 45 | } 46 | 47 | 48 | 49 | /* 50 | returns 1 if the given space may appear for a given attribute 51 | */ 52 | int RP_attr2spc(rp_attr_t type, ip_space_t space) 53 | { 54 | char *loadv4 = DF_attrcode_radix_load_v4( type ); 55 | char *loadv6 = DF_attrcode_radix_load_v6( type ); 56 | char *loadqry = ( space == IP_V4 ) ? loadv4 : loadv6; 57 | 58 | return ( loadqry != NULL ); /* 1 if defined, 0 otherwise */ 59 | } 60 | 61 | 62 | er_ret_t 63 | RP_asc2uni(const char *astr, /*+ string prefix/range/IP/inaddr +*/ 64 | rp_attr_t attr, 65 | rp_uni_t *uni) /* destination pointer */ 66 | { 67 | er_ret_t conv; 68 | rx_fam_t fam_id = RP_attr2fam( attr ); 69 | switch( attr ) { 70 | case A_IN: 71 | conv = IP_rang_e2b(&(uni->u.in), astr); 72 | break; 73 | case A_RT: 74 | case A_I6: 75 | conv = IP_pref_e2b(&(uni->u.rt), astr); 76 | break; 77 | case A_DN: 78 | conv = IP_revd_e2b(&(uni->u.rt), astr); 79 | break; 80 | default: 81 | /* die; / * shouldn't have got here */ 82 | conv = IP_INVARG; 83 | } 84 | 85 | if( conv == IP_OK ) { 86 | uni->fam = fam_id; 87 | 88 | if( fam_id == RX_FAM_RT ) { 89 | uni->space = IP_pref_b2_space( &(uni->u.rt) ); 90 | } else { /* RX_FAM_IN */ 91 | uni->space = IP_rang_b2_space( &(uni->u.in) ); 92 | } 93 | } 94 | 95 | return conv; 96 | } 97 | 98 | 99 | 100 | /* Function to fill data for radix tree */ 101 | /* returns error if string is not valid, also for reverse domains */ 102 | er_ret_t 103 | RP_asc2pack(rp_upd_pack_t *pack, rp_attr_t type, const char *string) 104 | { 105 | er_ret_t err; 106 | 107 | pack->type = type; 108 | 109 | ER_dbg_va(FAC_RP, ASP_RP_PACK_DET, 110 | "RP_asc2pack: converted attr %s: %s to pack at %08x", 111 | DF_get_attribute_code(type), string, pack ); 112 | 113 | 114 | err = RP_asc2uni(string, type, &(pack->uni) ); 115 | 116 | if( type == A_DN && err == IP_OK) { 117 | /* Check if it is an in-addr.arpa domain, set domain ptr only then */ 118 | pack->d.domain = string; 119 | } 120 | 121 | return err; 122 | } 123 | 124 | 125 | /* construct -K contents 126 | * 127 | * MT-NOTE: returns POITNER TO STATIC MEMORY !!! 128 | * 129 | * ASSUMES ONLY ONE UPDATE THREAD RUNNING. 130 | */ 131 | void rp_make_short(rp_upd_pack_t *pack, char **ptr, unsigned *len) 132 | { 133 | #undef STR_L 134 | #define STR_L 2048 135 | static char buf[STR_L]; 136 | char prefstr[IP_PREFSTR_MAX]; 137 | char rangstr[IP_RANGSTR_MAX]; 138 | 139 | switch( pack->type ) { 140 | case A_RT: 141 | dieif( IP_pref_b2a( &(pack->uni.u.rt), prefstr, IP_PREFSTR_MAX) != IP_OK ); 142 | snprintf(buf, STR_L, "route: \t%s\norigin: \t%s\n", prefstr, pack->d.origin); 143 | break; 144 | case A_I6: 145 | dieif( IP_pref_b2a( &(pack->uni.u.rt), prefstr, IP_PREFSTR_MAX) != IP_OK ); 146 | snprintf(buf, STR_L, "inet6num: \t%s\n", prefstr); 147 | break; 148 | case A_IN: 149 | dieif( IP_rang_b2a( &(pack->uni.u.in), rangstr, IP_RANGSTR_MAX) != IP_OK ); 150 | snprintf(buf, STR_L, "inetnum: \t%s\n", rangstr); 151 | break; 152 | case A_DN: 153 | snprintf(buf, STR_L, "domain: \t%s\n", pack->d.domain ); 154 | break; 155 | default: 156 | /* FALLTHROUGH */ 157 | ; 158 | } 159 | 160 | *ptr = buf; 161 | *len = strlen(buf); 162 | } 163 | 164 | /***************** set the values in rx_*_data thingies ***************/ 165 | er_ret_t RP_pack_set_orig(rp_attr_t attr, rp_upd_pack_t *pack, const char *origin) 166 | { 167 | pack->d.origin = origin; 168 | return(IP_OK); 169 | /* ignore attr */ 170 | } 171 | 172 | /* those are just interfacing to 173 | * functions to convert to IP binary format and retain raw values 174 | */ 175 | er_ret_t RP_pack_set_type(rp_attr_t attr, rp_upd_pack_t *pack) 176 | { 177 | pack->type = attr; 178 | pack->uni.fam = RP_attr2fam( attr ); 179 | return(IP_OK); 180 | } 181 | 182 | er_ret_t RP_pack_set_pref4(rp_attr_t attr, const char *avalue, rp_upd_pack_t *pack, 183 | unsigned *prefix, unsigned *prefix_length) 184 | { 185 | er_ret_t ret; 186 | if((ret = IP_pref_a2v4(avalue, &(pack->uni.u.rt), prefix, prefix_length)) == IP_OK){ 187 | pack->uni.space = IP_V4; 188 | RP_pack_set_type(attr, pack); 189 | } 190 | return(ret); 191 | } 192 | 193 | er_ret_t RP_pack_set_revd(rp_attr_t attr, const char *avalue, rp_upd_pack_t *pack) 194 | { 195 | dieif(IP_revd_a2b(&(pack->uni.u.rt), avalue) != IP_OK); /* assuming correctness checked */ 196 | pack->d.domain = avalue; 197 | pack->uni.space = IP_pref_b2_space( &(pack->uni.u.rt) ); 198 | RP_pack_set_type(attr, pack); 199 | return(IP_OK); 200 | } 201 | 202 | 203 | er_ret_t RP_pack_set_pref6(rp_attr_t attr, const char *avalue, rp_upd_pack_t *pack, 204 | ip_v6word_t *high, ip_v6word_t *low, unsigned *prefix_length) 205 | { 206 | er_ret_t ret; 207 | if((ret = IP_pref_a2v6(avalue, &(pack->uni.u.rt), high, low, prefix_length)) == IP_OK){ 208 | pack->uni.space = IP_V6; 209 | RP_pack_set_type(attr, pack); 210 | } 211 | return(ret); 212 | } 213 | 214 | er_ret_t RP_pack_set_rang(rp_attr_t attr, const char *avalue, rp_upd_pack_t *pack, 215 | unsigned *begin_in, unsigned *end_in) 216 | { 217 | er_ret_t ret; 218 | if((ret = IP_rang_a2v4(avalue, (ip_range_t *) &(pack->uni.u.in), 219 | begin_in, end_in)) == IP_OK) { 220 | pack->uni.space = IP_V4; 221 | RP_pack_set_type(attr, pack); 222 | } 223 | return(ret); 224 | } 225 | 226 | 227 | /***************************************************************************/ 228 | 229 | /***************************************************************************/