📄 ospfd_browser.c
字号:
/* * OSPFD routing daemon * Copyright (C) 1998 by John T. Moy * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/time.h>#include <unistd.h>#include <tcl8.3/tcl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include <signal.h>#include <syslog.h>#include "../src/ospfinc.h"#include "../src/monitor.h"#include "../src/system.h"#include "tcppkt.h"#include <time.h>// External referencesvoid print_lsa(LShdr *hdr);// Forward referencesconst char *yesorno(byte val);void get_statistics(bool print);int get_areas(bool print);void get_interfaces();void print_interface(MonMsg *m);void get_neighbors();void print_neighbor(MonMsg *m);void get_database(byte lstype);void select_lsa();void get_lsa();void get_rttbl();void display_html(char *);void display_error(char *);void get_opaques();const int OSPFD_MON_PORT = 12767;TcpPkt *monpkt;char buffer[80];uns32 ospf_router_id;byte id;int monfd;PatTree pairs;bool header_printed = false;/* External defintions of the raw pages. */extern char *page_header;extern char *page_footer;extern char *query_attach;extern char *statistics_page;extern char *area_header;extern char *area_row;extern char *area_footer;extern char *database_page_top;extern char *ase_page_top;extern char *database_row;extern char *database_page_bottom;extern char *select_area_top;extern char *select_area_bottom;extern char *interface_page_top;extern char *interface_row;extern char *interface_page_bottom;extern char *neighbor_page_top;extern char *neighbor_row;extern char *neighbor_page_bottom;extern char *rttbl_page_top;extern char *rttbl_row;extern char *rttbl_page_bottom;extern char *select_lsa_top;extern char *select_lsa_bottom;extern char *expand_lsa_top;extern char *expand_lsa_bottom;extern char *error_page;extern char *opaque_page_top;extern char *opaque_row;/* Class used to store the value-pairs returned * by the html server. */class ValuePair : public PatEntry { public: char *value; int vlen; ValuePair(char *s, const char *v); ~ValuePair();};/* Constructor for a value pair */ValuePair::ValuePair(char *s, const char *v){ keylen = strlen(s); key = new byte[keylen]; memcpy(key, s, keylen); vlen = strlen(v); value = new char[vlen+1]; memcpy(value, v, vlen); value[vlen] = '\0';}/* Destructor for a value pair. Free the allocated * strings. */ValuePair::~ValuePair(){ delete [] key; delete [] value;}/* Add a value pair to a given tree. * If the value pair already exists, just * substitute the new value. */void addVP(PatTree *tree, char *s, const char *v){ ValuePair *entry; entry = (ValuePair *) tree->find(s); if (!entry) { entry = new ValuePair(s, v); tree->add(entry); } else { delete [] entry->value; entry->vlen = strlen(v); entry->value = new char[entry->vlen+1]; memcpy(entry->value, v, entry->vlen); entry->value[entry->vlen] = '\0'; }}/* The ospfd_html program is a CGI application * that establishes a TCP connection to the ospfd * routing daemon, and then based on information * received from the web server, returns the correct * pages of information. */int main(int argc, char *argv[]){ int port; hostent *hostp; char *qs; char *vp; in_addr in; ValuePair *entry; bool attached=true; puts("Content-type: text/html\n\n"); addVP(&pairs, "errno", "error unknown"); addVP(&pairs, "cstate", "unattached"); // Set host and port defaults if (gethostname(buffer, sizeof(buffer)) != 0) { display_error("gethostname"); exit(0); } if (!(hostp = gethostbyname(buffer))) { display_html(page_header); addVP(&pairs, "operation", "gethostbyname"); sprintf(buffer, "host error #%d", h_errno); addVP(&pairs, "errno", buffer); display_html(error_page); display_html(page_footer); exit(0); } in.s_addr = *(uns32 *)(hostp->h_addr); port = OSPFD_MON_PORT; // Parse the query string coming from the server qs = getenv("QUERY_STRING"); vp = qs ? strtok(qs, "&") : 0; while (vp != 0) { char *value; value = strchr(vp, '='); *value = '\0'; value++; addVP(&pairs, vp, value); vp = strtok(0, "&"); } if (!pairs.find("addr")) { attached = false; addVP(&pairs, "addr", inet_ntoa(in)); } if (!pairs.find("port")) { attached = false; sprintf(buffer, "%d", port); addVP(&pairs, "port", buffer); } if (attached) { entry = (ValuePair *)pairs.find("addr"); sprintf(buffer, "%s", entry->value); addVP(&pairs, "cstate", buffer); } display_html(page_header); header_printed = true; if (!attached) { display_html(query_attach); } else { sockaddr_in saddr; char *command=0; // Open monitoring connection if ((monfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { display_error("socket"); exit(0); } entry = (ValuePair *)pairs.find("addr"); memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr(entry->value); entry = (ValuePair *)pairs.find("port"); saddr.sin_port = hton16(atoi(entry->value)); if (connect(monfd, (sockaddr *) &saddr, sizeof(saddr)) < 0) { display_error("connect"); exit(0); } monpkt = new TcpPkt(monfd); // Switch on command if ((entry = (ValuePair *)pairs.find("command"))) command = entry->value; if (!command || strncmp(command, "stat", 4) == 0) get_statistics(true); else if (strncmp(command, "area", 4) == 0) get_areas(true); else if (strncmp(command, "data", 4) == 0) get_database(0); else if (strncmp(command, "as", 2) == 0) get_database(LST_ASL); else if (strncmp(command, "int", 3) == 0) get_interfaces(); else if (strncmp(command, "nei", 3) == 0) get_neighbors(); else if (strncmp(command, "route", 5) == 0) get_rttbl(); else if (strncmp(command, "lsa", 3) == 0) select_lsa(); else if (strncmp(command, "adv", 3) == 0) get_lsa(); else if (strncmp(command, "opqs", 4) == 0) get_opaques(); } display_html(page_footer); exit(0);}/* Get global OSPF statistics */void get_statistics(bool print){ MonMsg req; int mlen; MonHdr *mhdr; MonMsg *m; uns16 type; uns16 subtype; StatRsp *s; in_addr in; req.hdr.version = OSPF_MON_VERSION; req.hdr.retcode = 0; req.hdr.exact = 0; mlen = sizeof(MonHdr); req.hdr.id = hton16(id++); if (!monpkt->sendpkt_suspend(&req, MonReq_Stat, 0, mlen)) { display_error("Send failed"); exit(0); } if (monpkt->rcv_suspend((void **)&mhdr, type, subtype) == -1) { display_error("Receive failed"); exit(0); } m = (MonMsg *) mhdr; s = &m->body.statrsp; in.s_addr = s->router_id; addVP(&pairs, "router_id", inet_ntoa(in)); sprintf(buffer, "%d", ntoh32(s->n_aselsas)); addVP(&pairs, "n_ases", buffer); sprintf(buffer, "0x%x", ntoh32(s->asexsum)); addVP(&pairs, "ase_xsum", buffer); sprintf(buffer, "%d", ntoh32(s->n_ase_import)); addVP(&pairs, "n_ase_orig", buffer); sprintf(buffer, "%d", ntoh32(s->extdb_limit)); addVP(&pairs, "ase_ceiling", buffer); sprintf(buffer, "%d", ntoh32(s->n_dijkstra)); addVP(&pairs, "n_dijkstra", buffer); sprintf(buffer, "%d", ntoh16(s->n_area)); addVP(&pairs, "n_areas", buffer); sprintf(buffer, "%d", ntoh16(s->n_dbx_nbrs)); addVP(&pairs, "n_exchange", buffer); addVP(&pairs, "mospf", yesorno(s->mospf)); addVP(&pairs, "ia_multicast", yesorno(s->inter_area_mc)); addVP(&pairs, "as_multicast", yesorno(s->inter_AS_mc)); addVP(&pairs, "overflow", yesorno(s->overflow_state)); sprintf(buffer, "%d.%d", s->vmajor, s->vminor); addVP(&pairs, "sw_vers", buffer); if (print) display_html(statistics_page);}/* Print out a line for each attached area. */int get_areas(bool print){ MonMsg req; int mlen; uns32 a_id; int i; int n_areas=0; get_statistics(false); if (print) display_html(area_header); for (a_id = 0, i = 0; ; i++) { MonHdr *mhdr; MonMsg *m; in_addr in; AreaRsp *arearsp; int n_lsas; uns16 type; uns16 subtype; req.hdr.version = OSPF_MON_VERSION; req.hdr.retcode = 0; req.hdr.exact = (i == 0) ? 1 : 0; req.body.arearq.area_id = hton32(a_id); mlen = sizeof(MonHdr) + sizeof(MonRqArea); req.hdr.id = hton16(id++); if (!monpkt->sendpkt_suspend(&req, MonReq_Area, 0, mlen)) { display_error("Send failed"); exit(0); } if (monpkt->rcv_suspend((void **)&mhdr, type, subtype) == -1) { display_error("Receive failed"); exit(0); } m = (MonMsg *) mhdr; if (m->hdr.retcode != 0) { if (i != 0) break; continue; } a_id = ntoh32(m->body.arearsp.area_id); arearsp = &m->body.arearsp; // Print out Area info in = *((in_addr *) &arearsp->area_id); sprintf(buffer, "area_id%d", n_areas); addVP(&pairs, buffer, inet_ntoa(in)); n_areas++; addVP(&pairs, "area_id", inet_ntoa(in)); sprintf(buffer, "%d", ntoh16(arearsp->n_ifcs)); addVP(&pairs, "n_ifcs", buffer); sprintf(buffer, "%d", ntoh16(arearsp->n_routers)); addVP(&pairs, "n_rtrs", buffer); n_lsas = ntoh16(arearsp->n_rtrlsas); n_lsas += ntoh16(arearsp->n_netlsas); n_lsas += ntoh16(arearsp->n_summlsas); n_lsas += ntoh16(arearsp->n_asbrlsas); n_lsas += ntoh16(arearsp->n_grplsas); sprintf(buffer, "%d", n_lsas); addVP(&pairs, "n_lsas", buffer); sprintf(buffer, "0x%x", ntoh32(arearsp->dbxsum)); addVP(&pairs, "area_xsum", buffer); buffer[0] = '\0'; if (arearsp->transit) strcat(buffer, "transit "); if (arearsp->demand) strcat(buffer, "demand-capable "); if (arearsp->stub) strcat(buffer, "stub "); if (!arearsp->import_summ) strcat(buffer, "no-import "); addVP(&pairs, "comments", buffer); if (print) display_html(area_row); } if (print) display_html(area_footer); return(n_areas);}/* Get the link-state database of a given area, printing * one line for each LSA. If called with LS type of 5 * dumps AS-external-LSAs instead. */void get_database(byte lstype){ MonMsg req; int mlen; uns32 a_id; uns32 ls_id; uns32 adv_rtr; byte new_lstype; int n_lsas = 0; uns32 xsum = 0; ValuePair *entry; get_statistics(false); if ((entry = (ValuePair *)pairs.find("area_id"))) { a_id = ntoh32(inet_addr(entry->value)); display_html(database_page_top); } else if (lstype != LST_ASL) { if (get_areas(false) > 1) { display_html(select_area_top); for (int i=0; ; i++) { sprintf(buffer, "area_id%d", i); if (!(entry = (ValuePair *)pairs.find(buffer))) break; printf("<option>%s\n", entry->value); } display_html(select_area_bottom); return; } else { entry = (ValuePair *)pairs.find("area_id"); a_id = ntoh32(inet_addr(entry->value)); display_html(database_page_top); } } else { a_id = 0; display_html(ase_page_top); } ls_id = 0; adv_rtr = 0; new_lstype = lstype; while (1) { MonHdr *mhdr; MonMsg *m; LShdr *lshdr; in_addr in; uns16 type; uns16 subtype; age_t age; char *ptr; req.hdr.version = OSPF_MON_VERSION; req.hdr.retcode = 0; req.hdr.exact = 0; req.body.lsarq.area_id = hton32(a_id); req.body.lsarq.ls_type = hton32(new_lstype); req.body.lsarq.ls_id = hton32(ls_id); req.body.lsarq.adv_rtr = hton32(adv_rtr); mlen = sizeof(MonHdr) + sizeof(MonRqLsa); req.hdr.id = hton16(id++); if (!monpkt->sendpkt_suspend(&req, MonReq_LSA, 0, mlen)) { display_error("Send failed"); exit(0); } if (monpkt->rcv_suspend((void **)&mhdr, type, subtype) == -1) { display_error("Receive failed"); exit(0); } m = (MonMsg *) mhdr; if (m->hdr.retcode != 0) break; if (a_id != ntoh32(m->body.lsarq.area_id)) break; new_lstype = ntoh32(m->body.lsarq.ls_type); if (new_lstype != lstype) { if (lstype == LST_ASL) break; if (new_lstype == LST_ASL) { new_lstype++; ls_id = 0; adv_rtr = 0; continue; } } ls_id = ntoh32(m->body.lsarq.ls_id); adv_rtr = ntoh32(m->body.lsarq.adv_rtr); n_lsas++; lshdr = (LShdr *) (((char *) m) + mlen); xsum += ntoh16(lshdr->ls_xsum); sprintf(buffer, "%d", lshdr->ls_type); addVP(&pairs, "ls_typeno", buffer); // Print out Link state header switch (lshdr->ls_type) { case LST_RTR: addVP(&pairs, "ls_type", "Router"); break; case LST_NET: addVP(&pairs, "ls_type", "Network"); break; case LST_SUMM: addVP(&pairs, "ls_type", "Summary"); break; case LST_ASBR: addVP(&pairs, "ls_type", "ASBR-Summary"); break; case LST_ASL: addVP(&pairs, "ls_type", "ASE"); break; case LST_GM: addVP(&pairs, "ls_type", "Group member"); break; case LST_LINK_OPQ: addVP(&pairs, "ls_type", "Link Opaque"); break; case LST_AREA_OPQ: addVP(&pairs, "ls_type", "Area Opaque"); break; case LST_AS_OPQ: addVP(&pairs, "ls_type", "AS Opaque"); break; } in = *((in_addr *) &lshdr->ls_id); addVP(&pairs, "ls_id", inet_ntoa(in)); in = *((in_addr *) &lshdr->ls_org); addVP(&pairs, "adv_rtr", inet_ntoa(in));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -