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