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