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

📄 grplsa.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 dealing with group-membership-LSAs. * This includes originating, parsing, and * running routing calculations. */#include "ospfinc.h"#include "phyint.h"#include "ifcfsm.h"/* Constructor for a group-membership-LSA. */grpLSA::grpLSA(SpfArea *a, LShdr *hdr, int blen) : LSA(0, a, hdr, blen){}/* Parse a group-membership-LSA. Just set the exception * flag, so that the caller will instead store * the body of the LSA. */void grpLSA::parse(LShdr *){    exception = true;}/* Unparse a group-LSA. NULL function. */void grpLSA::unparse(){}/* Build a group-membership-LSA. Since the parse function * always sets the exception flag, this function is never really * called. */void grpLSA::build(LShdr *){}/* Reoriginate a group-membership-LSA. */void grpLSA::reoriginate(int forced){    lsa_ap->grp_orig(ls_id(), forced);}/* Reoriginate the group-membership-LSAs for a given * group -- all areas at once. */void OSPF::grp_orig(InAddr group, int forced){    SpfArea *ap;    AreaIterator aiter(ospf);    while ((ap = aiter.get_next())) {	if (ap->n_active_if != 0)	    ap->grp_orig(group, forced);    }}/* Build the group-membership-LSA for a given multicast group * and area. We search through all the group entries, and * assume that the phyint of 0 is not used. */void SpfArea::grp_orig(InAddr group, int forced){    LSA *olsap;    AVLsearch iter(&ospf->local_membership);    bool added_self;    int maxlen;    LShdr *hdr;    uns16 length;    seq_t seqno;    AVLitem *entry;    GMref *gmref;    olsap = ospf->myLSA(0, this, LST_GM, group);    if (!ospf->mospf_enabled()) {	lsa_flush(olsap);	return;    }    // Estimate size of LSA    maxlen = sizeof(LShdr) + sizeof(GMref);    iter.seek(group, 0);    while ((entry = iter.next()) && entry->index1() == group)	maxlen += sizeof(GMref);    // Get LS Sequence Number    seqno = ospf->ospf_get_seqno(LST_GM, olsap, forced);    if (seqno == InvalidLSSeq)	return;    // Fill in LSA header    hdr = ospf->orig_buffer(maxlen);    hdr->ls_opts = SPO_DC | SPO_MC;    if (!a_stub)	hdr->ls_opts |= SPO_EXT;    hdr->ls_type = LST_GM;    hdr->ls_id = hton32(group);    hdr->ls_org = hton32(ospf->my_id());    hdr->ls_seqno = hton32(seqno);    // Body    length = sizeof(LShdr);    added_self = false;    gmref = (GMref *) (hdr + 1);    iter.seek(group, 0);    while ((entry = iter.next()) && entry->index1() == group) {        PhyInt *phyp;	int phyint=(int)entry->index2();	if (phyint != -1) {	    if (!(phyp = (PhyInt *)ospf->phyints.find((uns32) phyint, 0)))	        continue;	    if (!phyp->mospf_ifp)	        continue;	    if (phyp->mospf_ifp->area() != this)	        continue;	    if (phyp->mospf_ifp->if_nfull > 0 &&		phyp->mospf_ifp->is_multi_access()) {	        if (phyp->mospf_ifp->if_state == IFS_DR) {	            gmref->ls_type = hton32(LST_NET);		    gmref->ls_id = hton32(phyp->mospf_ifp->if_addr);		    gmref++;		    length += sizeof(GMref);		}		continue;	    }	    // Fall through on stubs and point-to-point links	}	// Add self instead	if (!added_self) {	    added_self = true;	    gmref->ls_type = hton32(LST_RTR);	    gmref->ls_id = hton32(ospf->my_id());	    gmref++;	    length += sizeof(GMref);	}    }    // If backbone area, may need to advertise membership from    // other areas.    if (!added_self && a_id == BACKBONE) {        AreaIterator a_iter(ospf);	SpfArea *a;	while ((a = a_iter.get_next()) && !added_self) {	    AVLsearch g_iter(&a->grpLSAs);	    LSA *glsa;	    if (a == this)	        continue;	    g_iter.seek(group, 0);	    while ((glsa = (LSA *)g_iter.next()) && glsa->index1() == group) {	        if (!glsa->parsed)		    continue;	        added_self = true;		gmref->ls_type = hton32(LST_RTR);		gmref->ls_id = hton32(ospf->my_id());		gmref++;		length += sizeof(GMref);		break;	    }	}    }    // Empty?    if (length == sizeof(LShdr))	lsa_flush(olsap);    else {	// Fill in length, then reoriginate        hdr->ls_length = hton16(length);	(void) ospf->lsa_reorig(0, this, olsap, hdr, forced);    }    ospf->free_orig_buffer(hdr);}/* The state of an interface has changed, requiring us * to reoriginate all the group-LSAs with members * on the interface. */void SpfIfc::reorig_all_grplsas(){    PhyInt *phyp;    AVLsearch iter(&ospf->local_membership);    AVLitem *entry;    if (!(phyp = (PhyInt *)ospf->phyints.find((uns32) if_phyint, 0)))	return;    if (phyp->mospf_ifp != this)	return;    while ((entry = iter.next())) {        if (entry->index2() == (uns32)if_phyint)	    if_area->grp_orig(entry->index1(), 0);    }}/* Determine whether there are grpup members directly * attached to a transit node, by looking for * the appropriate group-membership-LSA referencing * the transit node. * The body of the group-membership-LSA has not been * parsed, and is still in network-byte order. */bool TNode::has_members(InAddr group){    grpLSA *glsa;    size_t len;    GMref *vp;    // Always act as if group members for wild card receivers    if (is_wild_card())        return(true);    // look for group-membership-LSA    glsa = (grpLSA *) ospf->FindLSA(0, lsa_ap, LST_GM, group, adv_rtr());    if (!glsa || glsa->lsa_age() == MaxAge)	return(false);    // Search for vertex    len = glsa->ls_length() - sizeof(LShdr);    vp =  (GMref *) glsa->lsa_body;    for (; len >= sizeof(*vp); vp++, len -= sizeof(*vp)) {	if (ntoh32(vp->ls_id) != ls_id())	    continue;	if (ntoh32(vp->ls_type) == ls_type())	    return(true);    }    return(false);}

⌨️ 快捷键说明

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