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