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