📄 rsvp_mstat.c
字号:
/* * This procedure extracts reservation state information from rsvpd * data structures, marshals it, and sends it in one or more UDP packets. */voidstatus_RSVP_Resv(struct sockaddr_in *sinp){ RSVPInfo_t *Infop = (RSVPInfo_t *) buff; ResvInfo_t *Resvp = (ResvInfo_t *) buff; ResvInfo_t *New_Resvp; Session *dst; int i; nSession = 0; Infop->type = hton32(TYPE_RSVP_VRESV); strtcpy(Infop->name, RSVPNodeName, NAME_LEN); Resvp = &Infop->Session_un.resvInfo; /* first session */ /* * For each session, marshal data for each style, if any. */ for (i= 0; i < SESS_HASH_SIZE; i++) for (dst = session_hash[i]; dst; dst = dst->d_next) { nStyle_Sess = 0; New_Resvp = fmt_WF_Resv(dst, Resvp); New_Resvp = fmt_FF_Resv(dst, New_Resvp); New_Resvp = fmt_SE_Resv(dst, New_Resvp); if ((char *) New_Resvp > &buff[max_msg_size]) { int newlen = (char *)New_Resvp - (char *)Resvp; status_send((char *)Resvp, sinp); New_Resvp = &Infop->Session_un.resvInfo; memcpy(New_Resvp, Resvp, newlen); New_Resvp = (ResvInfo_t *) ((char *)New_Resvp + newlen); nSession = 0; } nSession += nStyle_Sess; Resvp = New_Resvp; } /* * Scan my private Session_List, looking for sessions that had * resv state last time but have none this time, and send an * "empty" entry for any that are found (but truncate if fill * buffer). */ Gone_Sessp = NULL; do { Gone_Session(SL_FSM_RESV); if (Gone_Sessp) { Resvp->resv_session = Gone_Sessp->sl_dest; Resvp->resv_style = 0; /* => all styles! */ Resvp->resv_R = 0; Resvp->nStruct = 0; New_Resvp = (ResvInfo_t *) mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT); if ((char *) New_Resvp > &buff[max_msg_size]) { status_send((char *)Resvp, sinp); return; /* truncate... */ } nSession++; Resvp = New_Resvp; } } while (Gone_Sessp); /* * Write last data, if any */ if ((nSession) || Send_Empty) status_send((char *)Resvp, sinp); }static ResvInfo_t *fmt_WF_Resv(Session *dst, ResvInfo_t *Resvp) { ResvWF_t *Rp; char *if_name, *tp; int nResv = 0; RSB *rf; /* Compute offset into buffer, considering variable-length part * (policy data) in 2nd level header. Actually fill it in later * if we marshal one or more 3rd level headers. */ Rp = (ResvWF_t *) mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT); /* * Scan sender list for wildcard sender, and for that sender, * the vector of outgoing interfaces, and marshal any * reservation state that is found; nResv is count. */ for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) { if (rf->rs_style != STYLE_WF) continue; if (rf->rs_OIf == api_num) if_name = LOCAL_HOST; else if_name = if_vec[rf->rs_OIf].if_name; strtcpy(Rp->WF_if, if_name, IFNAMSIZ); Rp->WF_ttd = rf->rs_ttd; Rp->WF_nexthop = rf->_rs_nhop; HTON32(Rp->WF_ttd); tp = mstat_objcpy(Object_of(&Rp->WF_flowspec), Object_of(rf->rs_spec)); Rp = (ResvWF_t *) mstat_objcpy(Object_of(tp), &NULL_OBJECT); /*** XXX CHECK OVERFLOW?? ***/ nResv++; } /* If we found any WF reservation state, set up 2nd level header * and advance output pointer. If buffer full, send it. */ if (nResv) { nStyle_Sess++; New_Resv_Session(dst, Resvp, RAPI_RSTYLE_WILDCARD); Resvp->nStruct = nResv; HTON32(Resvp->nStruct); Resvp = (ResvInfo_t *) Rp; } return(Resvp);}static ResvInfo_t *fmt_FF_Resv(Session *dst, ResvInfo_t *Resvp) { ResvFF_t *Rp; int nResv = 0; char *if_name, *tp; RSB *rf; Rp = (ResvFF_t *) mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT); for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) { if (rf->rs_style != STYLE_FF) continue; if (rf->rs_OIf == api_num) if_name = LOCAL_HOST; else if_name = if_vec[rf->rs_OIf].if_name; strtcpy(Rp->FF_if, if_name, IFNAMSIZ); Rp->FF_ttd = rf->rs_ttd; Rp->FF_nexthop = rf->_rs_nhop; HTON32(Rp->FF_ttd); tp = mstat_objcpy(Object_of(&Rp->FF_flowspec), Object_of(rf->rs_spec)); Rp = (ResvFF_t *) mstat_objcpy(Object_of(tp), Object_of(rf->rs_filter0)); nResv++; /* XXX CHECK FOR OVERFLOW */ } /* If we found any FF reservation state, set up 2nd level header * and advance output pointer. If buffer full, send it. */ if (nResv) { nStyle_Sess++; New_Resv_Session(dst, Resvp, RAPI_RSTYLE_FIXED); Resvp->nStruct = nResv; HTON32(Resvp->nStruct); Resvp = (ResvInfo_t *) Rp; } return(Resvp);}static ResvInfo_t *fmt_SE_Resv(Session *dst, ResvInfo_t *Resvp) { ResvSE_t *Rp; int nResv = 0, i; char *if_name, *tp; RSB *rf; Rp = (ResvSE_t *) mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT); for (rf = dst->d_RSB_list; rf; rf = rf->rs_next) { if (rf->rs_style != STYLE_SE) continue; if (rf->rs_OIf == api_num) if_name = LOCAL_HOST; else if_name = if_vec[rf->rs_OIf].if_name; strtcpy(Rp->SE_if, if_name, IFNAMSIZ); Rp->SE_ttd = rf->rs_ttd; Rp->SE_nexthop = rf->_rs_nhop; HTON32(Rp->SE_ttd); tp = mstat_objcpy(Object_of(&Rp->SE_flowspec), Object_of(rf->rs_spec)); Rp->nSE_filts = rf->rs_fcount; HTON32(Rp->nSE_filts); for (i = 0; i < rf->rs_fcount; i++) { tp = mstat_objcpy(Object_of(tp), Object_of(rf->rs_Filtp(i))); } Rp = (ResvSE_t *)tp; nResv++; /* CHECK FOR OVERFLOW */ } /* If we found any SE reservation state, set up 2nd level header * and advance output pointer. If buffer full, send it. */ if (nResv) { nStyle_Sess++; New_Resv_Session(dst, Resvp, RAPI_RSTYLE_SE); Resvp->nStruct = nResv; HTON32(Resvp->nStruct); Resvp = (ResvInfo_t *) Rp; } return(Resvp);}static voidNew_Resv_Session(Session *dst, ResvInfo_t *Resvp, int styleid) { Resvp->resv_session.sess_destaddr.s_addr = dst->d_addr.s_addr; Resvp->resv_session.sess_destport = dst->d_port; Mark_Session(&Resvp->resv_session, SL_FSM_RESV); Resvp->resv_style = styleid; HTON32(Resvp->resv_style); Resvp->resv_R = dst->d_Rtimor; HTON32(Resvp->resv_R); mstat_objcpy(Object_of(&Resvp->resv_policy), &NULL_OBJECT);}static voidstatus_send(char *bp, struct sockaddr_in *sinp) { RSVPInfo_t *Infop = (RSVPInfo_t *) buff; int len = bp - buff; Infop->nSession = nSession; HTON32(Infop->nSession); if (sendto(statsock, buff, len, 0, (struct sockaddr *) sinp, sizeof(struct sockaddr_in)) < 0) log(LOG_WARNING, errno, "sendto\n"); nSession = 0;}/* * Copy variable-length RSVP object -- flowspec, filterspec, ... or NULL */static char *mstat_objcpy(Object_header *dstp, Object_header *srcp){ char *tp; if (srcp) memcpy(dstp, srcp, Obj_Length(srcp)); else memcpy(dstp, &NULL_OBJECT, 4); tp = (char *)Next_Object(dstp);#if BYTE_ORDER == LITTLE_ENDIAN hton_object(dstp);#endif return(tp);} /* * Look up destination (session) [in network byte order] in local session * table, and mark it active. */static voidMark_Session(SESSION_ipv4 *sesp, int FSMid) { struct session_list *slp, *avail_slp = NULL; for (slp = Session_List; slp < Next_Sessp; slp++) { if (slp->sl_fsms[FSMid] == SL_IDLE) { if (slp->sl_fsms[SL_FSM_PATH] == SL_IDLE && slp->sl_fsms[SL_FSM_RESV] == SL_IDLE) { /* Entry not in use... clean it up */ slp->sl_dest.sess_destaddr.s_addr = 0; slp->sl_dest.sess_destport = 0; avail_slp = slp; } continue; } if (slp->sl_dest.sess_destaddr.s_addr == sesp->sess_destaddr.s_addr && slp->sl_dest.sess_destport == sesp->sess_destport) { slp->sl_fsms[FSMid] = SL_ACTV; if (IsDebugSess) fprintf(stderr, "%d ACTV %8.8X\n", FSMid, (u_int) slp); return; } } /* * Session is new... add it to table. */ if (avail_slp == NULL) { /* Did not find an unused slot. Extend table (if poss.) */ if (Next_Sessp >= &Session_List[MAX_SL]) return; /* Table is full, ignore this session */ avail_slp = Next_Sessp++; } if (IsDebugSess) fprintf(stderr, "%d NEW %8.8X <- ACTV\n", FSMid, (u_int) avail_slp); avail_slp->sl_dest = *sesp; avail_slp->sl_fsms[FSMid] = SL_ACTV; }/* * Calling this procedure sets Gone_Sessp to point to an entry * in the session_list that has been deleted, or to NULL if there * are no more such entries. */static voidGone_Session(int FSMid) { if (Gone_Sessp == NULL) Gone_Sessp = &Session_List[0]; else Gone_Sessp++; while (Gone_Sessp < Next_Sessp) { switch (Gone_Sessp->sl_fsms[FSMid]) { case SL_OLD: /* * Was there previously, but isn't now. Change to * IDLE state and return to process send GONE status. */ Gone_Sessp->sl_fsms[FSMid] = SL_IDLE; if (IsDebugSess) fprintf(stderr, "%d GONE %8.8X <- IDLE\n", FSMid, (u_int) Gone_Sessp); return; case SL_ACTV: if (IsDebugSess) fprintf(stderr, "%d UNMARK %8.8X <- OLD\n", FSMid, (u_int) Gone_Sessp); Gone_Sessp->sl_fsms[FSMid] = SL_OLD; break; default: break; } Gone_Sessp++; } Gone_Sessp = NULL;}/* * Remove any final suffix .<chars> (if any) from the end of a given string * by storing a NULL on top of the dot. Return a pointer to the beginning of * <chars>, or NULL if there is no suffix. **ShOULD ALLOW ':'** */char *rmsuffix(cp) char *cp;{ char *tp; tp = cp + strlen(cp) - 1; while (*tp != '.' && tp >= cp) tp--; if (*tp != '.') return (NULL); *tp = '\0'; return ((char *) tp + 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -