📄 rsvptrace.c
字号:
inttrace_input() { struct sockaddr_in from; net_addr src; net_if inf; int recv_len, rc; struct packet packet; packet_map map; recv_len = net_recv(&src, recv_buff, sizeof(recv_buff), &inf); if (recv_len < 0) { perror("recvfrom "); return (-1); } packet.pkt_order = BO_NET; packet.pkt_len = recv_len; packet.pkt_data = (common_header *) recv_buff; packet.pkt_offset = 0; packet.pkt_map = (packet_map *) ↦ packet.pkt_flags = PKTFLG_USE_UDP; packet.pkt_ttl = packet.pkt_data->rsvp_snd_TTL; /* * Call our common routine to do initial processing of RSVP packet. */ rc = rsvp_pkt_map(&packet); if (rc != PKT_OK) { printf("\nParse error in packet received from %s\n", iptoname(&from.sin_addr)); return (0); } switch (map.rsvp_msgtype) { case RSVP_DREP: return(trace_accept_reply(&packet,&src)); default: return (0); }}/* next_wait() : * * Starting from a given timeval and "wait" time in seconds, * calulate a wait timeval. The given timeval is typically some * time of an event like a sent or received packet . * * returns 1 for no wait time, zero otherwise. */intnext_wait(struct timeval *tfrom, int wait,struct timeval *twait) { struct timeval t_now; struct timezone tz; if (gettimeofday(&t_now,&tz) < 0) { perror("get time error "); exit(-1); } twait->tv_sec = (tfrom->tv_sec + wait) - t_now.tv_sec ; twait->tv_usec = tfrom->tv_usec - t_now.tv_usec; if(twait->tv_usec < 0) { twait->tv_usec += 1000000; twait->tv_sec--; } if (twait->tv_sec < 0) { twait->tv_sec = twait->tv_usec = 0; return 1; } return 0;} /* init_diag(): * * initialize diag request with valid defaults */ int init_diag() { /* the lite version of net_init returns a system selected * default address and port. We will receive the diagnostic * response here. */ net_init_udp_only(&diag_req.resp_to); Max_rsvp_msg = MAX_PKT ;/* allow conversion of addresses to names */ IP_NumOnly = 0;/* initialize the request info structure */ diag_req.path_mtu = DIAG_DEF_PATH_MTU; diag_req.max_hops = DIAG_DEF_MAX_HOPS; diag_req.H = DIAG_REPLY_DIRECT; diag_req.status = DIAG_NONE_RECVD; diag_req.rcount = 0; diag_req.curr_id = 0; diag_req.timeout = DIAG_DEF_TIMEOUT; /* Initialize the diag_req net_addr structures * the DREQ is sent to the Last_hop rsvp router's Pu port */ NET_SET_ADDR3_UDP_IPv4(&diag_req.last_hop, NET_GET_ADDR_UDP_IPv4(&diag_req.resp_to).sin_addr, hton16(RSVP_ENCAP_PORT)); NET_SET_ADDR3_UDP_IPv4(&diag_req.sender,inaddr_any,0); memset(&diag_req.rsvp_dsess,0,sizeof(SESSION_ipv4)); diag_req.rsvp_dsess.sess_protid = IPPROTO_UDP ; return 0;}/* Lifted directly from rsvp_api.c : * Macro used in api_prepare_xxxx to add an object to API packet and * to the map of the packet. The map address is 'var'; the object * has class (typedef) 'cls' and ctype (value) 'ctype'. * We use this macro while building the DREQ packet. */#define New_Object(var, cls, ctype) \ Init_Object(objp, cls, ctype); \ var = (cls *) objp; \ objp = Next_Object(objp);/* trace_prepare(): * * Allocate new packet buffer and new map. * (Use max message size; could compute actual size) XXX??? * Prepare an rsvp diagnostic request (DREQ) in the packet_map */int trace_prepare(struct packet *pkt) { common_header *hdrp; packet_map *mapp; int map_len = sizeof(packet_map); Object_header *objp; if ((hdrp = (common_header *) malloc(Max_rsvp_msg))==NULL || (mapp = (packet_map *) malloc(map_len))==NULL) { perror("Trace Prepare: "); return (-1); }/* offset may be set to 0. However in the future we may need this * so we harmlessly set it to this value */ pkt->pkt_offset = 0; pkt->pkt_map = mapp; pkt->pkt_data = hdrp; pkt->pkt_len = 0; pkt->pkt_flags = pkt->pkt_ttl = 0; pkt->pkt_order = BO_HOST; memset((char *)mapp, 0, sizeof(packet_map));/* Initialize RSVP objects needed in the packet with requested information, * in host byte order. */ memset((char *)pkt->pkt_data, 0, sizeof(common_header)); pkt->pkt_len = sizeof(common_header); mapp->rsvp_msgtype = pkt->pkt_data->rsvp_type = RSVP_DREQ; pkt->pkt_map->rsvp_resplist = 0; objp = (Object_header *)(pkt->pkt_data + 1);/* Fill the DIAGNOSTIC Object */ New_Object(mapp->rsvp_diag, DIAGNOSTIC, DIAGNOSTIC_ipv4);/* ID of the DREQ packet is set to 0. * This is actually in send_diag_request, just before sending. */ pkt->pkt_map->rsvp_diag->diag_msgID = 0; /* If the Last_hop was not specified, then this machine becomes the last hop. * If this machine is not running rsvpd, the packet will be dropped. */ pkt->pkt_map->rsvp_diag->diag_laddr = NET_GET_ADDR_UDP_IPv4(&diag_req.last_hop).sin_addr;/* Setup sender/port and response/port */ Init_Object(&mapp->rsvp_diag->diag_rfiltp, FILTER_SPEC, FILTER_SPEC_ipv4); pkt->pkt_map->rsvp_diag->diag_raddr = NET_GET_ADDR_UDP_IPv4(&diag_req.resp_to).sin_addr; pkt->pkt_map->rsvp_diag->diag_rport = NET_GET_ADDR_UDP_IPv4(&diag_req.resp_to).sin_port; Init_Object(&mapp->rsvp_diag->diag_sfiltp, FILTER_SPEC, FILTER_SPEC_ipv4); pkt->pkt_map->rsvp_diag->diag_saddr = NET_GET_ADDR_UDP_IPv4(&diag_req.sender).sin_addr; pkt->pkt_map->rsvp_diag->diag_sport = NET_GET_ADDR_UDP_IPv4(&diag_req.sender).sin_port;/* Read reply mode and set H bit */ pkt->pkt_map->rsvp_diag->diag_replymode |= diag_req.H << 1;/* other diagnostic header settings */ pkt->pkt_map->rsvp_diag->diag_hopcount = 0; pkt->pkt_map->rsvp_diag->diag_maxhops = diag_req.max_hops; pkt->pkt_map->rsvp_diag->diag_pMTU = diag_req.path_mtu; pkt->pkt_map->rsvp_diag->diag_frag_off = 0; pkt->pkt_len += sizeof(DIAGNOSTIC);/* Fill the SESSION object */ New_Object(mapp->rsvp_session, SESSION, SESSION_ipv4); pkt->rsvp_sess->sess4_addr = diag_req.rsvp_dsess.sess_destaddr; pkt->rsvp_sess->sess4_port = diag_req.rsvp_dsess.sess_destport; pkt->rsvp_sess->sess4_prot = diag_req.rsvp_dsess.sess_protid; pkt->rsvp_sess->sess4_flgs = SESSFLG_E_Police; pkt->pkt_len += sizeof(SESSION);/* Finish up common header. */ pkt->pkt_data->rsvp_cksum = 0; pkt->pkt_data->rsvp_length = pkt->pkt_len = (char *)objp - (char *) pkt->pkt_data; pkt->pkt_data->rsvp_snd_TTL = RSVP_TTL_MAX; return (0);}/* trace_accept_reply() * * Process received diagnostic reply (DREP). * Set status flag to indicate to dispatcher that there * are more replies. * Printout results. */int trace_accept_reply( struct packet *pkt, net_addr *fromp ) { struct timeval tm ; u_long t_const ; DIAG_RESPONSE *dresp; packet_map *mapp ; int c, dr_err; Object_header *op; char *end_of_dresp; mapp = pkt->pkt_map;/* If we already have some fragments pending, we ignore any * duplicate replies. */ if (diag_req.status == DIAG_SOME_RECVD && diag_req.curr_id != mapp->rsvp_diag->diag_msgID) return 1;/* Update the request status, so that the waiting routine gets * to know. Latch the message ID, if this is first reply ever. */ if (DIAG_MFBIT(mapp->rsvp_diag)) { if (diag_req.status != DIAG_SOME_RECVD) { diag_req.status = DIAG_SOME_RECVD; diag_req.curr_id = mapp->rsvp_diag->diag_msgID; } } else diag_req.status = DIAG_ALL_RECVD; printf("Reply from %s, %d hop(s), %d response(s)\n", iptoname(&(NET_GET_ADDR_UDP_IPv4(fromp).sin_addr)), mapp->rsvp_diag->diag_hopcount, mapp->rsvp_resplist); dresp = mapp->rsvp_diag_response; for (c = 0; c < mapp->rsvp_resplist; c++) { printf("\n%d) ",diag_req.rcount+c+1); /* this is to print the hop name along with * each response */ if(dresp->resp_in_addr.s_addr != INADDR_ANY) printf("%s ",iptoname(&dresp->resp_in_addr)); else if(dresp->resp_out_addr.s_addr != INADDR_ANY) printf("%s ",iptoname(&dresp->resp_out_addr)); else printf("%s ",iptoname(&(NET_GET_ADDR_UDP_IPv4(fromp).sin_addr))); dr_err = DIAG_RESPONSE_RERROR(dresp); if (dr_err) { switch(dr_err) { case RSVP_Erv_Diag_NOPATH : printf("PATH ?\n"); break ; case RSVP_Erv_Diag_MTUBIG : printf("MTU too big\n"); break ; case RSVP_Erv_Diag_ROUTEBIG : printf("ROUTE too big\n"); break ; default : printf("unknown err ??\n"); break ; } } if (!(dr_err & RSVP_Erv_Diag_NOPATH)) { t_const = get_time_constant(); tm.tv_sec = ((dresp->resp_arrtime >> 16) | t_const) - JAN_1970; tm.tv_usec = ((dresp->resp_arrtime & 0x0000FFFF) * 15625) >> 10; printf("[arr time: %s]\n",time_stamp(&tm)); if (dresp->resp_in_addr.s_addr != INADDR_ANY ) printf("[IN->%s", iptoname(&dresp->resp_in_addr)); else printf("[IN->local"); if (dresp->resp_out_addr.s_addr != INADDR_ANY) printf(", OI<-%s", iptoname(&dresp->resp_out_addr)); else printf(", OI<-local"); if (dresp->resp_pre_addr.s_addr != INADDR_ANY) { printf(", Phop->%s", iptoname(&dresp->resp_pre_addr)); } else printf(", Phop->N/A"); printf(", timer: %d, DTTL: %d]\n",dresp->resp_timeval, dresp->resp_DTTL); if (Obj_Length(dresp) > DRESP_BASIC_SIZE) { op = (Object_header *)((char *)dresp + DRESP_BASIC_SIZE); printf("%s",fmt_tspec((SENDER_TSPEC *)op)); op = Next_Object(op); } if (Obj_Length(dresp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC)) { printf(" %s",fmt_flowspec((FLOWSPEC *)op)); /*fmt_object(op, ctype_FLOWSPEC_Intserv0);*/ op = Next_Object(op); } if (Obj_Length(dresp) > DRESP_BASIC_SIZE + sizeof(SENDER_TSPEC) + sizeof(FILTER_SPEC)) { switch(dresp->resp_rstyle) { case STYLE_WF: printf(" WF"); break ; case STYLE_FF: printf(" FF"); break ; case STYLE_SE: printf(" SE"); break ; default : printf("Style ??"); } if (DIAG_RESPONSE_MFLAG(dresp)) printf(", M"); end_of_dresp = (char *)dresp + Obj_Length(dresp); while ((char *)op < end_of_dresp) { printf("\n{%s}",fmt_filtspec((FILTER_SPEC *)op)); /*fmt_object(op,ctype_FILTER_SPEC_ipv4);*/ op = Next_Object(op); } } (char *)dresp += Obj_Length(dresp); } printf("\n"); } diag_req.rcount += mapp->rsvp_resplist; return 0;}/* do_sendmsg() : * * Stub for sending generic rsvp packets without the extra machinery * of the same functions in rsvp_main.c (a lot of #ifdefs are needed!) * vif is a dummy parameter. */ int do_sendmsg( int vif, net_addr *to, net_addr *src, int flags, u_char ttl, u_char *data, int len) { return(net_send(to,src,data,len,NULL,ttl,FALSE));}/* get_time_constant() : * * Used for getting the constant part of the ntp time stamp. * The diag object contains the 64k differential only. * We recompute the MSB 16bits of the original 32bit NTP * time stamp which will be constant for all time sync'ed hosts, * within the 64k second range. */u_long get_time_constant() { struct timeval tm ; gettimeofday(&tm,0); tm.tv_sec += JAN_1970 ; return (tm.tv_sec & 0xFFFF0000) ;}char *time_stamp(struct timeval *tv) { struct tm tmv; static char buff[16]; memcpy(&tmv, localtime((time_t *) &tv->tv_sec), sizeof(struct tm)); sprintf(buff, "%02d:%02d:%02d.%03d", tmv.tm_hour, tmv.tm_min, tmv.tm_sec, (int)tv->tv_usec/1000); return(buff);}u_long resolve_name(name)char *name;{ net_addr addr; if (!net_addr_ascii(&addr,name)) return(INADDR_ANY); if (NET_GET_TYPE(&addr) != NET_ADDR_IPv4) return(INADDR_ANY); return(NET_GET_ADDR_IPv4(&addr).s_addr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -