📄 rsvp_diag.c
字号:
/* * * @(#) $Id: rsvp_diag.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_diag.c ******************************* * * * Routines to receive, process, and send diagnostic * * messages. * * * * * *********************************************************************//**************************************************************************** RSVPD -- ReSerVation Protocol Daemon USC Information Sciences Institute Marina del Rey, California Original Version: Shai Herzog, Nov. 1993. Current Version: Steven Berson & Bob Braden, May 1996. Copyright (c) 1996 by the University of Southern California All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation in source and binary forms for any purpose and without fee is hereby granted, provided that both the above copyright notice and this permission notice appear in all copies. and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed in part by the University of Southern California, Information Sciences Institute. The name of the University may not be used to endorse or promote products derived from this software without specific prior written permission. THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about the suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Other copyrights might apply to parts of this software and are so noted when applicable.********************************************************************/#include "rsvp_daemon.h"#include <sys/time.h>/* external declarations */int rsvp_pkt_process(struct packet *, net_addr *, int);Object_header *copy_object(Object_header *);int send_pkt_out_if(int, RSVP_HOP *, struct packet *);struct packet *new_packet_area(packet_area *);PSB *locate_PSB(Session *, SENDER_TEMPLATE *, int, RSVP_HOP *);int send_msgto(int, struct sockaddr_in *, struct in_addr *,struct packet *);int match_filt2star(FILTER_SPEC *, FiltSpecStar *);void FQkill(Fobject **);/* forward declarations */RSB *locate_RSB_diag(Session *, RSVP_HOP *, FILTER_SPEC *, int);int accept_diag_request(int, struct packet *, net_addr *);int accept_diag_reply(int, struct packet *);int send_diag_reply(struct packet *, int, u_char, RSVP_HOP *,int, DIAG_RESPONSE *);extern int bmptoif(bitmap *);extern int rsrr_route_query(void*,void *,net_addr *,net_addr *,int,int *,bitmap *);#define JAN_1970 2208988800UL /*1970-1900 in seconds *//* definitions for margin in rsvp diag replies and other constants */#define ROUTE_MARGIN (pkt->pkt_map->rsvp_resplist-1)*sizeof(struct in_addr)+ \ sizeof(ROUTE)#define packet_MTU pkt_map->rsvp_diag->diag_pMTU/* * accept_diag_request() : Process an incoming DREQ (diagnostics request) * (DREQ forwarding) * The local diagnostic response and optional ROUTE object are * inserted. */intaccept_diag_request(int in_vif, struct packet *pkt, net_addr *fromp){ struct timeval tp; Session *destp; DIAG_RESPONSE *d_resp; u_char hop_count; u_char flags = 0, H;#define DREQ_TRIMFWD 0x01#define DREQ_MAXHOP 0x02 if_rec phys_int, phys_fw_int, in_int; RSB *rsbp = NULL, tRSB; PSB *psbp = NULL; FILTER_SPEC *sendr_filtp; RSVP_HOP err_hop, nhop, *fwhop = NULL; ROUTE *droute, *dr_old = NULL; int mode = 0; int num_of_resp, fw_if, rc; net_addr laddr, saddr; Object_header *objp,*old_objp;/* Diagnostics processing at this hop : * If this packet already has embedded replies, and this node is the * LAST HOP, there could be a loop. In this case we will just drop * the packet. The other three combinations of (embedded-replies?, * last-hop?) are valid. */ NET_SET_ADDR_IPv4(&laddr,pkt->rsvp_diagnostic->diag_laddr); NET_SET_ADDR_IPv4(&saddr,pkt->rsvp_diagnostic->diag_saddr); if ( (pkt->rsvp_drespnum != 0) && (map_if_addr(&laddr) >=0)) return -1; H = DIAG_HBIT(pkt->rsvp_diagnostic); gettimeofday(&tp, 0); num_of_resp = pkt->pkt_map->rsvp_resplist; /* Increment the RSVP-hop-count field in the diagnostic packet * header */ pkt->rsvp_diagnostic->diag_hopcount++; /* If this packet already contained a ROUTE object, copy it out * for mapping it back in later after expanding it. */ if (H == 1) dr_old = (ROUTE *)copy_object( (Object_header *) pkt->pkt_map->rsvp_route); /* * Initialize the DIAG_RESPONSE et al */ d_resp = (DIAG_RESPONSE *)((char *)pkt->pkt_data + pkt->pkt_len); Init_Object(d_resp, DIAG_RESPONSE, DIAG_RESPONSE_ipv4); /* Init_Object(&sendr_filtp, FILTER_SPEC, ctype_FILTER_SPEC_ipv4);*/ Init_Object(&err_hop, RSVP_HOP, RSVP_HOP_ipv4); /* Set up the nhop, for locating RSB from RSB list later */ if (fromp) { Init_Object(&nhop, RSVP_HOP, RSVP_HOP_ipv4); nhop.hop4_addr = NET_GET_ADDR_IPv4(fromp); } /* Set DREQ arrival timer - 32bit NTP timestamp is use */ d_resp->resp_arrtime = ((tp.tv_sec+JAN_1970) << 16) + (tp.tv_usec << 10)/15625 ; hop_count= pkt->pkt_data->rsvp_snd_TTL - pkt->pkt_ttl; d_resp->resp_DTTL = hop_count; objp = Next_Object(d_resp); /* If no PATH state exists for the specified session, set * R-error in the Response Data object */ destp = locate_session(pkt->rsvp_sess); if (!destp) d_resp->resp_Rerror |= (RSVP_Erv_Diag_NOPATH << 4); else { /* Session exists * Locate the sender's path state in the session block */ sendr_filtp = &pkt->pkt_map->rsvp_diag->diag_sfiltp; psbp = locate_PSB(destp, sendr_filtp, -1,NULL); if (!psbp) { /* No path state for this sender */ d_resp->resp_Rerror=(RSVP_Erv_Diag_NOPATH << 4); } else { /* * fwhop and fw_if are used to forward the DREQ upstream */ fwhop = &psbp->ps_rsvp_phop; phys_int=if_vec[IF_UNICAST(in_vif)]; fw_if = psbp->ps_in_if; phys_fw_int=if_vec[IF_UNICAST(fw_if)]; /* If path MTU value is too large, set "MTU too large" * error bit, and change MTU value to that of the current * router. * * RSVP_DIAGS! : DISABLE this check now because if_vec's mtu is 0! * As a result, the MTU too large error will never happen. * But the trim and forward function will still work. if (pkt->packet_MTU > phys_fw_int.if_path_mtu) { pkt->packet_MTU = phys_fw_int.if_path_mtu; d_resp->response_Rerror |= (RSVP_Erv_Diag_MTUBIG << 4); } */ d_resp->resp_timeval = (u_int16_t) ((destp->d_refr_p.d_timeval.timev_R) /1000); in_int = if_vec[IF_UNICAST((int) psbp->ps_in_if)]; d_resp->resp_in_addr = NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&in_int.if_addr)); d_resp->resp_out_addr = NET_GET_ADDR_IPv4(&NET_GET_IF_PHY_ADDR(&phys_int.if_addr)); d_resp->resp_pre_addr = psbp->ps_phop.hop4_addr ; /* * Append RSVP objects containing variable response * information from the RSB and LLSB onto the end of * the outer DIAG_RESPONSE object. * Warning : Buffer overflow is not being checked for currently. */ /* Append Tspec of sender; save object location for overwriting * with effect traffic control tspec later, if reservation exists */ old_objp = objp; Move_Object(psbp->ps_tspec, objp); objp = Next_Object(objp); /* Find a reservation if it exists and append traffic control state */ rsbp = locate_RSB_diag(destp, &nhop,sendr_filtp, in_vif); if (rsbp != NULL) { /* Found RSB which matches outgoing Iface */ d_resp->resp_rstyle = rsbp->rs_style; /* K value */ d_resp->resp_Rerror |= K_FACTOR; /* * Build temporary RSB as parm list and * Extract effective link-layer values. */ tRSB.rs_OIf = rsbp->rs_OIf; tRSB.rs_filtstar = rsbp->rs_filtstar; tRSB.rs_style = rsbp->rs_style; tRSB.rs_UnkObjList = NULL ; rc = LL_GetInfo(tRSB.rs_OIf, destp, &tRSB); if (rc == LLDAL_RC_OK) { int i; if (tRSB.rs_flags & RSB_FLAG_MERGED) d_resp->resp_Rerror |=( 0x01 << 7 ); /* * Override Tspec with effective Tspec from LL; */ objp = old_objp; Move_Object(tRSB.rs_oldspec,objp); objp = Next_Object(objp); /* Append Effective flowspec */ Move_Object(tRSB.rs_spec, objp); objp = Next_Object(objp); /* Append all filter specs (senders) using * this (LL) reservation. */ for (i=0; i<tRSB.rs_fcount; i++){ move_object((Object_header *) tRSB.rs_Filtp(i), objp); objp = Next_Object(objp); } }/* Reservation exists */ } }/* Path state exists */ }/* Session exists */ Obj_Length(d_resp) = (char *)objp - (char *)d_resp; if (!pkt->pkt_map->rsvp_diag_response) pkt->pkt_map->rsvp_diag_response = d_resp ; pkt->pkt_map->rsvp_resplist ++; /* Update current pkt_len */ pkt->pkt_len += Obj_Length(d_resp); /* If we've reached the max hop limit, set a flag. */ if (pkt->rsvp_diagnostic->diag_hopcount == pkt->rsvp_diagnostic->diag_maxhops) flags |= DREQ_MAXHOP; /* if the resulting DREQ packet size exceeds MTU limit, and * if we have not reach the max hop limit, and this hop is not * the diagnosed sender, set the TRIMFWD flag. */ if (pkt->pkt_len > pkt->packet_MTU && !(flags & DREQ_MAXHOP) && (map_if_addr(&saddr) < 0)) flags |= DREQ_TRIMFWD ; /* For HBH mode of reply, if this is the last hop, create and * initialize a ROUTE object. */ if (H == 1) { droute = (ROUTE *)((char *)pkt->pkt_data + pkt->pkt_len); if (map_if_addr(&laddr) >=0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -