00001
00057 #include "config.h"
00058
00059
00060 #include <libxml/parser.h>
00061 #include <stdio.h>
00062 #include <string.h>
00063
00064 extern int errno;
00065
00066 static xmlValidCtxt cvp;
00072 static inline int parser_init()
00073 {
00074 cvp.userData = (void*)stderr;
00075 cvp.error = (xmlValidityErrorFunc) fprintf;
00076 cvp.warning = (xmlValidityWarningFunc) fprintf;
00077 return 1;
00078 }
00079
00083 static inline void parser_destroy()
00084 {
00085 xmlCleanupParser();
00086 }
00087
00093 static inline void quote_trim_dup(str *dest, char *src)
00094 {
00095 int i=0;
00096 dest->s=0;
00097 dest->len=0;
00098 if (!src) return;
00099 dest->len = strlen(src);
00100 if (src[0]=='\"') {i++;dest->len--;}
00101 if (src[dest->len-1]=='\"') {dest->len--;}
00102
00103 dest->s = shm_malloc(dest->len+1);
00104 if (!dest->s) {
00105 LOG_NO_MEM("shm",dest->len);
00106 dest->len=0;
00107 return;
00108 }
00109 memcpy(dest->s,src+i,dest->len);
00110 dest->s[dest->len]=0;
00111 }
00112
00118 dp_config* parse_dp_config(char* filename)
00119 {
00120 FILE *f=0;
00121 dp_config *x=0;
00122 xmlDocPtr doc=0;
00123 xmlNodePtr root=0,child=0,nephew=0;
00124 xmlChar *xc=0;
00125 int k;
00126 routing_entry *re,*rei;
00127 routing_realm *rr,*rri;
00128
00129 parser_init();
00130
00131 if (!filename){
00132 LOG(L_ERR,"ERROR:parse_dp_config(): filename parameter is null\n");
00133 goto error;
00134 }
00135 f = fopen(filename,"r");
00136 if (!f){
00137 LOG(L_ERR,"ERROR:parse_dp_config(): Error opening <%s> file > %s\n",filename,strerror(errno));
00138 goto error;
00139 }
00140 fclose(f);
00141
00142
00143 x = new_dp_config();
00144 if (!f){
00145 LOG(L_ERR,"ERROR:parse_dp_config(): Error opening <%s> file > %s\n",filename,strerror(errno));
00146 goto error;
00147 }
00148
00149 doc = xmlParseFile(filename);
00150 if (!doc){
00151 LOG(L_ERR,"ERR:parse_dp_config(): This is not a valid XML file <%s>\n",
00152 filename);
00153 goto error;
00154 }
00155
00156 root = xmlDocGetRootElement(doc);
00157 if (!root){
00158 LOG(L_ERR,"ERR:parse_dp_config(): Empty XML <%s>\n",filename);
00159 goto error;
00160 }
00161
00162 k = xmlStrlen(root->name);
00163 if (k>12) k = 12;
00164 if (strncasecmp((char*)root->name,"DiameterPeer",k)!=0){
00165 LOG(L_ERR,"ERR:parse_dp_config(): XML Root is not <DiameterPeer>\n");
00166 goto error;
00167 }
00168
00169 xc = xmlGetProp(root,(xmlChar*)"FQDN");
00170 quote_trim_dup(&(x->fqdn),(char*)xc);
00171 quote_trim_dup(&(x->identity),(char*)xc);
00172
00173 xc = xmlGetProp(root,(xmlChar*)"Realm");
00174 quote_trim_dup(&(x->realm),(char*)xc);
00175
00176 xc = xmlGetProp(root,(xmlChar*)"Vendor_Id");
00177 x->vendor_id = atoi((char*)xc);
00178
00179 xc = xmlGetProp(root,(xmlChar*)"Product_Name");
00180 quote_trim_dup(&(x->product_name),(char*)xc);
00181
00182 xc = xmlGetProp(root,(xmlChar*)"AcceptUnknownPeers");
00183 x->accept_unknown_peers = atoi((char*)xc);
00184
00185 xc = xmlGetProp(root,(xmlChar*)"DropUnknownOnDisconnect");
00186 x->drop_unknown_peers = atoi((char*)xc);
00187
00188 xc = xmlGetProp(root,(xmlChar*)"Tc");
00189 x->tc = atoi((char*)xc);
00190
00191 xc = xmlGetProp(root,(xmlChar*)"Workers");
00192 x->workers = atoi((char*)xc);
00193
00194 xc = xmlGetProp(root,(xmlChar*)"QueueLength");
00195 x->queue_length = atoi((char*)xc);
00196
00197 for(child = root->children; child; child = child->next)
00198 if (child->type == XML_ELEMENT_NODE)
00199 {
00200 if (xmlStrlen(child->name)==4 && strncasecmp((char*)child->name,"Peer",4)==0){
00201
00202 x->peers_cnt++;
00203 }
00204 else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
00205
00206 x->acceptors_cnt++;
00207 }
00208 else if (xmlStrlen(child->name)==4 && (strncasecmp((char*)child->name,"Auth",4)==0||
00209 strncasecmp((char*)child->name,"Acct",4)==0)){
00210
00211 x->applications_cnt++;
00212 }
00213 }
00214 x->peers = shm_malloc(x->peers_cnt*sizeof(peer_config));
00215 if (!x->peers){
00216 LOG_NO_MEM("shm",x->peers_cnt*sizeof(peer_config));
00217 goto error;
00218 }
00219 memset(x->peers,0,x->peers_cnt*sizeof(peer_config));
00220 x->peers_cnt=0;
00221 x->acceptors = shm_malloc(x->acceptors_cnt*sizeof(acceptor_config));
00222 if (!x->acceptors){
00223 LOG_NO_MEM("shm",x->acceptors_cnt*sizeof(acceptor_config));
00224 goto error;
00225 }
00226 memset(x->acceptors,0,x->acceptors_cnt*sizeof(acceptor_config));
00227 x->acceptors_cnt=0;
00228 x->applications = shm_malloc(x->applications_cnt*sizeof(app_config));
00229 if (!x->applications){
00230 LOG_NO_MEM("shm",x->applications_cnt*sizeof(app_config));
00231 goto error;
00232 }
00233 memset(x->applications,0,x->applications_cnt*sizeof(app_config));
00234 x->applications_cnt=0;
00235
00236 for(child = root->children; child; child = child->next)
00237 if (child->type == XML_ELEMENT_NODE)
00238 {
00239 if (xmlStrlen(child->name)==4 && strncasecmp((char*)child->name,"Peer",4)==0){
00240
00241 xc = xmlGetProp(child,(xmlChar*)"FQDN");
00242 quote_trim_dup(&(x->peers[x->peers_cnt].fqdn),(char*)xc);
00243 xc = xmlGetProp(child,(xmlChar*)"Realm");
00244 quote_trim_dup(&(x->peers[x->peers_cnt].realm),(char*)xc);
00245 xc = xmlGetProp(child,(xmlChar*)"port");
00246 x->peers[x->peers_cnt].port = atoi((char*)xc);
00247 x->peers_cnt++;
00248 }
00249 else if (xmlStrlen(child->name)==8 && strncasecmp((char*)child->name,"Acceptor",8)==0){
00250
00251 xc = xmlGetProp(child,(xmlChar*)"bind");
00252 quote_trim_dup(&(x->acceptors[x->acceptors_cnt].bind),(char*)xc);
00253 xc = xmlGetProp(child,(xmlChar*)"port");
00254 x->acceptors[x->acceptors_cnt].port = atoi((char*)xc);
00255 x->acceptors_cnt++;
00256 }
00257 else if (xmlStrlen(child->name)==4 && ((char*)strncasecmp((char*)child->name,"Auth",4)==0||
00258 strncasecmp((char*)child->name,"Acct",4)==0)){
00259
00260 xc = xmlGetProp(child,(xmlChar*)"id");
00261 x->applications[x->applications_cnt].id = atoi((char*)xc);
00262 xc = xmlGetProp(child,(xmlChar*)"vendor");
00263 x->applications[x->applications_cnt].vendor = atoi((char*)xc);
00264 if (child->name[1]=='u'||child->name[1]=='U')
00265 x->applications[x->applications_cnt].type = DP_AUTHORIZATION;
00266 else
00267 x->applications[x->applications_cnt].type = DP_ACCOUNTING;
00268 x->applications_cnt++;
00269 }
00270 else if (xmlStrlen(child->name)==12 && ((char*)strncasecmp((char*)child->name,"DefaultRoute",12)==0)){
00271 if (!x->r_table) {
00272 x->r_table = shm_malloc(sizeof(routing_table));
00273 memset(x->r_table,0,sizeof(routing_table));
00274 }
00275 re = new_routing_entry();
00276 if (re){
00277 xc = xmlGetProp(child,(xmlChar*)"FQDN");
00278 quote_trim_dup(&(re->fqdn),(char*)xc);
00279 xc = xmlGetProp(child,(xmlChar*)"metric");
00280 re->metric = atoi((char*)xc);
00281
00282
00283 if (! x->r_table->routes || re->metric <= x->r_table->routes->metric){
00284 re->next = x->r_table->routes;
00285 x->r_table->routes = re;
00286 }else{
00287 for(rei=x->r_table->routes;rei;rei=rei->next)
00288 if (!rei->next){
00289 rei->next = re;
00290 break;
00291 }else{
00292 if (re->metric <= rei->next->metric){
00293 re->next = rei->next;
00294 rei->next = re;
00295 break;
00296 }
00297 }
00298 }
00299 }
00300 }
00301 else if (xmlStrlen(child->name)==5 && ((char*)strncasecmp((char*)child->name,"Realm",5)==0)){
00302 if (!x->r_table) {
00303 x->r_table = shm_malloc(sizeof(routing_table));
00304 memset(x->r_table,0,sizeof(routing_table));
00305 }
00306 rr = new_routing_realm();
00307 if (rr){
00308 xc = xmlGetProp(child,(xmlChar*)"name");
00309 quote_trim_dup(&(rr->realm),(char*)xc);
00310
00311 if (!x->r_table->realms) {
00312 x->r_table->realms = rr;
00313 }else{
00314 for(rri=x->r_table->realms;rri->next;rri=rri->next);
00315 rri->next = rr;
00316 }
00317 for(nephew = child->children; nephew; nephew = nephew->next)
00318 if (nephew->type == XML_ELEMENT_NODE){
00319 if (xmlStrlen(nephew->name)==5 && ((char*)strncasecmp((char*)nephew->name,"Route",5)==0))
00320 {
00321 re = new_routing_entry();
00322 if (re) {
00323 xc = xmlGetProp(nephew,(xmlChar*)"FQDN");
00324 quote_trim_dup(&(re->fqdn),(char*)xc);
00325 xc = xmlGetProp(nephew,(xmlChar*)"metric");
00326 re->metric = atoi((char*)xc);
00327
00328
00329 if (! rr->routes || re->metric <= rr->routes->metric){
00330 re->next = rr->routes;
00331 rr->routes = re;
00332 }else{
00333 for(rei=rr->routes;rei;rei=rei->next)
00334 if (!rei->next){
00335 rei->next = re;
00336 break;
00337 }else{
00338 if (re->metric <= rei->next->metric){
00339 re->next = rei->next;
00340 rei->next = re;
00341 break;
00342 }
00343 }
00344 }
00345 }
00346 }
00347 }
00348 }
00349 }
00350 }
00351
00352 if (doc) xmlFreeDoc(doc);
00353 parser_destroy();
00354 return x;
00355 error:
00356 if (doc) xmlFreeDoc(doc);
00357 parser_destroy();
00358 if (x) free_dp_config(x);
00359 return 0;
00360 }
00361