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