#include #include #include #include #include #include #include #include #include #include #include #include #include "../rsvpd/rapi_err.h" #include "../rsvpd/rsvp.h" #include "../rsvpd/rapi_lib.h" /* *Globals */ #define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX_T 64 #define MAX_NFLWDS 64 #define Area_Data(cast, p) (cast ((p)? (rapi_hdr_t *) (p)+1: NULL)) #define NO_MODE 0 #define S_MODE 0x01 /* Send only */ #define R_MODE 0x02 /* Receive only */ #define RS_MODE S_MODE+R_MODE /* Send/Receive */ typedef struct { short area_size; /* total size of area */ short area_offset; /* Offset of next available space in area */ int area_cnt; /* Number of objects in area */ } area_t; int sid, resv, nspec, c, sender, Mode, ttl; int rerrno, Pm_vi, Pm_val; int resv_flags; int udpsock; int sid, ttl; area_t *snd_flowspec; area_t *snd_template; area_t *Flowspecs; area_t *Filter_specs; int event_gl; rapi_flowspec_t *flow_gl; struct sockaddr_in source, dest, rcvr; /* *Forward & External Declarations */ char *fmt_filterspec(rapi_filter_t *); /*************Get_Localhost **************************************/ get_localhost(char *hname,u_short pbase) { struct hostent *hp; hp = gethostbyname(hname); //printf("Sending Host: %s\n", hp->h_name); bcopy((char*)hp->h_addr, (char*)&dest.sin_addr, hp->h_length); dest.sin_family = hp->h_addrtype; dest.sin_port = pbase; return 0; } /*************Get_Remotehost **************************************/ get_remotehost(char *hname, u_short pbase) { struct hostent *hp; hp = gethostbyname(hname); //printf("Receiving Host: %s\n", hp->h_name); bcopy((char*)hp->h_addr, (char*)&source.sin_addr, hp->h_length); source.sin_family = hp->h_addrtype; source.sin_port = pbase; return 0; } /**************Cat_Area ******************************************/ area_t * init_Area(area_t **app, int size) { area_t *ap = *app; if (ap == NULL) { size += sizeof(area_t); if (size <= 0 || (ap = (area_t *) malloc(size)) == NULL) return(NULL); *app = ap; ap->area_size = size; } ap->area_offset = sizeof(area_t); ap->area_cnt = 0; return(ap); } char * Area_offset(area_t *ap) { return((char *) ap + ap->area_offset); } Cat_Area(area_t *orig, rapi_hdr_t *objp) { if (orig->area_offset + objp->len > orig->area_size) { //printf("!!Area overflow\n"); return; } memcpy((rapi_hdr_t *)Area_offset(orig), objp, objp->len); orig->area_offset += objp->len; orig->area_cnt++; } /* * Construct RAPI flowspec object from value list: * voff+: 0=type * type = g|p: 1=r, 2=b, [3=d, [4=dl]] * type = cl: 1=r, 2=b, [3=m, [4=M]] * type = gx: 1=R, 2=S, 3=r, 4=b, [5=p, [6=m, [7=M]]] */ int get_flowspec(int voff, area_t **areapp, int size, int rate, int bucket, int type) { rapi_flowspec_t Tflow, *flowsp = &Tflow; qos_flowspecx_t *csxp = &flowsp->specbody_qosx; switch (type) { case QOS_CNTR_LOAD: csxp->spec_type = type; csxp->xspec_r = rate; csxp->xspec_b = bucket; csxp->xspec_p = 100000000; csxp->xspec_m = 0; csxp->xspec_M = 65535; flowsp->form = RAPI_FLOWSTYPE_Simplified; break; case QOS_GUARANTEEDX: csxp->spec_type = type; csxp->xspec_R = rate; csxp->xspec_S = bucket; csxp->xspec_r = rate; csxp->xspec_b = bucket; csxp->xspec_p = 100000000; csxp->xspec_m = 0; csxp->xspec_M = 65535; flowsp->form = RAPI_FLOWSTYPE_Simplified; break; default: //printf("Unknown flowspec type\n"); return(-1); } flowsp->len = sizeof(rapi_flowspec_t); Cat_Area(*areapp, (rapi_hdr_t *) flowsp); 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 sinp->sin_addr.s_addr = source.sin_addr.s_addr; sinp->sin_port = source.sin_port; return(0); } void saddr_to_rapi_filt( struct sockaddr_in *host, rapi_filter_t *p) { p->len = sizeof(rapi_hdr_t) + sizeof(rapi_filter_lspv4_t); p->form = RAPI_FILTERFORM_LSPv4; p->rapi_filtlspv4 = *(struct sockaddr_in *)host; p->rapi_filtlspv4_zero = 0; p->rapi_filtlspv4_lspid = host->sin_port; } int get_filter(int voff, area_t **areap, int size) { struct sockaddr_in sin; rapi_filter_t Tfilt; get_sockaddr(voff, &sin); saddr_to_rapi_filt(&sin, &Tfilt); Cat_Area(*areap, (rapi_hdr_t *) &Tfilt); Pm_vi = voff; return (0); } /**************Get_TSPEC *****************************************/ int get_tspec(int voff, area_t **areapp, int size) { rapi_tspec_t Tspec, *tspecp = &Tspec; qos_tspecx_t *ctxp = &tspecp->tspecbody_qosx; /*int type = Pm_val[voff];*/ ctxp->spec_type = QOS_CNTR_LOAD; ctxp->xtspec_r = 500000; ctxp->xtspec_b = 500000; ctxp->xtspec_p = 100000000; /* Eigentlich INFINITY32f */ ctxp->xtspec_m = 0; ctxp->xtspec_M = 65535; tspecp->form = RAPI_TSPECTYPE_Simplified; tspecp->len = sizeof(rapi_hdr_t) + sizeof(qos_tspecx_t); Cat_Area(*areapp, (rapi_hdr_t *) tspecp); return(0); } /*************fmt_filterspec ************************************/ char * fmt_filterspec(rapi_filter_t *rfiltp) { static char FIbuff[256]; struct sockaddr_in *sinp; FIbuff[0] = '\0'; if (!rfiltp) return(FIbuff); switch (rfiltp->form) { case RAPI_FILTERFORM_BASE: break; case RAPI_FILTERFORM_LSPv4: sinp = &rfiltp->rapi_filtlspv4; sprintf(FIbuff, "%s:%d", inet_ntoa(sinp->sin_addr), ntoh16(sinp->sin_port)); return(FIbuff); break; case RAPI_EMPTY_OTYPE: return(FIbuff); default: sprintf(FIbuff, "Filtspec Type %d ??", rfiltp->form); return(FIbuff); } sinp = &rfiltp->rapi_filt4; if (sinp->sin_family != AF_INET) { sprintf(FIbuff, "Non-IP Filtspec Type %d Prot %d ??", rfiltp->form, sinp->sin_family); return(FIbuff); } if (sinp->sin_addr.s_addr == INADDR_ANY) { if (sinp->sin_port == 0) sprintf(FIbuff, " *:*"); else sprintf(FIbuff, " *:%d", ntoh16(sinp->sin_port)); } else sprintf(FIbuff, "%s:%d", inet_ntoa(sinp->sin_addr), ntoh16(sinp->sin_port)); return(FIbuff); } /**************Print_Status***************************************/ void print_errno(char *cp, int rapi_errno) { //printf("RAPI: %s err %d : %s\n", cp, rapi_errno, // rapi_errlist[rapi_errno]); } /**************Set_Receiver***************************************/ void Set_Recv(dstp, srcp) struct sockaddr_in *dstp; struct sockaddr_in *srcp; { struct ip_mreq mreq; if (!IN_MULTICAST(ntoh32(dstp->sin_addr.s_addr))) return; mreq.imr_multiaddr = dstp->sin_addr; mreq.imr_interface = srcp->sin_addr; /* if (0 > setsockopt(udpsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq))) { perror("Can't join multicast group"); return; } */ //printf("Joined multicast group %s\n", inet_ntoa(dstp->sin_addr)); } /**************Async_Handler**************************************/ int asynch_handler( rapi_sid_t sid, rapi_eventinfo_t event, int styleid, int errcode, int errval, struct sockaddr *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); /*event_gl = event;*/ 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 -- RSVP error: %s\n", // T, sid, 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); /*flow_gl = 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; } /*************Beginn der Main Function ****************************************/ int main(int argc,char* argv[]){ int rtap_fd=0; int resv_flags,rc; int rate, bucket, type; struct hostent *hp, *hp2; rapi_filter_t Fflow, *filtsp = &Fflow; rapi_event_rtn_t *event1; fd_set fds, t_fds; FILE *infp, *fp; struct timeval *intvp, timenow; u_short portsrc , portdest; pid_t pid; pid = getpid(); if((fp = fopen("/var/tmp/rapipid", "r+"))==NULL) { printf("Could not open file\n"); return -1; } fprintf(fp, "%d\n", pid); fclose(fp); Filter_specs = NULL; Flowspecs = NULL; snd_template = NULL; snd_flowspec = NULL; sid = ttl = 0; Mode = NO_MODE; resv_flags = 0; udpsock = -1; memset(&dest, 0, sizeof(struct sockaddr_in)); memset(&source, 0, sizeof(struct sockaddr_in)); portsrc = htons((u_short) atoi(argv[2])); portdest = htons((u_short) atoi(argv[4])); get_localhost(argv[1], portsrc); get_remotehost(argv[3], portdest); type = QOS_CNTR_LOAD; /* type = atoi(argv[4]); */ rate = atoi(argv[5]); bucket = atoi(argv[6]); filtsp->len = sizeof(filtsp); filtsp->form = RAPI_FILTERFORM_LSPv4; filtsp->rapi_filtlspv4 = dest; /***** Festlegen der Rapi-Session ***************/ sid = rapi_session((struct sockaddr *)&dest, 17, RAPI_LSP_SESSION, (rapi_event_rtn_t) asynch_handler, 0, &rerrno); rtap_fd = rapi_getfd(sid); //printf("Rapi_Session: sid=%d ,fd=%d\n",sid,rtap_fd ); //fprintf(stderr,"%d \n",rerrno ); /***** Aufbau einer Reservation-Message *********/ /***** falls PATH Message vom Sender *********/ memset(&rcvr, 0, sizeof(struct sockaddr_in)); Set_Recv(&dest, &rcvr); init_Area((area_t **)&Filter_specs, MAX_NFLWDS*sizeof(rapi_filter_t)); init_Area((area_t **)&Flowspecs, MAX_NFLWDS*sizeof(rapi_flowspec_t)); Set_Recv(&dest,&rcvr); get_filter(1, &Filter_specs, sizeof(rapi_filter_t)); get_flowspec(1, &Flowspecs, sizeof(rapi_filter_t), rate, bucket,type); resv = rapi_reserve(sid, 0, (struct sockaddr *)&dest, RAPI_RSTYLE_FIXED, NULL, NULL, Filter_specs->area_cnt, Area_Data((rapi_filter_t *), Filter_specs), Flowspecs->area_cnt, Area_Data((rapi_flowspec_t *), Flowspecs)); Mode |= R_MODE; //printf("rapi_reserve(): %d\n", resv); /***** Select Funktion fuer Asynch_handler ****/ infp = stdin; fflush(stdout); FD_ZERO(&t_fds); while (1) { /*memcpy(&t_fds, &fds, FD_SETSIZE);*/ /*FD_SET(fileno(infp), &t_fds);*/ if (rtap_fd > 0) FD_SET(rtap_fd, &t_fds); intvp = NULL; rc = select(FD_SETSIZE, &t_fds, NULL, NULL, intvp); if (rc < 0) { if (errno != EINTR) { perror("select"); exit(1); } continue; } gettimeofday(&timenow, NULL); if (rtap_fd>0 && FD_ISSET(rtap_fd, &t_fds)) { rc = rapi_dispatch(); if (rc < 0) { rtap_fd = 0; /* XXX print error */ } continue; } } rapi_release(sid); }