⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sim.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   OSPFD routing simulation controller *   Copyright (C) 1999 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 <sys/resource.h>#include <sys/param.h>#include <unistd.h>#include <tcl.h>#include <tk.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.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 "machtype.h"#include "sim.h"#include "simctl.h"#include <time.h>#include "mtrace.h"/* Forward references */bool get_prefix(char *prefix, InAddr &net, InMask &mask);// Tk/Tcl callbacksvoid tick(ClientData);int StartRouter(ClientData, Tcl_Interp *, int, char *argv[]);int ToggleRouter(ClientData, Tcl_Interp *, int, char *argv[]);int RestartRouter(ClientData, Tcl_Interp *, int, char *argv[]);int HitlessRestart(ClientData, Tcl_Interp *, int, char *argv[]);int StartPing(ClientData, Tcl_Interp *, int, char *argv[]);int StopPing(ClientData, Tcl_Interp *, int, char *argv[]);int StartTraceroute(ClientData, Tcl_Interp *, int, char *argv[]);int StartMtrace(ClientData, Tcl_Interp *, int, char *argv[]);int PrefixMatch(ClientData, Tcl_Interp *, int, char *argv[]);int AddMapping(ClientData, Tcl_Interp *, int, char *argv[]);int AddNetMember(ClientData, Tcl_Interp *interp, int, char *argv[]);int TimeStop(ClientData, Tcl_Interp *, int, char *argv[]);int TimeResume(ClientData, Tcl_Interp *, int, char *argv[]);int SendGeneral(ClientData, Tcl_Interp *, int, char *argv[]);int SendArea(ClientData, Tcl_Interp *, int, char *argv[]);int SendInterface(ClientData, Tcl_Interp *, int, char *argv[]);int SendVL(ClientData, Tcl_Interp *, int, char *argv[]);int SendNeighbor(ClientData, Tcl_Interp *, int, char *argv[]);int SendAggregate(ClientData, Tcl_Interp *, int, char *argv[]);int SendHost(ClientData, Tcl_Interp *, int, char *argv[]);int SendExtRt(ClientData, Tcl_Interp *, int, char *argv[]);int SendGroup(ClientData, Tcl_Interp *, int, char *argv[]);int LeaveGroup(ClientData, Tcl_Interp *, int, char *argv[]);// Global variableschar *sim_tcl_src = "/ospf_sim.tcl";char *cfgfile = 0;SimCtl *sim;/* Process messages received from simulated nodes. */bool SimCtl::process_replies(){    int n_fd;    fd_set fdset;    int err;    SimNode *node;    timeval timeout;    bool active = false;    FD_ZERO(&fdset);    // Add listen socket    n_fd = server_fd;    FD_SET(server_fd, &fdset);    // Add one connection per simulated router    for (int i = 0; i <= maxfd; i++) {        if (!(node = nodes[i]))	    continue;	n_fd = MAX(n_fd, node->fd);	FD_SET(node->fd, &fdset);    }    // Poll for I/O    timeout.tv_sec = 0;    timeout.tv_usec = 0;    err = select(n_fd+1, &fdset, 0, 0, &timeout);    // Handle errors in select    if (err == -1 && errno != EINTR) {	perror("select failed");	exit(1);    }    // Handle new connections    if (FD_ISSET(server_fd, &fdset)) {        active = true;	incoming_call();    }    // Handle replies from simulated routers    for (int i = 0; i <= maxfd; i++) {        if (!(node = nodes[i]))	    continue;	if (FD_ISSET(node->fd, &fdset)) {	    active = true;	    simnode_handler_read(node->fd);	}    }    return(active);}/* Send data to simulated nodes. */bool SimCtl::send_data(){    int n_fd;    fd_set wrset;    int err;    SimNode *node;    timeval timeout;    bool active=false;    FD_ZERO(&wrset);    n_fd = -1;    // Add one connection per simulated router    // If we have data pending to that node    for (int i = 0; i <= maxfd; i++) {        if (!(node = nodes[i]))	    continue;	if (node->pktdata.xmt_pending()) {	    n_fd = MAX(n_fd, node->fd);	    FD_SET(node->fd, &wrset);	}    }    // No data to send?    if (n_fd == -1)        return(active);    // Poll for I/O    timeout.tv_sec = 0;    timeout.tv_usec = 0;    err = select(n_fd+1, 0, &wrset, 0, &timeout);    // Handle errors in select    if (err == -1 && errno != EINTR) {	perror("select failed");	exit(1);    }    // Write pending data if there is space    for (int i = 0; i <= maxfd; i++) {        if (!(node = nodes[i]))	    continue;	if ((node == nodes[i]) && FD_ISSET(node->fd, &wrset)) {	    active = true;	    if (!node->pktdata.sendpkt())	        delete_router(node);	}    }    return(active);}/* Controlling process for the OSPF simulator. * After initialization, simply send timer ticks * to each simulated OSPF router and wait for their * replies. Their replies indicate whether they have * synchronized databases. Also can receiving logging * messages from the simulated routers, which are * written to a file. */int main(int argc, char *argv[]){    Tcl_Interp *interp; // Interpretation of config commands    if (argc > 2) {	printf("Syntax: ospf_sim [config_filename]\n");	exit(1);    }    if (argc == 2)	cfgfile = argv[1];    interp = Tcl_CreateInterp();    Tcl_AppInit(interp);    // Main loop, never exits    Tk_MainLoop();    exit(0);}/* Initialize the simulation. * First read the TCL commands, and register * those that are written in C++. Then read the configuration * file (if any), and start separate processes for each * simulated router. When the router connects * to the controller, send it its complete configuration. */int Tcl_AppInit(Tcl_Interp *interp){//  rlimit rlim;    int fd;    struct sockaddr_in addr;    socklen size;    int namlen;    char *filename;    // Allow core files//  rlim.rlim_max = RLIM_INFINITY;//  (void) setrlimit(RLIMIT_CORE, &rlim);    // Create simulation controller    sim = new SimCtl(interp);    // Complete interpreter initialization    if (Tcl_Init(interp) != TCL_OK) {        printf("Error in Tcl_Init(): %s\n", interp->result);	exit(1);    }    if (Tk_Init(interp) != TCL_OK) {        printf("Error in Tk_Init(): %s\n", interp->result);	exit(1);    }    // Install C-language TCl commands    Tcl_CreateCommand(interp, "startrtr", StartRouter, 0, 0);    Tcl_CreateCommand(interp, "togglertr", ToggleRouter, 0, 0);    Tcl_CreateCommand(interp, "rstrtr", RestartRouter, 0, 0);    Tcl_CreateCommand(interp, "hitlessrtr", HitlessRestart, 0, 0);    Tcl_CreateCommand(interp, "start_ping", StartPing, 0, 0);    Tcl_CreateCommand(interp, "stop_ping", StopPing, 0, 0);    Tcl_CreateCommand(interp, "start_traceroute", StartTraceroute, 0, 0);    Tcl_CreateCommand(interp, "start_mtrace", StartMtrace, 0, 0);    Tcl_CreateCommand(interp, "prefix_match", PrefixMatch, 0, 0);    Tcl_CreateCommand(interp, "add_mapping", AddMapping, 0, 0);    Tcl_CreateCommand(interp, "add_net_membership", AddNetMember, 0, 0);    Tcl_CreateCommand(interp, "time_stop", TimeStop, 0, 0);    Tcl_CreateCommand(interp, "time_resume", TimeResume, 0, 0);    Tcl_CreateCommand(interp, "sendgen", SendGeneral, 0, 0);    Tcl_CreateCommand(interp, "sendarea", SendArea, 0, 0);    Tcl_CreateCommand(interp, "sendifc", SendInterface, 0, 0);    Tcl_CreateCommand(interp, "sendvl", SendVL, 0, 0);    Tcl_CreateCommand(interp, "sendnbr", SendNeighbor, 0, 0);    Tcl_CreateCommand(interp, "sendagg", SendAggregate, 0, 0);    Tcl_CreateCommand(interp, "sendhost", SendHost, 0, 0);    Tcl_CreateCommand(interp, "sendextrt", SendExtRt, 0, 0);    Tcl_CreateCommand(interp, "sendgrp", SendGroup, 0, 0);    Tcl_CreateCommand(interp, "leavegrp", LeaveGroup, 0, 0);    // Read additional TCL commands    namlen = strlen(INSTALL_DIR) + strlen(sim_tcl_src);    filename = new char[namlen+1];    strcpy(filename, INSTALL_DIR);    strcat(filename, sim_tcl_src);    if (Tcl_EvalFile(interp, filename) != TCL_OK) {	printf("Error in %s, line %d\r\n", filename, interp->errorLine);	exit(1);    }    delete [] filename;    // Create server socket    fd = socket(AF_INET, SOCK_STREAM, 0);    sim->server_fd = fd;    memset(&addr, 0, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(INADDR_ANY);    if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {	perror("bind");	exit (1);    }    size = sizeof(addr);    if (getsockname(fd, (struct sockaddr *) &addr, &size) < 0) {	perror("getsockname");	exit (1);    }    sim->assigned_port = ntohs(addr.sin_port);    // Read config file    if (cfgfile) {	if (Tcl_EvalFile(interp, cfgfile) != TCL_OK) {	    printf("Error in %s, line %d", cfgfile, interp->errorLine);	    exit(1);	}	// Tell TCL the config file name	if (Tcl_VarEval(sim->interp, "ConfigFile ", cfgfile, 0) != TCL_OK)            printf("ConfigFile: %s\n", sim->interp->result);    }    // Use the sample.cfg configuration    else {        extern char *sample_cfg;	int size;	char *cmd;	size = strlen(sample_cfg);	cmd = new char[size+1];	strcpy(cmd, sample_cfg);	if (Tcl_Eval(sim->interp, cmd) != TCL_OK) {            printf("sample.cfg: %s\n", sim->interp->result);	    exit(1);	}    }    // Now we're up and running    sim->running = true;    // Listen for simulated nodes that are initializing    listen(fd, 150);    // Start timer ticks    Tk_CreateTimerHandler(1000/TICKS_PER_SECOND, tick, 0);    return(TCL_OK);}/* Accept an incoming connection from a simulated router. * We don't add a simulated node yet, because we have to get * the first message to find out the router ID of the other * end. */void SimCtl::incoming_call(){    int fd;    struct sockaddr_in addr;    socklen len;    SimNode *temp;    len = sizeof(addr);    if (!(fd = accept(server_fd, (struct sockaddr *) &addr, &len))) {	perror("incoming_call:accept");	return;    }    // Allocate placeholder SimNode    temp = new SimNode(0, fd);}/* Tick processing. If all nodes have responded, increase * the current time and send out a new round of ticks. */void tick(ClientData){    bool all_responded=true;    AVLsearch *iter;    SimNode *node;    int max_sync = 0;    NodeStats *max_dbstats=0;    // Process all I/O from simulated nodes    while (sim->process_replies())        ;    // Check to see that all have responded    iter = new AVLsearch(&sim->simnodes);    while ((node = (SimNode *)iter->next())) {        if (!node->got_tick) {	    all_responded = false;	    break;	}    }    delete iter;    // Recolor map according to latest database    // statistics received    iter = new AVLsearch(&sim->simnodes);    while ((node = (SimNode *)iter->next())) {        if (node->dbstats && node->dbstats->refct >= max_sync) {	    max_sync = node->dbstats->refct;	    max_dbstats = node->dbstats;	}    }    delete iter;    iter = new AVLsearch(&sim->simnodes);    while ((node = (SimNode *)iter->next())) {        in_addr addr;	int old_color=node->color;	char *color;        if (!node->dbstats || node->dbstats->refct == 1)	    node->color = SimNode::WHITE;	else if (node->dbstats == max_dbstats)	    node->color = SimNode::GREEN;	else	    node->color = SimNode::ORANGE;	if (old_color == node->color)	    continue;	switch (node->color) {	  default:	  case SimNode::WHITE:	    color = " white";	    break;	  case SimNode::GREEN:	    color = " green";	    break;	  case SimNode::ORANGE:	    color = " orange";	    break;	}	addr.s_addr = hton32(node->id());	if (Tcl_VarEval(sim->interp, "color_router ", inet_ntoa(addr),			color, 0) != TCL_OK)	    printf("color_router: %s\n", sim->interp->result);    }    delete iter;    // If all responded, and we're not frozen    // Send out new timer ticks    if (all_responded && !sim->frozen) {        char display_buffer[20];        sim->n_ticks++;	sprintf(display_buffer, "%d", sim->n_ticks);	// Update displayed time	if (Tcl_VarEval(sim->interp, "show_time ",display_buffer, 0) != TCL_OK)	    printf("show_time: %s\n", sim->interp->result);	iter = new AVLsearch(&sim->simnodes);	while ((node = (SimNode *)iter->next())) {	    TickBody tm;	    node->got_tick = false;	    tm.tick = sim->n_ticks;	    node->pktdata.queue_xpkt(&tm, SIM_TICK, 0, sizeof(tm));	}	delete iter;    }    // Send all pending data to simulated routers    while (sim->send_data())        ;    // Regardless, schedule next tick() invocation    Tk_CreateTimerHandler(1000/TICKS_PER_SECOND, tick, 0);}/* I/0 activity on the connection to a simulated router. * Process any reads, and send pending data if there is * room. */void SimCtl::simnode_handler_read(int fd){    SimNode *node;    void *msg;    uns16 type;    uns16 subtype;    int nbytes;    if (!(node = sim->nodes[fd]))        return;    nbytes = node->pktdata.receive(&msg, type, subtype);    if (nbytes < 0) {	sim->delete_router(node);	return;    }    if (type != 0) {	SimHello *hello;	DBStats *dbstats;	in_addr addr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -