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

📄 os-instance.c

📁 BCAST Implementation for NS2
💻 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. *//* Routines covering both the Xorp ospfd routing daemon * and the OSPF routing simulator. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include "ospf_module.h"#include "ospfinc.h"#include "monitor.h"#include "system.h"#include "tcppkt.h"#include "os-instance.h"/* Allocate a new monitoring connection. */TcpConn::TcpConn(int fd) : AVLitem(fd, 0), monpkt(fd){}/* Process a monitor response from the OSPF application. * Simple note its location and length. Response will be sent * out in the main loop as long as we're not blocking. */void OSInstance::monitor_response(struct MonMsg *msg, uns16 code, int len, int fd){    TcpConn *conn;    if ((conn = (TcpConn *)monfds.find(fd, 0)))	conn->monpkt.queue_xpkt(msg, code, 0, len);}/* Constructor for the common XORP OspfSysCalls * class. */OSInstance::OSInstance(EventLoop& e, uns16 mon_port) : OspfSysCalls(), _eventloop(e){    ospfd_mon_port = mon_port;    listenfd = -1;}/* Set up to detect monitor read/write availability * in select(). */#if (0)void OSInstance::mon_fd_set(int &n_fd, fd_set *fdsetp, fd_set *wrsetp){    AVLsearch iter(&monfds);    TcpConn *conn;    while ((conn = (TcpConn *)iter.next())) {	n_fd = MAX(n_fd, conn->monfd());	FD_SET(conn->monfd(), fdsetp);	if (conn->monpkt.xmt_pending())	    FD_SET(conn->monfd(), wrsetp);    }    if (listenfd != -1) {	FD_SET(listenfd, fdsetp);	n_fd = MAX(n_fd, listenfd);    }}#endif/* Cloase all monitor connections. Necessary when, for example, * simulated ospfd restarts but its process remains. */void OSInstance::close_monitor_connections(){    AVLsearch iter(&monfds);    TcpConn *conn;    while ((conn = (TcpConn *)iter.next()))        close_monitor_connection(conn);}#if (0)void OSInstance::process_mon_io(fd_set *fdsetp, fd_set *wrsetp){    AVLsearch iter(&monfds);    TcpConn *conn;    while ((conn = (TcpConn *)iter.next())) {        int fd = conn->monfd();	if (FD_ISSET(fd, fdsetp))	    process_monitor_request(conn);	if (FD_ISSET(fd, wrsetp) && !conn->monpkt.sendpkt()) {	    /* XXX Should remove connection or just remove write selector ? */	    close_monitor_connection(conn); 	}    }    // Monitor connect request    if (listenfd != -1 && FD_ISSET(listenfd, fdsetp))	accept_monitor_connection();}#endif /* Receive a monitor request packet, calling the OSPF * application if the full request has been received. */void OSInstance::process_monitor_request(TcpConn *conn){        MonHdr *msg;    uns16 type;    uns16 subtype;    int nbytes;    int fd;        fd = conn->monfd();    if ((nbytes = conn->monpkt.receive((void **)&msg, type, subtype)) < 0) {	close_monitor_connection(conn);    } else if (type != 0 && ospf) {	ospf->monitor((MonMsg *)msg, type, nbytes, fd);    }}/* Accept a monitor connection. Only do this if there * is no current monitor connection. */void OSInstance::accept_monitor_connection(){    sockaddr_in addr;    socklen len;    int fd;    len = sizeof(addr);    if ((fd = accept(listenfd, (sockaddr *) &addr, &len)) < 0)	XLOG_ERROR("recvfrom: %s", strerror(errno));    else {        TcpConn *conn;	conn = new TcpConn(fd);	monfds.add(conn);	if (!_eventloop.add_selector(fd, SEL_ALL,				      callback(this, 					       &OSInstance::tcp_data_cb,					       conn))) {	    XLOG_WARNING("Failed to add selector.");	}    }}/* Close the current monitor connection. Immediately start * a listen for another. */void OSInstance::close_monitor_connection(TcpConn *conn){    close(conn->monfd());    _eventloop.remove_selector(conn->monfd());    monfds.remove(conn);    if (ospf)        ospf->register_for_opqs(conn->monfd(), true);    delete conn;}/* Listen for monitor connections */void OSInstance::monitor_listen(){    sockaddr_in monaddr;    socklen size;    char temp[40];    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {	XLOG_ERROR("Monitor socket failed: %s", strerror(errno));	exit(1);    }    memset(&monaddr, 0, sizeof(monaddr));    monaddr.sin_family = AF_INET;    monaddr.sin_addr.s_addr = hton32(INADDR_ANY);    monaddr.sin_port = hton16(ospfd_mon_port);    if (bind(listenfd,  (struct sockaddr *) &monaddr, sizeof(monaddr)) <  0) {	XLOG_FATAL("Monitor bind failed: %s", strerror(errno));    }    size = sizeof(monaddr);    if (getsockname(listenfd, (struct sockaddr *) &monaddr, &size) < 0) {	XLOG_FATAL("getsockname: %s", strerror(errno));    }    ospfd_mon_port = ntohs(monaddr.sin_port);    sprintf(temp, "PID %d ospfd_mon port %d", getpid(), ospfd_mon_port);    sys_spflog(ERR_SYS, temp);    if (listen(listenfd, 2) < 0) {	XLOG_FATAL("Monitor listen failed: %s", strerror(errno));    }    if (_eventloop.add_selector(listenfd, SEL_RD, 				 callback(this, &OSInstance::accept_cb)				 ) == false) {	XLOG_FATAL("Monitor could not add selector.");    }}void OSInstance::accept_cb(int fd, SelectorMask m){    assert(m == SEL_RD);    assert(get_listenfd() == fd);    accept_monitor_connection();}void OSInstance::tcp_data_cb(int fd, SelectorMask m, TcpConn* conn){    assert(fd == conn->monfd());    if (m & SEL_RD)	process_monitor_request(conn);    if ((m & SEL_WR) && !conn->monpkt.sendpkt())	close_monitor_connection(conn);}/* Utility to parse prefixes. Returns false if the * prefix is malformed. */InMask masks[33] = {    0x00000000L, 0x80000000L, 0xc0000000L, 0xe0000000L,    0xf0000000L, 0xf8000000L, 0xfc000000L, 0xfe000000L,    0xff000000L, 0xff800000L, 0xffc00000L, 0xffe00000L,    0xfff00000L, 0xfff80000L, 0xfffc0000L, 0xfffe0000L,    0xffff0000L, 0xffff8000L, 0xffffc000L, 0xffffe000L,    0xfffff000L, 0xfffff800L, 0xfffffc00L, 0xfffffe00L,    0xffffff00L, 0xffffff80L, 0xffffffc0L, 0xffffffe0L,    0xfffffff0L, 0x80000000L, 0xfffffffcL, 0xfffffffeL,    0xffffffffL};bool get_prefix(const char *prefix, InAddr &net, InMask &mask){    char *string;    char netstr[16];    int len;    if (!(string = index(prefix, '/')))	return(false);    memcpy(netstr, prefix, string-prefix);    netstr[string-prefix] = '\0';    net = ntoh32(inet_addr(netstr));    len = atoi(string+1);    if (len < 0 || len > 32)	return(false);    mask = masks[len];    return(true);}

⌨️ 快捷键说明

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