ospfd_linux.c

来自「BCAST Implementation for NS2」· C语言 代码 · 共 1,100 行 · 第 1/2 页

C
1,100
字号
    delete [] filename;    // (Re)read kernel interfaces    read_kernel_interfaces();    // (Re)read config file    if (Tcl_EvalFile(interp, ospfd_config_file) != TCL_OK) {	syslog(LOG_ERR, "Error in config file, line %d", interp->errorLine);	return;    }    // Verify router ID was given    if (!ospf ||  new_router_id == 0) {	syslog(LOG_ERR, "Failed to set Router ID");	return;    }    // Request to change OSPF Router ID?    if (ospf->my_id() != new_router_id) {        changing_routerid = true;	ospf->shutdown(10);	return;    }    // Reset current config    ospf->cfgStart();    // Download new config    Tcl_Eval(interp, sendcfg);    Tcl_DeleteInterp(interp);    // Signal configuration complete    ospf->cfgDone();}/* Complete the changing of the OSPF Router ID. */void LinuxOspfd::process_routerid_change(){    if (changing_routerid && change_complete) {        changing_routerid = false;	change_complete = false;	delete ospf;	ospf = 0;	read_config();	if (!ospf) {	    syslog(LOG_ERR, "Router ID change failed");	    exit(1);	}    }}/* Find the physical interface to which a given address * belongs. Returns -1 if no matching interface * can be found. */int LinuxOspfd::get_phyint(InAddr addr){    AVLsearch iter(&phyints);	BSDPhyInt *phyp;    while ((phyp = (BSDPhyInt *)iter.next())) {	if ((phyp->addr & phyp->mask) == (addr & phyp->mask))	    return(phyp->phyint());    }    return(-1);}/* Read the IP interface information out of the Linux * kernel. */void LinuxOspfd::read_kernel_interfaces(){    ifconf cfgreq;    ifreq *ifrp;    ifreq *end;    size_t size;    char *ifcbuf;    int blen;    AVLsearch iter(&directs);    DirectRoute *rte;    AVLsearch iter2(&phyints);    BSDPhyInt *phyp;    blen = MAXIFs*sizeof(ifreq);    ifcbuf = new char[blen];    cfgreq.ifc_buf = ifcbuf;    cfgreq.ifc_len = blen;    if (ioctl(udpfd, SIOCGIFCONF, (char *)&cfgreq) < 0) {	syslog(LOG_ERR, "Failed to read interface config: %m");	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;    while((phyp = (BSDPhyInt *)iter2.next())) {        phyp->addr = 0;	phyp->mask = 0;    }    ifrp = (ifreq *) ifcbuf;    end = (ifreq *)(ifcbuf + cfgreq.ifc_len);    for (; ifrp < end; ifrp = (ifreq *)(((byte *)ifrp) + size)) {	ifreq ifr;	sockaddr_in *insock;	InAddr addr;	// Find next interface structure in list	size = sizeof(InAddr) + sizeof(ifrp->ifr_name);	if (size < sizeof(ifreq))	    size = sizeof(ifreq);	if (ifrp->ifr_addr.sa_family != AF_INET)	    continue;	// Get interface flags	short ifflags;	memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));	if (ioctl(udpfd, SIOCGIFFLAGS, (char *)&ifr) < 0) {	    syslog(LOG_ERR, "SIOCGIFFLAGS Failed: %m");	    exit(1);	}	// Ignore master tunnel interface	if (strncmp(ifrp->ifr_name, "tunl0", 5) == 0)	    continue;	ifflags = ifr.ifr_flags;#if LINUX_VERSION_CODE >= LINUX22	int ifindex;	// Get interface index	memcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));	if (ioctl(udpfd, SIOCGIFINDEX, (char *)&ifr) < 0) {	    syslog(LOG_ERR, "SIOCGIFINDEX Failed: %m");	    exit(1);	}	ifindex = ifr.ifr_ifindex;#else	ifindex = ++next_phyint;#endif	/* Found a legitimate interface	 * Add physical interface and	 * IP address maps	 */	if (!(phyp = (BSDPhyInt *) phyints.find(ifindex, 0))) {	    phyp = new BSDPhyInt(ifindex);	    phyp->phyname = new char[strlen(ifrp->ifr_name)];	    strcpy(phyp->phyname, ifrp->ifr_name);	    phyp->flags = 0;	    phyints.add(phyp);	    ioctl(udpfd, SIOCGIFHWADDR, &ifr);	    if (ifr.ifr_hwaddr.sa_family == ARPHRD_TUNNEL) {	        ip_tunnel_parm tp;		phyp->tunl = true;		ifr.ifr_ifru.ifru_data = (char *)&tp;	        ioctl(udpfd, SIOCGETTUNNEL, &ifr);		phyp->tsrc = ntoh32(tp.iph.saddr);		phyp->tdst = ntoh32(tp.iph.daddr);			    }	}	if (!memchr(ifrp->ifr_name, ':', sizeof(ifrp->ifr_name)))	    set_flags(phyp, ifflags);	// Get interface MTU	phyp->mtu = ((phyp->flags & IFF_BROADCAST) != 0) ? 1500 : 576;	if (ioctl(udpfd, SIOCGIFMTU, (char *)&ifr) >= 0)	    phyp->mtu = ifr.ifr_mtu;	// store address information; real IP interfaces only	// Allow loopback interfaces; just not 127.x.x.x addresses	insock = (sockaddr_in *) &ifrp->ifr_addr;	if ((ntoh32(insock->sin_addr.s_addr) & 0xff000000) == 0x7f000000)	    continue;	addr = ntoh32(insock->sin_addr.s_addr);	// Get subnet mask	if (ioctl(udpfd, SIOCGIFNETMASK, (char *)&ifr) < 0) {	    syslog(LOG_ERR, "SIOCGIFNETMASK Failed: %m");	    exit(1);	}	insock = (sockaddr_in *) &ifr.ifr_addr;	if (phyp->tunl && ntoh32(insock->sin_addr.s_addr) == 0xffffffff)	    continue;	phyp->addr = addr;	phyp->mask = ntoh32(insock->sin_addr.s_addr);	add_direct(phyp, addr, phyp->mask);	add_direct(phyp, addr, 0xffffffffL);	// For point-to-point links, get other end's address	phyp->dstaddr = 0;	if ((phyp->flags & IFF_POINTOPOINT) != 0 &&	    (ioctl(udpfd, SIOCGIFDSTADDR, (char *)&ifr) >= 0)) {	    addr = phyp->dstaddr = ntoh32(insock->sin_addr.s_addr);	    add_direct(phyp, addr, 0xffffffffL);	}	// Install map from IP address to physical interface	if (!interface_map.find(addr, 0)) {	    BSDIfMap *map;	    map = new BSDIfMap(addr, phyp);	    interface_map.add(map);	}    }    /* Put back any routes that were obscured by formerly     * operational direct routes. Take away routes that are     * now supplanted by direct routes.     */    iter.seek(0, 0);    while ((rte = (DirectRoute *)iter.next())) {        InAddr net=rte->index1();	InMask mask=rte->index2();        if (!rte->valid) {	    directs.remove(rte);	    delete rte;	    ospf->krt_delete_notification(net, mask);	}	    #if LINUX_VERSION_CODE >= LINUX22	else	    sys->rtdel(net, mask, 0);#endif    }    delete [] ifcbuf;}/* Set the interface flags, If the IFF_UP flag * has changed, call the appropriate OSPFD API * routine. */void LinuxOspfd::set_flags(BSDPhyInt *phyp, short flags){    short old_flags=phyp->flags;    phyp->flags = flags;    if (((old_flags^flags) & IFF_UP) != 0 && ospf) {        if ((flags & IFF_UP) != 0)	    ospf->phy_up(phyp->phyint());	else	    ospf->phy_down(phyp->phyint());    }}/* Add to the list of directly attached prefixes. These * we will let the kernel manage directly. */void LinuxOspfd::add_direct(BSDPhyInt *phyp, InAddr addr, InMask mask){    DirectRoute *rte;    if ((phyp->flags & IFF_UP) == 0)        return;    addr = addr & mask;    if (!(rte = (DirectRoute *)directs.find(addr, mask))) {	rte = new DirectRoute(addr, mask);	directs.add(rte);    }    rte->valid = true;}/* Parse an interface identifier, which can either be an address * or a name like "eth0". */bool LinuxOspfd::parse_interface(char *arg, in_addr &addr, BSDPhyInt *&phyp){    phyp = 0;    if (inet_aton(arg, &addr) == 1) {	BSDIfMap *map;	InAddr ifaddr;	ifaddr = ntoh32(addr.s_addr);	map = (BSDIfMap *) interface_map.find(ifaddr, 0);	if (map != 0)	    phyp = map->phyp;    }    else {        AVLsearch iter(&phyints);	while ((phyp = (BSDPhyInt *)iter.next())) {	    if (strcmp(arg, phyp->phyname))	        continue;	    // Found interface by name	    addr.s_addr = hton32(phyp->addr);	    break;	}    }    if (!phyp) {	syslog(LOG_ERR, "Bad interface identifier %s", arg);	return(false);    }    return(true);}/* Set the Router ID of the OSPF Process. * Refuse to reset the OSPF Router ID if it has already * been set. */int SetRouterID(ClientData, Tcl_Interp *, int, char *argv[]){    new_router_id = ntoh32(inet_addr(argv[1]));    if (!ospf)	ospf = new OSPF(new_router_id, sys_etime);    return(TCL_OK);}/* Download the global configuration values into the ospfd * software. If try to change Router ID, refuse reconfig. * If first time, create OSPF protocol instance. */int SendGeneral(ClientData, Tcl_Interp *, int, char *argv[]){    CfgGen m;    m.lsdb_limit = atoi(argv[1]);    m.mospf_enabled = atoi(argv[2]);    m.inter_area_mc = atoi(argv[3]);    m.ovfl_int = atoi(argv[4]);    m.new_flood_rate = atoi(argv[5]);    m.max_rxmt_window = atoi(argv[6]);    m.max_dds = atoi(argv[7]);    m.host_mode = atoi(argv[9]);    m.log_priority = atoi(argv[8]);    m.refresh_rate = atoi(argv[10]);    m.PPAdjLimit = atoi(argv[11]);    m.random_refresh = atoi(argv[12]);    ospf->cfgOspf(&m);    return(TCL_OK);}/* Dowload configuration of a single area */int SendArea(ClientData, Tcl_Interp *, int, char *argv[]){    CfgArea m;    m.area_id = ntoh32(inet_addr(argv[1]));    m.stub = atoi(argv[2]);    m.dflt_cost = atoi(argv[3]);    m.import_summs = atoi(argv[4]);    ospf->cfgArea(&m, ADD_ITEM);    return(TCL_OK);}int SendAggregate(ClientData, Tcl_Interp *, int, char *argv[]){    CfgRnge m;    InAddr net;    InAddr mask;    if (get_prefix(argv[1], net, mask)) {	m.net = net;	m.mask = mask;	m.area_id = ntoh32(inet_addr(argv[2]));	m.no_adv = atoi(argv[3]);	ospf->cfgRnge(&m, ADD_ITEM);    }    return(TCL_OK);}int SendHost(ClientData, Tcl_Interp *, int, char *argv[]){    CfgHost m;    InAddr net;    InAddr mask;    if (get_prefix(argv[1], net, mask)) {	m.net = net;	m.mask = mask;	m.area_id = ntoh32(inet_addr(argv[2]));	m.cost = atoi(argv[3]);	ospf->cfgHost(&m, ADD_ITEM);    }    return(TCL_OK);}/* Download an interface's configuration. * Interface can by identified by its address, name, or * for point-to-point addresses, the other end of the link. */int SendInterface(ClientData, Tcl_Interp *, int, char *argv[]){    CfgIfc m;    in_addr addr;    BSDPhyInt *phyp;    int intval;    if (!ospfd_sys->parse_interface(argv[1], addr, phyp))	return(TCL_OK);    m.address = phyp->addr;    m.phyint = phyp->phyint();    m.mask = phyp->mask;    intval = atoi(argv[2]);    m.mtu = (intval ? intval : phyp->mtu);    m.IfIndex = atoi(argv[3]);    m.area_id = ntoh32(inet_addr(argv[4]));    intval = atoi(argv[5]);    if (intval)	m.IfType = intval;    else if ((phyp->flags & IFF_BROADCAST) != 0)	m.IfType = IFT_BROADCAST;    else if ((phyp->flags & IFF_POINTOPOINT) != 0)	m.IfType = IFT_PP;    else	m.IfType = IFT_NBMA;    m.dr_pri = atoi(argv[6]);    m.xmt_dly = atoi(argv[7]);    m.rxmt_int = atoi(argv[8]);    m.hello_int = atoi(argv[9]);    m.if_cost = atoi(argv[10]);    m.dead_int = atoi(argv[11]);    m.poll_int = atoi(argv[12]);    m.auth_type = atoi(argv[13]);    memset(m.auth_key, 0, 8);    strncpy((char *) m.auth_key, argv[14], (size_t) 8);    m.mc_fwd = atoi(argv[15]);    m.demand = atoi(argv[16]);    m.passive = atoi(argv[17]);    switch (atoi(argv[18])) {      case 0:	m.igmp = 0;	break;      case 1:	m.igmp = 1;	break;      default:	m.igmp = ((m.IfType == IFT_BROADCAST) ? 1 : 0);	break;    }    ospf->cfgIfc(&m, ADD_ITEM);    return(TCL_OK);}int SendVL(ClientData, Tcl_Interp *, int, char *argv[]){    CfgVL m;    m.nbr_id = ntoh32(inet_addr(argv[1]));    m.transit_area = ntoh32(inet_addr(argv[2]));    m.xmt_dly = atoi(argv[3]);    m.rxmt_int = atoi(argv[4]);    m.hello_int = atoi(argv[5]);    m.dead_int = atoi(argv[6]);    m.auth_type = atoi(argv[7]);    strncpy((char *) m.auth_key, argv[8], (size_t) 8);    ospf->cfgVL(&m, ADD_ITEM);    return(TCL_OK);}int SendNeighbor(ClientData, Tcl_Interp *, int, char *argv[]){    CfgNbr m;    m.nbr_addr = ntoh32(inet_addr(argv[1]));    m.dr_eligible = atoi(argv[2]);    ospf->cfgNbr(&m, ADD_ITEM);    return(TCL_OK);}int SendExtRt(ClientData, Tcl_Interp *, int, char *argv[]){    CfgExRt m;    InAddr net;    InMask mask;    if (get_prefix(argv[1], net, mask)) {	m.net = net;	m.mask = mask;	m.type2 = (atoi(argv[3]) == 2);	m.mc = (atoi(argv[5]) != 0);	m.direct = 0;	m.noadv = 0;	m.cost = atoi(argv[4]);	m.gw = ntoh32(inet_addr(argv[2]));	m.phyint = ospfd_sys->get_phyint(m.gw);	m.tag = atoi(argv[6]);	ospf->cfgExRt(&m, ADD_ITEM);    }    return(TCL_OK);}int SendMD5Key(ClientData, Tcl_Interp *, int, char *argv[]){    CfgAuKey m;    in_addr addr;    BSDPhyInt *phyp;    timeval now;    tm tmstr;    if (!ospfd_sys->parse_interface(argv[1], addr, phyp))	return(TCL_OK);    gettimeofday(&now, 0);    m.address = phyp->addr;    m.phyint = phyp->phyint();    m.key_id = atoi(argv[2]);    memset(m.auth_key, 0, 16);    strncpy((char *) m.auth_key, argv[3], (size_t) 16);    if (strptime(argv[4], "%D@%T", &tmstr)) {	m.start_accept = SPFtime(mktime(&tmstr), 0);    } else {	m.start_accept = now;    }        if (strptime(argv[5], "%D@%T", &tmstr)) {	m.start_generate = SPFtime(mktime(&tmstr), 0);    } else {	m.start_accept = now;    }    if (strptime(argv[6], "%D@%T", &tmstr)) {	m.stop_generate = SPFtime(mktime(&tmstr), 0);	m.stop_generate_specified = true;    } else {	m.stop_generate_specified = false;    }    if (strptime(argv[7], "%D@%T", &tmstr)) {	m.stop_accept = SPFtime(mktime(&tmstr), 0);	m.stop_accept_specified = true;    } else {	m.stop_accept_specified = false;    }    ospf->cfgAuKey(&m, ADD_ITEM);    return(TCL_OK);}

⌨️ 快捷键说明

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