/** * does the work for dump_fifo, traverses the routing tree * and prints route rules if present. * * @param msg MI node that is used to append the informations * @param node pointer to the routing tree node * @param prefix carries the current scan prefix * * @return 0 for success, negative result for error */ static int dump_tree_recursor (struct mi_node* msg, struct dtrie_node_t *node, char *prefix) { char s[256]; char *p; int i; struct route_flags *rf; struct route_rule *rr; struct route_rule_p_list * rl; double prob; struct mi_node* tmp_node = NULL; strcpy (s, prefix); p = s + strlen (s); p[1] = '\0'; for (i = 0; i < cr_match_mode; ++i) { if (node->child[i] != NULL) { *p = i + '0'; /* if there is a problem in processing the child nodes .. return an error */ if(dump_tree_recursor (msg->next, node->child[i], s) < 0) return -1; } } *p = '\0'; for (rf = (struct route_flags *)(node->data); rf != NULL; rf = rf->next) { for (rr = rf->rule_list; rr != NULL; rr = rr->next) { if(rf->dice_max){ prob = (double)(rr->prob * DICE_MAX)/(double)rf->dice_max; } else { prob = rr->prob; } tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, "%10s: %0.3f %%, '%.*s': %s, '%i', '%.*s', '%.*s', '%.*s'\n", strlen(prefix) > 0 ? prefix : "NULL", prob * 100, rr->host.len, rr->host.s, (rr->status ? "ON" : "OFF"), rr->strip, rr->local_prefix.len, rr->local_prefix.s, rr->local_suffix.len, rr->local_suffix.s, rr->comment.len, rr->comment.s); if(!tmp_node) return -1; if(!rr->status && rr->backup && rr->backup->rr){ tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, " Rule is backed up by: %.*s\n", rr->backup->rr->host.len, rr->backup->rr->host.s); if(!tmp_node) return -1; } if(rr->backed_up){ rl = rr->backed_up; i=0; while(rl){ if(rl->rr){ tmp_node = addf_mi_node_child(msg->next, 0, 0, 0, " Rule is backup for: %.*s", rl->rr->host.len, rl->rr->host.s); if(!tmp_node) return -1; } rl = rl->next; i++; } } } } return 0; }
/** * does the work for dump_fifo, traverses the routing tree * and prints route rules if present. * * @param msg MI node that is used to append the informations * @param tree pointer to the routing tree node * @param prefix carries the current scan prefix * * @return mi node containing the route rules */ static int dump_tree_recursor (struct mi_node* msg, struct route_tree_item *tree, char *prefix) { char s[256]; char *p; int i; struct route_flags *rf; struct route_rule *rr; struct route_rule_p_list * rl; double prob; strcpy (s, prefix); p = s + strlen (s); p[1] = '\0'; for (i = 0; i < 10; ++i) { if (tree->nodes[i] != NULL) { *p = i + '0'; dump_tree_recursor (msg->next, tree->nodes[i], s); } } *p = '\0'; for (rf = tree->flag_list; rf != NULL; rf = rf->next) { for (rr = rf->rule_list; rr != NULL; rr = rr->next) { if(rf->dice_max){ prob = (double)(rr->prob * DICE_MAX)/(double)rf->dice_max; } else { prob = rr->prob; } addf_mi_node_child(msg->next, 0, 0, 0, "%10s: %0.3f %%, '%.*s': %s, '%i', '%.*s', '%.*s', '%.*s'\n", strlen(prefix) > 0 ? prefix : "NULL", prob * 100, rr->host.len, rr->host.s, (rr->status ? "ON" : "OFF"), rr->strip, rr->local_prefix.len, rr->local_prefix.s, rr->local_suffix.len, rr->local_suffix.s, rr->comment.len, rr->comment.s); if(!rr->status && rr->backup && rr->backup->rr){ addf_mi_node_child(msg->next, 0, 0, 0, " Rule is backed up by: %.*s\n", rr->backup->rr->host.len, rr->backup->rr->host.s); } if(rr->backed_up){ rl = rr->backed_up; i=0; while(rl){ if(rl->rr){ addf_mi_node_child(msg->next, 0, 0, 0, " Rule is backup for: %.*s", rl->rr->host.len, rl->rr->host.s); } rl = rl->next; i++; } } } } return 0; }
/** * prints the routing data * * @param cmd_tree the MI command tree * @param param the parameter * * @return code 200 on success, code 400 or 500 on failure */ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) { struct route_data_t * rd; str *tmp_str; str empty_str = str_init("<empty>"); if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); return init_mi_tree(500, "error during command processing", 31); } struct mi_root* rpl_tree; struct mi_node* node = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) goto error2; node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing routing information:"); if(node == NULL) goto error; LM_DBG("start processing of data\n"); int i, j; for (i = 0; i < rd->carrier_num; i++) { if (rd->carriers[i]) { tmp_str = (rd->carriers[i] ? rd->carriers[i]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for carrier '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i] ? rd->carriers[i]->id : 0); if(node == NULL) goto error; for (j=0; j<rd->carriers[i]->domain_num; j++) { if (rd->carriers[i]->domains[j] && rd->carriers[i]->domains[j]->tree) { tmp_str = (rd->carriers[i]->domains[j] ? rd->carriers[i]->domains[j]->name : &empty_str); node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain '%.*s' (%i)\n", tmp_str->len, tmp_str->s, rd->carriers[i]->domains[j]->id); if(node == NULL) goto error; if (dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->domains[j]->tree, "") < 0) goto error; } } } } release_data (rd); return rpl_tree; error: free_mi_tree(rpl_tree); error2: release_data (rd); return 0; }
/** * prints the routing data * * @param mi_root the fifo command tree * @param param the parameter * * @return code 200 on success, code 400 or 500 on failure */ struct mi_root* dump_fifo (struct mi_root* cmd_tree, void *param) { struct rewrite_data * rd; if((rd = get_data ()) == NULL) { LM_ERR("error during retrieve data\n"); return init_mi_tree(500, "error during command processing", 31); } struct mi_root* rpl_tree; struct mi_node* node = NULL; rpl_tree = init_mi_tree( 200, MI_OK_S, MI_OK_LEN); if(rpl_tree == NULL) return 0; node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing routing information:"); if(node == NULL) goto error; LM_DBG("start processing of data\n"); int i, j; for (i = 0; i < rd->tree_num; i++) { if (rd->carriers[i]) { node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for carrier %s (%i)\n", rd->carriers[i] ? rd->carriers[i]->name.s : "<empty>", rd->carriers[i] ? rd->carriers[i]->id : 0); if(node == NULL) goto error; for (j=0; j<rd->carriers[i]->tree_num; j++) { if (rd->carriers[i]->trees[j] && rd->carriers[i]->trees[j]->tree) { node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "Printing tree for domain %s\n", rd->carriers[i]->trees[j] ? rd->carriers[i]->trees[j]->name.s : "<empty>"); if(node == NULL) goto error; dump_tree_recursor (&rpl_tree->node, rd->carriers[i]->trees[j]->tree, ""); } } } } release_data (rd); return rpl_tree; return 0; error: release_data (rd); free_mi_tree(rpl_tree); return 0; }