00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <stdio.h>
00047
00048 #include "olsr.h"
00049 #include "ipcalc.h"
00050 #include "neighbor_table.h"
00051 #include "tc_set.h"
00052 #include "hna_set.h"
00053 #include "mid_set.h"
00054 #include "routing_table.h"
00055 #include "olsr_ip_prefix_list.h"
00056 #include "parser.h"
00057 #include "olsr_comport_txt.h"
00058 #include "olsr_comport_http.h"
00059 #include "common/string.h"
00060 #include "common/autobuf.h"
00061 #include "plugin_loader.h"
00062 #include "plugin_util.h"
00063
00064 #define PLUGIN_DESCR "OLSRD txtinfo plugin"
00065 #define PLUGIN_AUTHOR "Henning Rogge"
00066
00067
00068 struct txtinfo_cmd {
00069 const char *name;
00070 olsr_txthandler handler;
00071 struct olsr_txtcommand *cmd;
00072 };
00073
00074 static int txtinfo_init(void);
00075 static int txtinfo_enable(void);
00076 static int txtinfo_disable(void);
00077 static int txtinfo_exit(void);
00078
00079 static enum olsr_txtcommand_result txtinfo_neigh(struct comport_connection *con,
00080 const char *cmd, const char *param);
00081 static enum olsr_txtcommand_result txtinfo_neigh2(struct comport_connection *con,
00082 const char *cmd, const char *param);
00083 static enum olsr_txtcommand_result txtinfo_link(struct comport_connection *con,
00084 const char *cmd, const char *param);
00085 static enum olsr_txtcommand_result txtinfo_routes(struct comport_connection *con,
00086 const char *cmd, const char *param);
00087 static enum olsr_txtcommand_result txtinfo_topology(struct comport_connection *con,
00088 const char *cmd, const char *param);
00089 static enum olsr_txtcommand_result txtinfo_hna(struct comport_connection *con,
00090 const char *cmd, const char *param);
00091 static enum olsr_txtcommand_result txtinfo_mid(struct comport_connection *con,
00092 const char *cmd, const char *param);
00093 static enum olsr_txtcommand_result txtinfo_interfaces(struct comport_connection *con,
00094 const char *cmd, const char *param);
00095
00096
00097 static struct ip_acl allowed_nets;
00098
00099
00100 static const struct olsrd_plugin_parameters plugin_parameters[] = {
00101 {.name = IP_ACL_ACCEPT_PARAP,.set_plugin_parameter = &ip_acl_add_plugin_accept,.data = &allowed_nets},
00102 {.name = IP_ACL_REJECT_PARAM,.set_plugin_parameter = &ip_acl_add_plugin_reject,.data = &allowed_nets},
00103 {.name = IP_ACL_CHECKFIRST_PARAM,.set_plugin_parameter = &ip_acl_add_plugin_checkFirst,.data = &allowed_nets},
00104 {.name = IP_ACL_DEFAULTPOLICY_PARAM,.set_plugin_parameter = &ip_acl_add_plugin_defaultPolicy,.data = &allowed_nets}
00105 };
00106
00107 OLSR_PLUGIN6(plugin_parameters) {
00108 .descr = PLUGIN_DESCR,
00109 .author = PLUGIN_AUTHOR,
00110 .init = txtinfo_init,
00111 .enable = txtinfo_enable,
00112 .disable = txtinfo_disable,
00113 .exit = txtinfo_exit,
00114 .deactivate = true
00115 };
00116
00117
00118 static struct txtinfo_cmd commands[] = {
00119 {"link", &txtinfo_link, NULL},
00120 {"neigh", &txtinfo_neigh, NULL},
00121 {"neigh2", &txtinfo_neigh2, NULL},
00122 {"topology", &txtinfo_topology, NULL},
00123 {"hna", &txtinfo_hna, NULL},
00124 {"mid", &txtinfo_mid, NULL},
00125 {"routes", &txtinfo_routes, NULL},
00126 {"interfaces", &txtinfo_interfaces, NULL},
00127 };
00128
00129
00130 static const char KEY_LOCALIP[] = "localip";
00131 static const char KEY_NEIGHIP[] = "neighip";
00132 static const char KEY_ALIASIP[] = "aliasip";
00133 static const char KEY_2HOPIP[] = "2hopip";
00134 static const char KEY_DESTPREFIX[] = "destprefix";
00135 static const char KEY_SYM[] = "issym";
00136 static const char KEY_MPR[] = "ismpr";
00137 static const char KEY_MPRS[] = "ismprs";
00138 static const char KEY_VIRTUAL[] = "isvirtual";
00139 static const char KEY_WILLINGNESS[] = "will";
00140 static const char KEY_2HOP_CNT[] = "2hop";
00141 static const char KEY_LINKCOST[] = "linkcost";
00142 static const char KEY_RAWLINKCOST[] = "rawlinkcost";
00143 static const char KEY_LINKCOST2[] = "linkcost2";
00144 static const char KEY_RAWLINKCOST2[] = "rawlinkcost2";
00145 static const char KEY_HOPCOUNT[] = "hopcount";
00146 static const char KEY_FAILCOUNT[] = "failcount";
00147 static const char KEY_INTERFACE[] = "interface";
00148 static const char KEY_VTIME[] = "vtime";
00149 static const char KEY_STATE[] = "state";
00150 static const char KEY_MTU[] = "mtu";
00151 static const char KEY_SRCIP[] = "srcip";
00152 static const char KEY_DSTIP[] = "dstip";
00153
00154 static struct ipaddr_str buf_localip, buf_neighip, buf_aliasip, buf_2hopip, buf_srcip, buf_dstip;
00155 struct ipprefix_str buf_destprefix;
00156 static char buf_sym[6], buf_mrp[4], buf_mprs[4], buf_virtual[4];
00157 static char buf_willingness[7];
00158 static char buf_2hop_cnt[6];
00159 static char buf_rawlinkcost[11], buf_rawlinkcost2[11];
00160 static char buf_linkcost[LQTEXT_MAXLENGTH], buf_linkcost2[LQTEXT_MAXLENGTH];
00161 static char buf_hopcount[4];
00162 static char buf_failcount[8];
00163 static char buf_state[5];
00164 static char buf_mtu[5];
00165 static char buf_interface[IF_NAMESIZE];
00166 struct millitxt_buf buf_vtime;
00167
00168 static size_t tmpl_indices[32];
00169
00170
00171 static const char *keys_link[] = {
00172 KEY_LOCALIP, KEY_NEIGHIP, KEY_SYM, KEY_MPR, KEY_VTIME,
00173 KEY_RAWLINKCOST, KEY_LINKCOST,
00174 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00175 };
00176 static char *values_link[] = {
00177 buf_localip.buf, buf_neighip.buf, buf_sym, buf_mrp, buf_vtime.buf,
00178 buf_rawlinkcost, buf_linkcost,
00179 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00180 };
00181 static char tmpl_link[256], headline_link[256];
00182 static size_t link_keys_static = 0, link_keys_count = 0, link_value_size = 0;
00183
00184 static const char *tmpl_neigh = "%neighip%\t%issym%\t%ismpr%\t%ismprs%\t%will%\t%2hop%\n";
00185 static const char *keys_neigh[] = {
00186 KEY_NEIGHIP, KEY_SYM, KEY_MPR, KEY_MPRS, KEY_WILLINGNESS, KEY_2HOP_CNT
00187 };
00188 static char *values_neigh[] = {
00189 buf_neighip.buf, buf_sym, buf_mprs, buf_mprs, buf_willingness, buf_2hop_cnt
00190 };
00191
00192 static const char *tmpl_neigh2 = "%neighip%\t%linkcost%\t%2hopip%\t%linkcost2%\n";
00193 static const char *keys_neigh2[] = {
00194 KEY_NEIGHIP, KEY_LINKCOST, KEY_RAWLINKCOST, KEY_2HOPIP, KEY_LINKCOST2, KEY_RAWLINKCOST2
00195 };
00196 static char *values_neigh2[] = {
00197 buf_neighip.buf, buf_linkcost, buf_rawlinkcost, buf_2hopip.buf, buf_linkcost2, buf_rawlinkcost2
00198 };
00199
00200 static const char *tmpl_routes = "%destprefix%\t%neighip%\t%hopcount%\t%linkcost%\t%interface%\t%failcount%\n";
00201 static const char *keys_routes[] = {
00202 KEY_DESTPREFIX, KEY_NEIGHIP, KEY_HOPCOUNT, KEY_VTIME,
00203 KEY_INTERFACE, KEY_RAWLINKCOST, KEY_LINKCOST, KEY_FAILCOUNT
00204 };
00205 static char *values_routes[] = {
00206 buf_destprefix.buf, buf_neighip.buf, buf_hopcount, buf_vtime.buf,
00207 buf_interface, buf_rawlinkcost, buf_linkcost, buf_failcount
00208 };
00209
00210 static const char *tmpl_topology = "%neighip%\t%localip%\t%isvirtual%\t%linkcost%\n";
00211 static const char *keys_topology[] = {
00212 KEY_LOCALIP, KEY_NEIGHIP, KEY_VIRTUAL, KEY_VTIME,
00213 KEY_RAWLINKCOST, KEY_LINKCOST
00214 };
00215 static char *values_topology[] = {
00216 buf_localip.buf, buf_neighip.buf, buf_virtual, buf_vtime.buf,
00217 buf_rawlinkcost, buf_linkcost
00218 };
00219
00220 static const char *tmpl_hna = "%destprefix%\t%localip%\t%vtime%\n";
00221 static const char *keys_hna[] = {
00222 KEY_LOCALIP, KEY_DESTPREFIX, KEY_VTIME
00223 };
00224 static char *values_hna[] = {
00225 buf_localip.buf, buf_destprefix.buf, buf_vtime.buf
00226 };
00227
00228 static const char *tmpl_mid = "%localip%\t%aliasip%\t%vtime%\n";
00229 static const char *keys_mid[] = {
00230 KEY_LOCALIP, KEY_ALIASIP, KEY_VTIME
00231 };
00232 static char *values_mid[] = {
00233 buf_localip.buf, buf_aliasip.buf, buf_vtime.buf
00234 };
00235
00236 static const char *tmpl_interface = "%interface%\t%state%\t%mtu%\t%srcip%\t%dstip%\n";
00237 static const char *keys_interface[] = {
00238 KEY_INTERFACE, KEY_STATE, KEY_MTU,
00239 KEY_SRCIP, KEY_DSTIP
00240 };
00241 static char *values_interface[] = {
00242 buf_interface, buf_state, buf_mtu,
00243 buf_srcip.buf, buf_dstip.buf
00244 };
00245
00246
00247 static const char *OLSR_YES = "yes";
00248 static const char *OLSR_NO = "no";
00249
00253 static int
00254 txtinfo_init(void)
00255 {
00256 ip_acl_init(&allowed_nets);
00257
00258
00259 if (olsr_cnf->ip_version == AF_INET) {
00260 union olsr_ip_addr ip;
00261
00262 ip.v4.s_addr = ntohl(INADDR_LOOPBACK);
00263 ip_acl_add(&allowed_nets, &ip, 32, false);
00264 } else {
00265 ip_acl_add(&allowed_nets, (const union olsr_ip_addr *)&in6addr_loopback, 128, false);
00266 ip_acl_add(&allowed_nets, (const union olsr_ip_addr *)&in6addr_v4mapped_loopback, 128, false);
00267 }
00268 return 0;
00269 }
00270
00274 static int
00275 txtinfo_disable(void)
00276 {
00277 size_t i;
00278
00279 for (i=0; i<ARRAYSIZE(commands); i++) {
00280 olsr_com_remove_normal_txtcommand(commands[i].cmd);
00281 }
00282 for (i=link_keys_static; i<link_keys_count; i++) {
00283 free(values_link[i]);
00284 }
00285 return 0;
00286 }
00287
00288
00289
00290
00291 static int
00292 txtinfo_enable(void)
00293 {
00294 size_t i;
00295
00296
00297 while (keys_link[link_keys_static]) {
00298 link_keys_static++;
00299 link_keys_count++;
00300 }
00301
00302
00303 for (i=1; i<olsr_get_linklabel_count(); i++) {
00304 keys_link[link_keys_static + i - 1] = olsr_get_linklabel(i);
00305 values_link[link_keys_static + i - 1] = olsr_malloc(LQTEXT_MAXLENGTH, "txtinfo linktemplate values");
00306 link_keys_count++;
00307 }
00308 link_value_size = LQTEXT_MAXLENGTH;
00309
00310
00311 strscpy(tmpl_link, "%localip%\t%neighip", sizeof(tmpl_link));
00312 for (i=1; i<olsr_get_linklabel_count(); i++) {
00313 strscat(tmpl_link, "%\t%", sizeof(tmpl_link));
00314 strscat(tmpl_link, olsr_get_linklabel(i), sizeof(tmpl_link));
00315 }
00316 strscat(tmpl_link, "%\t%linkcost%\n", sizeof(tmpl_link));
00317
00318
00319 strscpy(headline_link, "Table: Links\nLocal IP\tRemote IP", sizeof(headline_link));
00320 for (i=1; i<olsr_get_linklabel_count(); i++) {
00321 strscat(headline_link, "\t", sizeof(headline_link));
00322 strscat(headline_link, olsr_get_linklabel(i), sizeof(headline_link));
00323 }
00324 strscat(headline_link, "\t", sizeof(headline_link));
00325 strscat(headline_link, olsr_get_linklabel(0), sizeof(headline_link));
00326 strscat(headline_link, "\n", sizeof(headline_link));
00327
00328 for (i=0; i<ARRAYSIZE(commands); i++) {
00329 commands[i].cmd = olsr_com_add_normal_txtcommand(commands[i].name, commands[i].handler);
00330 commands[i].cmd->acl = &allowed_nets;
00331 }
00332 return 0;
00333 }
00334
00335 static int
00336 txtinfo_exit(void) {
00337 ip_acl_flush(&allowed_nets);
00338 return 0;
00339 }
00340
00346 static char *
00347 parse_user_template(const char *template) {
00348
00349 static char buffer[1024];
00350 char *dst = buffer;
00351
00352 while (*template && (size_t)(dst - buffer) < sizeof(buffer)-1) {
00353 if (*template == '\\') {
00354 template++;
00355 switch (*template) {
00356 case 0:
00357 *dst = 0;
00358 break;
00359 case 'n':
00360 *dst = '\n';
00361 break;
00362 case 't':
00363 *dst = '\t';
00364 break;
00365 case '\\':
00366 *dst = '\\';
00367 break;
00368 default:
00369 *dst++ = '\\';
00370 *dst = *template;
00371 break;
00372 }
00373 }
00374 else {
00375 *dst = *template;
00376 }
00377 template++;
00378 dst++;
00379 }
00380 *dst = 0;
00381 return buffer;
00382 }
00383
00387 static enum olsr_txtcommand_result
00388 txtinfo_neigh(struct comport_connection *con,
00389 const char *cmd __attribute__ ((unused)), const char *param)
00390 {
00391 struct nbr_entry *neigh, *iterator;
00392 const char *template;
00393 int indexLength;
00394
00395 template = param != NULL ? parse_user_template(param) : tmpl_neigh;
00396 if (param == NULL &&
00397 abuf_puts(&con->out, "Table: Neighbors\nIP address\tSYM\tMPR\tMPRS\tWill.\t2 Hop Neighbors\n") < 0) {
00398 return ABUF_ERROR;
00399 }
00400
00401 if ((indexLength = abuf_template_init(keys_neigh, ARRAYSIZE(keys_neigh), template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00402 return ABUF_ERROR;
00403 }
00404
00405
00406 OLSR_FOR_ALL_NBR_ENTRIES(neigh, iterator) {
00407 olsr_ip_to_string(&buf_neighip, &neigh->nbr_addr);
00408 strscpy(buf_sym, neigh->is_sym ? OLSR_YES : OLSR_NO, sizeof(buf_sym));
00409 strscpy(buf_mrp, neigh->is_mpr ? OLSR_YES : OLSR_NO, sizeof(buf_mrp));
00410 strscpy(buf_mprs, neigh->mprs_count>0 ? OLSR_YES : OLSR_NO, sizeof(buf_mprs));
00411
00412 snprintf(buf_willingness, sizeof(buf_willingness), "%d", neigh->willingness);
00413 snprintf(buf_2hop_cnt, sizeof(buf_2hop_cnt), "%d", neigh->con_tree.count);
00414
00415 if (abuf_templatef(&con->out, template, values_neigh, tmpl_indices, indexLength) < 0) {
00416 return ABUF_ERROR;
00417 }
00418 }
00419
00420 return CONTINUE;
00421 }
00422
00426 static enum olsr_txtcommand_result
00427 txtinfo_neigh2(struct comport_connection *con,
00428 const char *cmd __attribute__ ((unused)), const char *param)
00429 {
00430 struct nbr_entry *neigh, *iterator;
00431 struct link_entry *lnk;
00432 struct nbr_con *nbr_con, *con_it;
00433 const char *template;
00434 int indexLength;
00435
00436 template = param != NULL ? parse_user_template(param) : tmpl_neigh2;
00437 if (param == NULL &&
00438 abuf_puts(&con->out, "Table: 2-Hop Neighbors\nIP address\tCost\t2-Hop IP\tCost\n") < 0) {
00439 return ABUF_ERROR;
00440 }
00441
00442 if ((indexLength = abuf_template_init(keys_neigh2, ARRAYSIZE(keys_neigh2), template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00443 return ABUF_ERROR;
00444 }
00445
00446
00447 OLSR_FOR_ALL_NBR_ENTRIES(neigh, iterator) {
00448 olsr_linkcost cost = LINK_COST_BROKEN;
00449
00450 lnk = get_best_link_to_neighbor(neigh);
00451 if (lnk) {
00452 cost = lnk->linkcost;
00453 }
00454
00455 olsr_ip_to_string(&buf_neighip, &neigh->nbr_addr);
00456
00457 snprintf(buf_rawlinkcost, sizeof(buf_rawlinkcost), "%ud", cost);
00458 olsr_get_linkcost_text(cost, false, buf_linkcost, sizeof(buf_linkcost));
00459
00460 OLSR_FOR_ALL_NBR_CON_ENTRIES(neigh, nbr_con, con_it) {
00461 olsr_ip_to_string(&buf_2hopip, &nbr_con->nbr2->nbr2_addr);
00462
00463 snprintf(buf_rawlinkcost2, sizeof(buf_rawlinkcost2), "%ud", nbr_con->second_hop_linkcost);
00464 olsr_get_linkcost_text(nbr_con->second_hop_linkcost, false, buf_linkcost2, sizeof(buf_linkcost2));
00465
00466 if (abuf_templatef(&con->out, template, values_neigh2, tmpl_indices, indexLength) < 0) {
00467 return ABUF_ERROR;
00468 }
00469 }
00470 }
00471
00472 return CONTINUE;
00473 }
00474
00478 static enum olsr_txtcommand_result
00479 txtinfo_link(struct comport_connection *con,
00480 const char *cmd __attribute__ ((unused)), const char *param)
00481 {
00482 struct link_entry *lnk, *iterator;
00483 size_t i;
00484 const char *template;
00485 int indexLength;
00486
00487 template = param != NULL ? parse_user_template(param) : tmpl_link;
00488 if (param == NULL) {
00489 if (abuf_puts(&con->out, headline_link) < 0) {
00490 return ABUF_ERROR;
00491 }
00492 }
00493
00494 if ((indexLength = abuf_template_init(keys_link, link_keys_count,
00495 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00496 return ABUF_ERROR;
00497 }
00498
00499
00500 OLSR_FOR_ALL_LINK_ENTRIES(lnk, iterator) {
00501 olsr_ip_to_string(&buf_localip, &lnk->local_iface_addr);
00502 olsr_ip_to_string(&buf_neighip, &lnk->neighbor_iface_addr);
00503 strscpy(buf_sym, lnk->status == SYM_LINK ? OLSR_YES : OLSR_NO, sizeof(buf_sym));
00504 strscpy(buf_mrp, lnk->is_mpr ? OLSR_YES : OLSR_NO, sizeof(buf_mrp));
00505 olsr_clock_to_string(&buf_vtime, lnk->link_sym_timer == NULL ? 0 : lnk->link_sym_timer->timer_clock - olsr_clock_getNow());
00506 snprintf(buf_rawlinkcost, sizeof(buf_rawlinkcost), "%ud", lnk->linkcost);
00507
00508 olsr_get_linkcost_text(lnk->linkcost, false, buf_linkcost, sizeof(buf_linkcost));
00509 for (i=1; i< olsr_get_linklabel_count(); i++) {
00510 olsr_get_linkdata_text(lnk, i, values_link[link_keys_static + i - 1], link_value_size);
00511 }
00512
00513 if (abuf_templatef(&con->out, template, values_link, tmpl_indices, indexLength) < 0) {
00514 return ABUF_ERROR;
00515 }
00516 }
00517
00518 return CONTINUE;
00519 }
00520
00524 static enum olsr_txtcommand_result
00525 txtinfo_routes(struct comport_connection *con,
00526 const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
00527 {
00528 struct rt_entry *rt, *iterator;
00529 const char *template;
00530 int indexLength;
00531
00532 template = param != NULL ? parse_user_template(param) : tmpl_routes;
00533 if (param == NULL) {
00534 if (abuf_appendf(&con->out, "Table: Routes\nDestination\tGateway IP\tMetric\t%s\tInterface\n",
00535 olsr_get_linklabel(0)) < 0) {
00536 return ABUF_ERROR;
00537 }
00538 }
00539
00540 if ((indexLength = abuf_template_init(keys_routes, ARRAYSIZE(keys_routes),
00541 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00542 return ABUF_ERROR;
00543 }
00544
00545
00546 OLSR_FOR_ALL_RT_ENTRIES(rt, iterator) {
00547 if (!rt->rt_best) {
00548
00549 continue;
00550 }
00551 olsr_ip_prefix_to_string(&buf_destprefix, &rt->rt_dst);
00552 olsr_ip_to_string(&buf_neighip, &rt->rt_best->rtp_nexthop.gateway);
00553
00554 if (rt->failure_count < 0) snprintf(buf_failcount, sizeof(buf_failcount), "%d del", rt->failure_count*(-1));
00555 else if (rt->failure_count == 0) snprintf(buf_failcount, sizeof(buf_failcount), "0");
00556 else snprintf(buf_failcount, sizeof(buf_failcount), "%d add", rt->failure_count);
00557
00558 snprintf(buf_hopcount, sizeof(buf_hopcount), "%d", rt->rt_best->rtp_metric.hops);
00559 snprintf(buf_rawlinkcost, sizeof(buf_rawlinkcost), "%ud", rt->rt_best->rtp_metric.cost);
00560 olsr_get_linkcost_text(rt->rt_best->rtp_metric.cost, true, buf_linkcost, sizeof(buf_linkcost));
00561 strscpy(buf_interface,
00562 rt->rt_best->rtp_nexthop.interface ? rt->rt_best->rtp_nexthop.interface->int_name : "[null]",
00563 sizeof(buf_interface));
00564
00565 if (abuf_templatef(&con->out, template, values_routes, tmpl_indices, indexLength) < 0) {
00566 return ABUF_ERROR;
00567 }
00568 }
00569 return CONTINUE;
00570 }
00571
00575 static enum olsr_txtcommand_result
00576 txtinfo_topology(struct comport_connection *con,
00577 const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
00578 {
00579 struct tc_entry *tc, *iterator;
00580 const char *template;
00581 int indexLength;
00582
00583 template = param != NULL ? parse_user_template(param) : tmpl_topology;
00584 if (param == NULL) {
00585 if (abuf_appendf(&con->out, "Table: Topology\nDest. IP\tLast hop IP\tVirtual\t%s\n",
00586 olsr_get_linklabel(0)) < 0) {
00587 return ABUF_ERROR;
00588 }
00589 }
00590
00591 if ((indexLength = abuf_template_init(keys_topology, ARRAYSIZE(keys_topology),
00592 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00593 return ABUF_ERROR;
00594 }
00595
00596
00597 OLSR_FOR_ALL_TC_ENTRIES(tc, iterator) {
00598 struct tc_edge_entry *tc_edge, *edge_iterator;
00599 olsr_ip_to_string(&buf_localip, &tc->addr);
00600 if (tc->validity_timer) {
00601 olsr_clock_to_string(&buf_vtime, tc->validity_timer->timer_clock - olsr_clock_getNow());
00602 }
00603 else {
00604 strscpy(buf_vtime.buf, "0.0", sizeof(buf_vtime));
00605 }
00606
00607 OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge, edge_iterator) {
00608 olsr_ip_to_string(&buf_neighip, &tc_edge->T_dest_addr);
00609 strscpy(buf_virtual, tc_edge->virtual ? OLSR_YES : OLSR_NO, sizeof(buf_virtual));
00610 if (tc_edge->virtual) {
00611 buf_linkcost[0] = 0;
00612 buf_rawlinkcost[0] = '0';
00613 buf_rawlinkcost[1] = 0;
00614 }
00615 else {
00616 snprintf(buf_rawlinkcost, sizeof(buf_rawlinkcost), "%ud", tc_edge->cost);
00617 olsr_get_linkcost_text(tc_edge->cost, false, buf_linkcost, sizeof(buf_linkcost));
00618 }
00619
00620 if (abuf_templatef(&con->out, template, values_topology, tmpl_indices, indexLength) < 0) {
00621 return ABUF_ERROR;
00622 }
00623 }
00624 }
00625
00626 return CONTINUE;
00627 }
00628
00632 static enum olsr_txtcommand_result
00633 txtinfo_interfaces(struct comport_connection *con,
00634 const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
00635 {
00636 const struct olsr_if_config *ifs;
00637 const char *template;
00638 int indexLength;
00639
00640 template = param != NULL ? parse_user_template(param) : tmpl_interface;
00641 if (param == NULL) {
00642 if (abuf_puts(&con->out, "Table: Interfaces\nName\tState\tMTU\tSrc-Adress\tDst-Adress\n") < 0) {
00643 return ABUF_ERROR;
00644 }
00645 }
00646
00647 if ((indexLength = abuf_template_init(keys_interface, ARRAYSIZE(keys_interface),
00648 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00649 return ABUF_ERROR;
00650 }
00651
00652
00653 for (ifs = olsr_cnf->if_configs; ifs != NULL; ifs = ifs->next) {
00654 const struct interface *const rifs = ifs->interf;
00655
00656
00657 strscpy(buf_interface, ifs->name, sizeof(buf_interface));
00658
00659 if (!rifs) {
00660 snprintf(buf_state, sizeof(buf_state), "DOWN");
00661 snprintf(buf_mtu, sizeof(buf_mtu), "-");
00662 snprintf(buf_srcip.buf, sizeof(buf_srcip.buf), "-");
00663 snprintf(buf_dstip.buf, sizeof(buf_srcip.buf), "-");
00664 } else {
00665 snprintf(buf_mtu, sizeof(buf_mtu), "%d", rifs->int_mtu);
00666 snprintf(buf_state, sizeof(buf_state), "UP");
00667
00668 if (olsr_cnf->ip_version == AF_INET){
00669 ip4_to_string(&buf_srcip, rifs->int_src.v4.sin_addr);
00670 ip4_to_string(&buf_dstip, rifs->int_multicast.v4.sin_addr);
00671 } else {
00672 ip6_to_string(&buf_srcip, &rifs->int_src.v6.sin6_addr);
00673 ip6_to_string(&buf_dstip, &rifs->int_multicast.v6.sin6_addr);
00674 }
00675 }
00676
00677 if (abuf_templatef(&con->out, template,
00678 values_interface, tmpl_indices, indexLength) < 0) {
00679 return ABUF_ERROR;
00680 }
00681 }
00682
00683 return CONTINUE;
00684 }
00685
00689 static enum olsr_txtcommand_result
00690 txtinfo_hna(struct comport_connection *con,
00691 const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
00692 {
00693 const struct ip_prefix_entry *hna, *prefix_iterator;
00694 struct tc_entry *tc, *tc_iterator;
00695 const char *template;
00696 int indexLength;
00697
00698 template = param != NULL ? parse_user_template(param) : tmpl_hna;
00699 if (param == NULL) {
00700 if (abuf_puts(&con->out, "Table: HNA\nDestination\tGateway\tvtime\n") < 0) {
00701 return ABUF_ERROR;
00702 }
00703 }
00704
00705 if ((indexLength = abuf_template_init(keys_hna, ARRAYSIZE(keys_hna),
00706 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00707 return ABUF_ERROR;
00708 }
00709
00710
00711 OLSR_FOR_ALL_IPPREFIX_ENTRIES(&olsr_cnf->hna_entries, hna, prefix_iterator) {
00712 olsr_ip_to_string(&buf_localip, &olsr_cnf->router_id);
00713 olsr_ip_prefix_to_string(&buf_destprefix, &hna->net);
00714 strscpy(buf_vtime.buf, "0.0", sizeof(buf_vtime));
00715
00716 if (abuf_templatef(&con->out, template, values_hna, tmpl_indices, indexLength) < 0) {
00717 return ABUF_ERROR;
00718 }
00719 }
00720
00721
00722 OLSR_FOR_ALL_TC_ENTRIES(tc, tc_iterator) {
00723 struct hna_net *tmp_net, *hna_iterator;
00724
00725 olsr_ip_to_string(&buf_localip, &tc->addr);
00726 if (tc->validity_timer) {
00727 olsr_clock_to_string(&buf_vtime, tc->validity_timer->timer_clock - olsr_clock_getNow());
00728 }
00729 else {
00730 strscpy(buf_vtime.buf, "0.0", sizeof(buf_vtime));
00731 }
00732
00733
00734 OLSR_FOR_ALL_TC_HNA_ENTRIES(tc, tmp_net, hna_iterator) {
00735 olsr_ip_prefix_to_string(&buf_destprefix, &tmp_net->hna_prefix);
00736
00737 if (abuf_templatef(&con->out, template, values_hna, tmpl_indices, indexLength) < 0) {
00738 return ABUF_ERROR;
00739 }
00740 }
00741 }
00742
00743 return CONTINUE;
00744 }
00745
00749 static enum olsr_txtcommand_result
00750 txtinfo_mid(struct comport_connection *con,
00751 const char *cmd __attribute__ ((unused)), const char *param __attribute__ ((unused)))
00752 {
00753 struct tc_entry *tc, *tc_iterator;
00754 struct interface *interface, *ifp_iterator;
00755
00756 const char *template;
00757 int indexLength;
00758
00759 template = param != NULL ? parse_user_template(param) : tmpl_mid;
00760 if (param == NULL) {
00761 if (abuf_puts(&con->out, "Table: MID\nIP address\tAliases\tvtime\n") < 0) {
00762 return ABUF_ERROR;
00763 }
00764 }
00765
00766 if ((indexLength = abuf_template_init(keys_mid, ARRAYSIZE(keys_mid),
00767 template, tmpl_indices, ARRAYSIZE(tmpl_indices))) < 0) {
00768 return ABUF_ERROR;
00769 }
00770
00771 OLSR_FOR_ALL_INTERFACES(interface, ifp_iterator) {
00772 if (olsr_ipcmp(&olsr_cnf->router_id, &interface->ip_addr) != 0) {
00773 olsr_ip_to_string(&buf_localip, &olsr_cnf->router_id);
00774 olsr_ip_to_string(&buf_aliasip, &interface->ip_addr);
00775 strscpy(buf_vtime.buf, "0.0", sizeof(buf_vtime));
00776
00777 if (abuf_templatef(&con->out, template, values_mid, tmpl_indices, indexLength) < 0) {
00778 return ABUF_ERROR;
00779 }
00780 }
00781 }
00782
00783
00784 OLSR_FOR_ALL_TC_ENTRIES(tc, tc_iterator) {
00785 struct mid_entry *alias, *alias_iterator;
00786
00787 olsr_ip_to_string(&buf_localip, &tc->addr);
00788 if (tc->validity_timer) {
00789 if (tc->validity_timer) {
00790 olsr_clock_to_string(&buf_vtime, tc->validity_timer->timer_clock - olsr_clock_getNow());
00791 }
00792 else {
00793 strscpy(buf_vtime.buf, "0.0", sizeof(buf_vtime));
00794 }
00795
00796 OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias, alias_iterator) {
00797 olsr_ip_to_string(&buf_aliasip, &alias->mid_alias_addr);
00798
00799 if (abuf_templatef(&con->out, template, values_mid, tmpl_indices, indexLength) < 0) {
00800 return ABUF_ERROR;
00801 }
00802 }
00803 }
00804 }
00805 return CONTINUE;
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815