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

📄 ospfd_xorp.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   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 <sys/types.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <net/if.h>#include "ospf_module.h"#include "config.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxipc/xrl_std_router.hh"#include "ospfinc.h"#include "monitor.h"#include "system.h"#include "tcppkt.h"#include "os-instance.h"#include "ospf_config.h"#include "ospfd_xorp.h"#include "xrl_target.h"/* Initialize the FreeBSD interface. * Open the network interface. * Start the random number generator. */XorpOspfd::XorpOspfd(EventLoop& e, XrlRouter& r)     : OSInstance(e, OSPFD_MON_PORT), _router(r), _rib_client(&r){    const char *ospfd_log_file = "/tmp/ospfd.log";    debug_msg("----\nXorpOspfd\n");    rlimit rlim;    next_phyint = 0;    memset(phys, 0, sizeof(phys));    (void) gettimeofday(&last_time, NULL);    _changing_routerid = false;    _change_complete = false;    _dumping_remnants = false;    // Allow core files    rlim.rlim_max = RLIM_INFINITY;    (void) setrlimit(RLIMIT_CORE, &rlim);    // Open log file    if ((_logstr = fopen(ospfd_log_file, "w"))==NULL) {	XLOG_FATAL("Logfile open failed: %s", strerror(errno));    }    // Open monitoring listen socket    monitor_listen();    // Open network    if ((_netfd = socket(AF_INET, SOCK_RAW, PROT_OSPF)) == -1) {	XLOG_FATAL("Network open failed: %s", strerror(errno));    }    // We will supply headers on output    int hincl = 1;    setsockopt(_netfd, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl));    // Call receive raw when _netfd has data to be read    if (_eventloop.add_selector(_netfd, SEL_RD, 		       callback(this, &XorpOspfd::raw_receive)) == false) {	XLOG_FATAL("Failed to add net fd.");    }    // Open ioctl socket    if ((_udpfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {	XLOG_FATAL("Failed to open UDP socket: %s", strerror(errno));    }    // Start random number generator    srand(getpid());    // Will open multicast fd if requested to later    _igmpfd = -1;    // Set up one second timer    _one_sec_ticker = _eventloop.new_periodic(1000,					       callback(this, &XorpOspfd::one_second_tick));}char buffer[MAX_IP_PKTSIZE];// External declarationsbool get_prefix(const char *prefix, InAddr &net, InMask &mask);void quit(int){    XorpOspfd* ospfd_sys = static_cast<XorpOspfd*>(sys);    ospfd_sys->_changing_routerid = false;    ospf->shutdown(10);}/* Process packets received on a raw socket. Could * be either the OSPF socket or the IGMP socket. */void XorpOspfd::raw_receive(int fd, SelectorMask m){    assert(SEL_RD == m);    debug_msg("----\nraw_receive\n");    int plen;    int rcvint = -1;#if 1    unsigned int fromlen;    plen = recvfrom(fd, buffer, sizeof(buffer), 0, 0, &fromlen);    if (plen < 0) {        XLOG_ERROR("recvfrom: %s", strerror(errno));	return;    }#else    msghdr msg;    iovec iov;    byte cmsgbuf[128];    msg.msg_name = 0;    msg.msg_namelen = 0;    iov.iov_len = sizeof(buffer);    iov.iov_base = buffer;    msg.msg_iov = &iov;    msg.msg_iovlen = 1;    msg.msg_control = cmsgbuf;    msg.msg_controllen = sizeof(cmsgbuf);    plen = recvmsg(fd, &msg, 0);    if (plen < 0) {        XLOG_ERROR("recvmsg: %s", strerror(errno));	return;    }    else {	cmsghdr *cmsg;	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;	     cmsg = CMSG_NXTHDR(&msg, cmsg)) {	    if (cmsg->cmsg_level == SOL_IP &&		cmsg->cmsg_type == IP_PKTINFO) {	        in_pktinfo *pktinfo;		pktinfo = (in_pktinfo *) CMSG_DATA(cmsg);		rcvint = pktinfo->ipi_ifindex;		break;	    }	}    }#endif    struct ip *iph = (struct ip *)buffer;    InPkt *pkt = (InPkt *) buffer;    //FreeBSD gives us the packet with the IP length in host    //byte order, but ospfd expects it in network byte order.  Fix it    //here so we don't need to change the rest of ospfd.    //    //Even worse, FreeBSD modifies the IP header length to remove the IP    //length to remove the IP header - add it back on.    pkt->i_len = ntoh16(pkt->i_len + (iph->ip_hl*4));    //    assert(pkt->i_len <= sizeof(buffer)); // always true    // Dispatch based on IP protocol    switch (pkt->i_prot) {      case PROT_OSPF:	  debug_msg("it's OSPF\n");        ospf->rxpkt(rcvint, pkt, plen);	break;      case PROT_IGMP:	  debug_msg("it's IGMP\n");        ospf->rxigmp(rcvint, pkt, plen);	break;      case 0:	ospf->mclookup(pkt->i_src, pkt->i_dest);	break;      default:	break;    }}/* Update the program's notion of time, which is in milliseconds * since program start. Wait until receiving the timer signal * to update a full second. */void XorpOspfd::time_update(){    debug_msg("----\ntime_update\n");    timeval now;	// Current idea of time    int timediff;    (void) gettimeofday(&now, NULL);    timediff = 1000*(now.tv_sec - last_time.tv_sec);    timediff += (now.tv_usec - last_time.tv_usec)/1000;    if ((timediff + sys_etime.msec) < 1000)	sys_etime.msec += timediff;    last_time = now;}/* Signal handler for the one second timer. * Up the elapsed time to the next whole second. */bool XorpOspfd::one_second_tick(){    //    debug_msg("----\none_second_timer\n");    timeval now;	// Current idea of time    (void) gettimeofday(&now, NULL);    sys_etime.sec++;     sys_etime.msec = 0;    last_time = now;    return true;}/* Destructor not expected to be called during the life * of the program. */XorpOspfd::~XorpOspfd(){}/* Find the physical interface to which a given address * belongs. Returns -1 if no matching interface * can be found. */int XorpOspfd::get_phyint(InAddr addr){    debug_msg("----\nget_phyint\n");    int i;    for (i=0; i < MAXIFs; i++) {	BSDPhyInt *phyp;	phyp = phys[i];	if (phyp && (phyp->addr & phyp->mask) == (addr & phyp->mask))	    return(i);    }    return(-1);}/* Read the IP interface information out of the FreeBSD * kernel. */void XorpOspfd::read_kernel_interfaces(){    debug_msg("----\nread_kernel_interfaces\n");    ifconf cfgreq;    ifreq *ifrp;    ifreq *end;    size_t size;    char *ifcbuf;    int blen;    AVLsearch iter(&directs);    DirectRoute *rte;    blen = MAXIFs*sizeof(ifreq);    ifcbuf = new char[blen];    cfgreq.ifc_buf = ifcbuf;    cfgreq.ifc_len = blen;    if (ioctl(_udpfd, SIOCGIFCONF, (char *)&cfgreq) < 0) {	XLOG_ERROR("Failed to read interface config: %s", strerror(errno));	exit(1);    }    /* Clear current list of interfaces and directly     * attached subnets, since we're going to reread     * them.     */    interface_map.clear();    while ((rte = (DirectRoute *)iter.next()))        rte->valid = false;    ifrp = (ifreq *) ifcbuf;    end = (ifreq *)(ifcbuf + cfgreq.ifc_len);    for (; ifrp < end; ifrp = (ifreq *)(((byte *)ifrp) + size)) {	BSDPhyInt *phyp;	byte *phystr;	ifreq ifr;	sockaddr_in *insock;	InAddr addr;	// Find next interface structure in list	size=_SIZEOF_ADDR_IFREQ(*ifrp) ;		// IP interfaces only	if (ifrp->ifr_addr.sa_family != AF_INET) 	    continue;	debug_msg("IFname: %s\n", ifrp->ifr_name);	// Ignore loopback interfaces	// Also ignore "down" interfaces	// Get interface flags	short ifflags;	memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));	if (ioctl(_udpfd, SIOCGIFFLAGS, (char *)&ifr) < 0) {	    XLOG_ERROR("SIOCGIFFLAGS Failed: %s", strerror(errno));	    exit(1);	}	if ((ifr.ifr_flags & IFF_LOOPBACK) != 0)	    continue;	ifflags = ifr.ifr_flags;	debug_msg("Flags=%x\n", ifflags);	/* Found a legitimate interface	 * Add physical interface and	 * IP address maps	 */

⌨️ 快捷键说明

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