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

📄 ripng.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	    syslog(LOG_DEBUG, "RIPng DUMP\t%d\t%s/%d (%d) on %s",		   nn, ip6str(&np->rip6_dest, 0),		   np->rip6_plen, np->rip6_metric,		   ripif->rip_ife->ifi_ifn->if_name);	  np++;  /* nibbing */ 	  nn++;  /* count   */	    	  agg->rt_aggr.ag_flags |= AGGR_ADVDONE;	}	if (!((rte->rt_aggr.ag_flags & AGGR_NOADVD) &&	      agg &&	      agg->rt_aggr.ag_flags & AGGR_ADVDONE) &&	    !rip_output_filter(ripif, &rte->rt_ripinfo)) {	  if ((ripif->rip_mode & IFS_DEFAULTORIGINATE) &&	      IN6_IS_ADDR_UNSPECIFIED(&rte->rt_ripinfo.rip6_dest) &&	      rte->rt_ripinfo.rip6_plen == 0) {	    IFLOG(LOG_RIP)	      syslog(LOG_DEBUG,		     "<%s>: ignore default route when originating",		     __FUNCTION__);		  goto nextroute;	  }	  memcpy(np, &rte->rt_ripinfo, sizeof(struct ripinfo6));	  np->rip6_metric = MIN(np->rip6_metric+1, RIPNG_METRIC_UNREACHABLE);	  IFLOG(LOG_RIP)	    syslog(LOG_DEBUG, "RIPng DUMP\t%d\t%s/%d (%d) on %s",		   nn, ip6str(&np->rip6_dest, 0),		   np->rip6_plen, np->rip6_metric,		   ripif->rip_ife->ifi_ifn->if_name);	  np++;  /* nibbing */ 	  nn++;  /* count   */	}      }      nextroute:      if ((rte = rte->rt_next) == base)	break;    } /* while(rte) */    if ((rtp = rtp->rtp_next) == ripif->rip_adj_ribs_out)      break;  } /* while(rtp) */  return nn;  /* End of rip_make_dump() */}/* *  rip_make_data()  *    DESCRIPTION: make a RIP data. (excluding RIP header) */intrip_make_data(rte, ripif, ripmode)     struct rt_entry *rte;     struct ripif    *ripif;  /* NULL case .... withdrawning. */     byte	     ripmode;{  struct ripinfo6 *np;   /* RIPng RTE, nibbing "ripbuf" */  struct rt_entry *r, *agg;  struct rtproto   artp;  int nn = 0;  np  = (struct ripinfo6 *)(ripbuf + sizeof(struct riphdr));  if (ripif) {    memset(&artp, 0, sizeof(artp));    artp.rtp_type = RTPROTO_IF;    artp.rtp_if   = ripif->rip_ife;  }  r = rte;  while(r) {    agg = r->rt_aggr.ag_agg;    if (ripif &&	aggr_advable(agg, &artp) &&	!rip_output_filter(ripif, &agg->rt_ripinfo)) {      if ((ripmode & IFS_DEFAULTORIGINATE) &&	  IN6_IS_ADDR_UNSPECIFIED(&agg->rt_ripinfo.rip6_dest) &&	  agg->rt_ripinfo.rip6_plen) {	IFLOG(LOG_RIP)	  syslog(LOG_DEBUG,		 "<%s>: ignore default route when originating",		 __FUNCTION__);	      goto nextroute;      }      memcpy(np, &agg->rt_ripinfo, sizeof(struct ripinfo6));      np->rip6_metric = MIN(np->rip6_metric+1, RIPNG_METRIC_UNREACHABLE);      np++;  /* nibbing */       nn++;  /* count   */	          agg->rt_aggr.ag_flags |= AGGR_ADVDONE;    }    if (ripif == NULL ||  /* withdrawing or.. */	(((r->rt_flags & RTF_UP ||	  (r->rt_proto.rtp_type == RTPROTO_RIP &&	   (r->rt_flags & RTF_IGP_EGP_SYNC)))       &&	 !(r->rt_aggr.ag_flags & AGGR_NOADVD &&	   agg                               &&	   (agg->rt_aggr.ag_flags & AGGR_ADVDONE))) &&	!rip_output_filter(ripif, &r->rt_ripinfo))) {      if ((ripmode & IFS_DEFAULTORIGINATE) &&	  IN6_IS_ADDR_UNSPECIFIED(&r->rt_ripinfo.rip6_dest) &&	  r->rt_ripinfo.rip6_plen) {	IFLOG(LOG_RIP)	  syslog(LOG_DEBUG,		 "<%s>: ignore default route when originating",		 __FUNCTION__);	      goto nextroute;      }      memcpy(np, &r->rt_ripinfo, sizeof(struct ripinfo6));      np->rip6_metric = MIN(np->rip6_metric + 1, RIPNG_METRIC_UNREACHABLE);      np++;  /* nibbing */       nn++;  /* count   */     }    nextroute:    if ((r = r->rt_next) == rte)      break;  }  return nn;  /* End of rip_make_data() */}/* *    find_rip_by_index() */struct ripif *find_rip_by_index(u_int index){  struct ripif *rip;  extern struct ripif *ripifs;    if ((rip = ripifs) == NULL)    return NULL;  while(rip) {    if (rip->rip_ife == NULL ||	rip->rip_ife->ifi_ifn == NULL)      fatalx("<find_rip_by_index>: BUG !");        if (rip->rip_ife->ifi_ifn->if_index == index)      break;    if ((rip = rip->rip_next) == ripifs)      return NULL;  }  return rip;}/* *  rip_disable_rte() *    DESCRIPTION: called by rip_life_expired(), bgp_process_update(), *                            or, when received metric=16. */struct rt_entry *rip_disable_rte(rte)     struct rt_entry *rte;{  struct rt_entry *crte;  /* to be copied */  IFLOG(LOG_RIP)    syslog(LOG_DEBUG, "<%s>: delroute()...", __FUNCTION__);  if (delroute(rte, &rte->rt_gw) != 0) {    syslog(LOG_ERR, "<%s>: route couldn't be deleted.", __FUNCTION__);    return NULL;    rte->rt_flags &= ~RTF_UP;  }  rte->rt_flags &= ~RTF_UP;          /* down */  rte->rt_ripinfo.rip6_metric = RIPNG_METRIC_UNREACHABLE;  /* also disable BGP routes that use this route to resolve the nexthop */  bgp_disable_rte_by_igp(rte);  MALLOC(crte, struct rt_entry);  memcpy(crte, rte, sizeof(struct rt_entry));  return crte;}/* *  rip_erase_rte() *     DESCRIPTION:  Kernel delroute(). *                   rip_adj_ribs_in is shorten. */voidrip_erase_rte(rte)     struct rt_entry *rte;{  struct ripif    *ripif;  if (rte->rt_proto.rtp_type != RTPROTO_RIP)    fatalx("<rip_erase_rte>: BUG !");  IFLOG(LOG_RIP)    syslog(LOG_DEBUG, "<%s>: delroute()...", __FUNCTION__);  if (delroute(rte, &rte->rt_gw) != 0)    syslog(LOG_ERR, "<%s>: route couldn't be deleted.", __FUNCTION__);  /* also disable BGP routes that use this route to resolve the nexthop */  bgp_disable_rte_by_igp(rte);  if ((ripif = rte->rt_proto.rtp_rip) == NULL)    fatalx("<rip_erase_rte>: BUG !");  ripif->rip_adj_ribs_in     = rte_remove(rte, ripif->rip_adj_ribs_in);}/* *  rip_change_rte() */struct rt_entry *rip_change_rte(rte)     struct rt_entry *rte;{  struct rt_entry *crte;  /* to be copied */  if (chroute(rte, &rte->rt_gw, rte->rt_proto.rtp_rip->rip_ife) != 0) {    syslog(LOG_ERR, "<rip_change_rte>: route couldn't be changed.");    return NULL;  }  MALLOC(crte, struct rt_entry);  memcpy(crte, rte, sizeof(struct rt_entry));  return crte;}/* *   rip_dump() *      triggered by SIGALRM. */voidrip_dump() {  struct ripif        *ripif;  struct in6_pktinfo   spktinfo;      /* Adv. API */  struct riphdr       *rp;  int                  nn;  extern task                *taskhead;  memset(ripbuf, 0, RIPNG_BUFSIZ);  memset(rippkt, 0, RIPNG_MAXPKT);  rp = (struct riphdr *)rippkt;    /* outgoing RIPng header  */  rp->riph_cmd   = RIPNGCMD_RESPONSE;  rp->riph_vers  = RIPNG_VERSION;  rp->riph_zero2 = 0;  ripif = ripifs;  /* global */  while(ripif) {    if (!(ripif->rip_mode & IFS_NORIPOUT)) {      nn = rip_make_dump(ripif);     /* periodic DUMP */	      spktinfo.ipi6_addr    = ripif->rip_ife->ifi_laddr;  /* copy */      spktinfo.ipi6_ifindex = ripif->rip_ife->ifi_ifn->if_index;      if (nn > 0) {	int mm;  /* current */	int done;	done = 0;	while(1) {	  mm = MIN(nn - done, RIPNG_MAXRTES);	  memcpy(&rippkt[sizeof(struct riphdr)],		 &ripbuf[sizeof(struct riphdr) + done*sizeof(struct ripinfo6)],		 mm * sizeof(struct ripinfo6));	  if (rip_sendmsg(&ripsin,      /* ff02::9.RIPNG_PORT  */			  &spktinfo,    /* source address, I/F */			  sizeof(struct riphdr) +			  mm * sizeof(struct ripinfo6)))	    ripif->rip_respfail++;	  ripif->rip_responsesent++;	  done += mm;	  if (done == nn) break;	}      }    }    if ((ripif = ripif->rip_next) == ripifs)      break;  }  taskhead->tsk_timefull.tv_sec = RIP_T_DUMP +    (random()%(RIP_T_DUMPRAND*2)) - RIP_T_DUMPRAND;  taskhead->tsk_timefull.tv_usec = 0;  task_timer_update(taskhead);  /* End of rip_dump() */}/* *   rip_life_expired() */voidrip_life_expired() {  struct ripif    *ripif;  task            *garbage;  byte             garbageyes;  struct rt_entry *rte;                         /* cursor */  struct rt_entry *dwnrte;  extern task     *taskhead;  MALLOC(garbage, task);  garbageyes = 0;  garbage->tsk_timename = RIP_GARBAGE_TIMER;  ripif = taskhead->tsk_rip;  rte = ripif->rip_adj_ribs_in;  while(rte) {    dwnrte = NULL;    if (rte->rt_riptime->tsk_next == NULL)  /* safety check */      fatalx("<rip_life_expired>: BUG !");    if (rte->rt_riptime == taskhead) {      rte->rt_riptime = garbage;   garbageyes = 1;      rte->rt_ripinfo.rip6_metric = RIPNG_METRIC_UNREACHABLE;      IFLOG(LOG_RIP)	syslog(LOG_DEBUG, "<%s>: calling rip_disable_rte()...", __FUNCTION__);      dwnrte = rip_disable_rte(rte); /* copied */      if (dwnrte) {	dwnrte->rt_next = dwnrte->rt_prev = dwnrte;	propagate(dwnrte);      /* triggered update */	free(dwnrte);		bgp_recover_rte(rte);      }    }    if ((rte = rte->rt_next) ==  ripif->rip_adj_ribs_in)      break;  } /* while(rte) */  taskhead = task_remove(taskhead);   /* erase lifetime */  if (garbageyes) {    garbage->tsk_rip             = ripif;    garbage->tsk_timename        = RIP_GARBAGE_TIMER;    garbage->tsk_timefull.tv_sec = RIP_T_GARBAGE;    insque(garbage, taskhead);         /* taskhead exists. */    task_timer_update(garbage);  } else {    free(garbage);  }  return;}/* *   rip_garbage_expired() */voidrip_garbage_expired() {  struct ripif    *ripif;  struct rt_entry *rte;                         /* cursor */  extern task     *taskhead;  IFLOG(LOG_RIP)    syslog(LOG_DEBUG, "<rip_garbage_expired>: invoked.");  ripif = taskhead->tsk_rip;  rte = ripif->rip_adj_ribs_in;  if (rte)    while(rte) {      if (rte->rt_riptime == taskhead) {	ripif->rip_adj_ribs_in 	  = rte_remove(rte, ripif->rip_adj_ribs_in);	if ((rte = ripif->rip_adj_ribs_in))	  continue;	else	  break;      }      if ((rte = rte->rt_next) == ripif->rip_adj_ribs_in)	break;    }  taskhead = task_remove(taskhead);  IFLOG(LOG_RIP)    syslog(LOG_DEBUG, "<rip_garbage_expired>: done.");}/* * Detect if a specified outgoing RIPng route should be filtered on the given * interface. * 1. If we specify to restrict rotes to the default, all non default routes *    should be filtered. * 2. If we specify the restiction list, filter the route unless it *    matches at least one entry of the list. * 3. If we filter the default route on the interface, filter it. * 4. If we specify the filter list, the route that matches *    at least one entry of the list should be filtered. */intrip_output_filter(struct ripif *ripif, struct ripinfo6 *ripinfo){	struct filterset *f = &ripif->rip_filterset;	if (output_filter_check(f, rip_use_sitelocal, ripinfo)) {		IFLOG(LOG_RIP)			syslog(LOG_DEBUG,			       "<%s>: output route %s/%d on %s was filtered",			       __FUNCTION__,			       ip6str(&ripinfo->rip6_dest, 0),			       ripinfo->rip6_plen,			       ripif->rip_ife->ifi_ifn->if_name);		return(1);	}	return(0);}

⌨️ 快捷键说明

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