#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rtest.h" #include "rsvp.h" #include "rapi_lib.h" #include "rapi_err.h" /* *Globals */ #define MAX(a,b) (((a)>(b))?(a):(b)) int rerrno, label_flag,lsp_tunnel; int Pm_vi, Pm_val; char RouteHeader[] = "\ Route Entry: Flag IP-Addr(x.x.x.x) Prefix (0-Strict) (1-Loose) ---------------------------------------------------------------------------\n"; char RouteFormat[] = "%d %s %d\n"; /* * creates a new EXROUTE Object witch specified number of slots */ EXROUTE * new_exroute_obj(int count,u_char ctype) { int size; EXROUTE *exp; switch(ctype) { case ctype_EX_ROUTE_IPv4: size = sizeof(EX_ROUTE_IPv4); break; #ifdef USE_IPV6 /* case ctype_EXROUTE_ipv6: size = sizeof(EX_ROUTE_IPv6); break; */ #endif /* USE_IPV6 */ default: return(NULL); } size = count * size + sizeof(Object_header); exp = (EXROUTE *)malloc(size); assert(exp); Obj_Length(exp) = size; Obj_Class(exp) = class_EXROUTE_DATA; Obj_CType(exp) = ctype; return(exp); } #define EXROUTE_LEN 10 #define MAX_SCOPE_LEN 65536 void exroute_cat(EXROUTE ** exppp, EX_ROUTE_IPv4 * ex_route) { int N, L, ctype, addrsize; char *cp,*end,*addr; EXROUTE *expp, *new_expp; ctype = ctype_EX_ROUTE_IPv4; addrsize = 8; addr = (char *)ex_route; expp = *exppp; if (!expp) { /* First time... set up object * We use the object length field to keep track of * the number of entries at present. The size of * malloc'd area is nearest power of 2 that is >= * this len, but at least INIT_SCOPE_LEN. */ expp = new_exroute_obj(EXROUTE_LEN, ctype); if (!expp) return; Obj_Length(expp) = sizeof(Object_header); } else { if (Obj_CType(expp) != ctype) return; /* Ignore a duplicate ip addr in list. */ end = ((char *) expp) + Obj_Length(expp); for (cp = (char *) Obj_data(expp);cp < end; cp += addrsize) if (memcmp(cp,addr,addrsize) == 0) return; } /* Compute size of existing area */ L = Obj_Length(expp); for (N = EXROUTE_LEN; N < MAX_SCOPE_LEN; N <<= 1) if (N >= L) break; if (L + addrsize > N) { /* Overflow. Malloc a new object area of double size, * copy into it, and free original one. */ new_expp = (EXROUTE *) malloc(N+N); if (!new_expp) { /* XXX ?? */ return; } memset(new_expp, 0, N+N); memcpy(new_expp, expp, L); free(expp); expp = new_expp; } memcpy(((char *) expp) + Obj_Length(expp),addr,addrsize); Obj_Length(expp) += addrsize; *exppp = expp; } /**************Resolve_Name ******************************************/ u_long resolve_name( namep , i) char *namep; int i; { struct hostent *hp ; if (isdigit(*namep)) return(ntohl((u_long) inet_network(namep))); else if (NULL == (hp = gethostbyname( namep ))) return(0) ; return( *( u_long *) hp->h_addr) ; } /**************Set_Route_list *****************************************/ EXROUTE * set_route_list(EXROUTE* rlistp, int i, routepara* nexthop) { EX_ROUTE_IPv4 *ex_routep; u_int32_t temp_ipaddr; ex_routep = malloc(sizeof(EX_ROUTE_IPv4)); if (nexthop != NULL){ if (nexthop[i].flag == 0) ex_routep->l= 0; else ex_routep->l= 1; ex_routep->type = EXROUTE_IPv4_PREFIX; ex_routep->length = 8; //ex_routep->ipv4_addr = resolve_name(nexthop[i].addr, nexthop[i].prefix); temp_ipaddr = resolve_name(nexthop[i].addr, nexthop[i].prefix); ex_routep->ipv4_addr1 = temp_ipaddr & 0xffff; ex_routep->ipv4_addr2 = (temp_ipaddr >> 16) & 0xffff; ex_routep->rprefix = nexthop[i].prefix; ex_routep->padd = 0; exroute_cat(&rlistp, ex_routep); free(ex_routep); } return rlistp; } EXROUTE* init() { int i, n; routepara *rpointer; EXROUTE *snd_rlist; system("clear"); printf("**********************************************************************\n"); printf("* *\n"); printf("* RTEST creates a RSVP-Path message including an *\n"); printf("* explicit routing object !! *\n"); printf("* *\n"); printf("**********************************************************************\n"); printf("\n\n"); printf(" Should PATH-message include a label-request-object (0-No, 1-Yes) "); scanf("%d" ,&label_flag); printf("\n"); printf(" Should This Session be set up as a LSP Tunnel (0-No, 1-Yes) "); scanf("%d" ,&lsp_tunnel); printf("\n"); printf(" Specify the number of route entities (max. 10): "); scanf("%d",&n); printf("\n"); snd_rlist = NULL; if (n == 0){ return snd_rlist; } rpointer = malloc(sizeof(routepara)*n); for (i = 0; i < n; i++){ printf(RouteHeader); /* scanf(" %d", &rpointer[i].flag); scanf(" %s", &rpointer[i].addr); scanf(" %d", &rpointer[i].prefix); */ printf(" "); scanf("\t %d %s %d",&rpointer[i].flag,rpointer[i].addr,&rpointer[i].prefix); printf("\n"); snd_rlist = set_route_list(snd_rlist, i, rpointer); } printf(" ---------------------------------------------------------------------------\n\n"); return snd_rlist; } /* *Forward & External Declarations char *fmt_filterspec(rapi_filter_t *); */ /**************Set_TSPEC *****************************************/ int set_tspec(rapi_tspec_t* tspecp, int bucket_rate, int bucket_size, int peakrate, int min_policed_unit, int max_packet_size) { qos_tspecx_t *tbody = &tspecp->tspecbody_qosx; tbody->spec_type = QOS_CNTR_LOAD; /* only CL is supported at the moment */ tbody->xtspec_r = bucket_rate; tbody->xtspec_b = bucket_size; tbody->xtspec_p = peakrate; tbody->xtspec_m = min_policed_unit; tbody->xtspec_M = max_packet_size; tspecp->form = RAPI_TSPECTYPE_Simplified; tspecp->len = sizeof(rapi_hdr_t) + sizeof(qos_tspecx_t); return 0; } /**************Set_FLSPEC *****************************************/ int set_flspec(rapi_flowspec_t* flspecp, int bucket_rate, int bucket_size, int peakrate, int min_policed_unit, int max_packet_size) { qos_flowspecx_t *flbody = &flspecp->specbody_qosx; flbody->spec_type = QOS_CNTR_LOAD; /* only CL is supported at the moment */ flbody->xspec_r = bucket_rate; flbody->xspec_b = bucket_size; flbody->xspec_p = peakrate; flbody->xspec_m = min_policed_unit; flbody->xspec_M = max_packet_size; flspecp->form = RAPI_FLOWSTYPE_Simplified; flspecp->len = sizeof(rapi_flowspec_t); return 0; } /**************Get_Filter*****************************************/ int get_sockaddr(voff, sinp) int voff; struct sockaddr_in *sinp; { memset(sinp, 0, sizeof(struct sockaddr_in)); sinp->sin_family = AF_INET; #if BSD > 199103 sinp->sin_len = sizeof(struct sockaddr_in); #endif Pm_val = 1; sinp->sin_addr.s_addr = INADDR_ANY; if (Pm_vi > voff+1) sinp->sin_port = hton16((u_short)Pm_val); else sinp->sin_port = 0; return(0); } void saddr_to_rapi_filt( struct sockaddr_in *host, rapi_filter_t* p) { p->len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_base_t); p->form = RAPI_FILTERFORM_BASE; p->filt_u.base.sender = *host; } int get_filter(int voff, rapi_filter_t* Tfilt, int size) { struct sockaddr_in sin; get_sockaddr(voff, &sin); saddr_to_rapi_filt(&sin, Tfilt); Pm_vi = voff; return (0); } char * fmt_filterspec(rapi_filter_t *rfiltp) { static char FIbuff[256]; rapi_fmt_filtspec(rfiltp, FIbuff, 256); return(FIbuff); } /**************Async_Handler**************************************/ int asynch_handler( rapi_sid_t sid, rapi_eventinfo_t event, int styleid, int errcode, int errval, struct sockaddr_in errnode, u_char errflags, int filt_num, rapi_filter_t *filt_list, int flow_num, rapi_flowspec_t *flow_list, int adspec_num, rapi_adspec_t *adspec_list, void *myparm) { rapi_filter_t *filtp = filt_list; rapi_flowspec_t *flowp = flow_list; rapi_adspec_t *adsp = adspec_list; int isPath = 1; char buff[128], out1[80]; int T, i; extern char *rapi_rstyle_names[]; /*for (T=0 ; T < MAX_T; T++) Map sid into thread# T if (Sid[T] == sid) break; */ T = 0; /*sprintf(out1, " Session= %.32s:%d", inet_ntoa(dest.sin_addr), ntoh16(dest.sin_port));*/ printf( "---------------------------------------------------------------\n"); switch (event) { case RAPI_PATH_EVENT: printf("T%d: Path Event -- %s\n", T, out1); break; case RAPI_RESV_EVENT: printf("T%d: Resv Event -- %s\n", T, out1); isPath = 0; break; case RAPI_RESV_ERROR: isPath = 0; printf("T%d: sid=%d %s -- RSVP error: %s\n", T, sid, out1, out1); break; case RAPI_PATH_ERROR: printf("T%d: sid=%d %s -- RSVP error: %s\n", T, sid, out1, (errcode==RSVP_Err_API_ERROR)? rapi_errlist[errval]: rsvp_errlist[errcode]); if (event == RAPI_RESV_ERROR) printf(" Style=%s", rapi_rstyle_names[styleid]); printf(" Code=%d Val=%d Node= %s", errcode, errval, inet_ntoa(errnode.sin_addr)); if (errflags&RAPI_ERRF_InPlace) printf(" *InPlace*"); if (errflags&RAPI_ERRF_NotGuilty) printf(" *NotGuilt*"); printf("\n"); break; case RAPI_RESV_STATUS: isPath = 0; printf("T%d: Resv State -- %s:\n", T, out1); break; case RAPI_PATH_STATUS: printf("T%d: Path Stat -- %s:\n", T, out1); break; case RAPI_RESV_CONFIRM: printf("T%d: Confirm Event -- %s:\n", T, out1); break; default: printf("!!?\n"); break; } for (i = 0; i < MAX(filt_num, flow_num); i++) { if (i < filt_num) { printf("\t%s", fmt_filterspec(filtp)); filtp = (rapi_filter_t *)After_RAPIObj(filtp); } else printf("\t\t"); if (i < flow_num) { if (isPath) rapi_fmt_tspec((rapi_tspec_t *)flowp, buff, sizeof(buff)); else rapi_fmt_flowspec(flowp, buff, sizeof(buff)); printf("\t%s\n", buff); flowp = (rapi_flowspec_t *)After_RAPIObj(flowp); } else printf("\n"); if (i < adspec_num) { rapi_fmt_adspec(adsp, buff, sizeof(buff)); printf("\t\t%s\n", buff); adsp = (rapi_adspec_t *)After_RAPIObj(adsp); } } printf( "---------------------------------------------------------------\n"); fflush(stdout); return 0; } /****************** path message ***********************************/ int main(int argc,char* argv[]){ int sd = 0, fd = 0; int rc = 0, n; short int dport, sport; long int rate, depth, peak; rapi_tspec_t snd_tspec; #ifdef EX_ROUTE EXROUTE *snd_rlist; #endif struct sockaddr_in source, target; struct hostent *sp, *dp, *rp; char hname[100]; rapi_filter_t snd_template; if(argc < 4) { printf("You have to assign source/dest address and port !!!!\n"); return 0; } rate = 90000; depth =100000; peak = 100000; dport = atoi(argv[2]); sport = atoi(argv[4]); dp = malloc(sizeof(struct hostent)); rp = malloc(sizeof(struct hostent)); sp = malloc(sizeof(struct hostent)); snd_rlist = init(); printf(" Path Message to: %s, Port: %d \n\n", argv[1], dport); target.sin_addr.s_addr = resolve_name(argv[1]); target.sin_family = AF_INET; target.sin_port = htons(dport); /***** Festlegen der Rapi-Session ***************/ if((sd = rapi_session((struct sockaddr*)&target, 17 /*UDP*/, (lsp_tunnel)?RAPI_LSP_SESSION:0, (rapi_event_rtn_t) asynch_handler, 0, &rerrno))==0){ perror("can't open rapisession"); return -1; } /* debugging code */ fd = rapi_getfd(sd); printf(" Rapi_Session: session id=%d ,fd=%d\n\n",sd, fd ); rc = rapi_dispatch(); /* TSpec setting */ /* fixed values for peak rate, min pol unit and max pkt size ! */ set_tspec(&snd_tspec, rate, depth, peak, 512, 1500); /* setting the source of the path message */ if( argc == 5) source.sin_addr.s_addr = resolve_name(argv[3]); else { gethostname(hname, sizeof(hname)); sp = gethostbyname(hname); printf(" Sending Host: %s\n\n", sp->h_name); bcopy((char*)sp->h_addr, (char*)&source.sin_addr, sp->h_length); } source.sin_family = AF_INET; source.sin_port = htons(sport); /* setting the sender template */ if(lsp_tunnel) { bcopy((char*)&source.sin_addr, (char*)&snd_template.rapi_filtlspv4_addr, sizeof(u_int32_t)); snd_template.rapi_filtlspv4_zero = 0; snd_template.rapi_filtlspv4_lspid = ntoh16(sport); snd_template.form = RAPI_FILTERFORM_LSPv4; snd_template.len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_lspv4_t); } else { bcopy((char*)&source.sin_addr, (char*)&snd_template.rapi_filtbase4_addr, sizeof(u_int32_t)); snd_template.rapi_filtbase4_port = source.sin_port; snd_template.form = RAPI_FILTERFORM_BASE; snd_template.len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_base_t); } /* rapi_sender */ if((n = rapi_sender(sd, 0, (struct sockaddr*)&source, snd_rlist, (label_flag)?&snd_template:NULL, &snd_tspec, NULL, NULL, 10, label_flag)) != 0){ perror("rapi_sender error"); return -1; } while (1) { sleep(1000); } return sd; }