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