/* * rtap -- RealTime Application Program: Test program for RSVP * * rtap_cmds.c: Body of program * * * This file contains the common elements are rtap that are needed * when rtap is either integral with rsvpd or a separate process. * Thus, it includes command parsing, command execution, and the * RSVP API rapi_xxx interface calls. * * Separate process: rtap = rtap_main.c + rtap_cmds.c * * Integral with rsvpd: rtap = rsvp_rtap.c + rtap_cmds.c + * * * Written by Bob Braden, ISI */ /******************************************************************* Copyright (c) 1998 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 "config.h" /* must come first */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsvp_socks.h" #include "rsvp_trans.h" #include "rsvp.h" #include "rapi_lib.h" #include "rapi_err.h" #include "rsvp_mac.h" #include "rsvp_api.h" /* To include management interface */ #ifdef INCLUDE_SYSTEM_H #include "system.h" int printf(), strcasecmp(); #endif #include "Pm_parse.h" #define show_help(op) printf(cmd_table[op].cmd_help) #define RAPI_OBJLEN(objp) ( (*(int *) objp)? *(int *)objp : sizeof(int)) /* Define standard header for an area to hold vector of variable-length * flowspecs, filterspecs, etc. */ 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; area_t *init_Area(area_t **, int size); void free_Area(area_t **); char *Area_offset(area_t *); void Cat_Area(area_t *orig, rapi_hdr_t *new); #define Area_Data(cast, p) (cast ((p)? (rapi_hdr_t *) (p)+1: NULL)) /* * Forward & External Declarations */ void rtap_sleep(int), rtap_sleepdone(); void rapi_fmt_flowspec(rapi_flowspec_t *, char *, int); void rapi_fmt_tspec(rapi_tspec_t *, char *, int); void rapi_fmt_adspec(rapi_adspec_t *, char *, int); void rapi_fmt_filtspec(rapi_filter_t *, char *, int); void Send_data(void); int Do_Command(char *, FILE *); void saddr_to_rapi_filt(struct sockaddr *, rapi_filter_t *); int pfxcmp(char *, char *); void print_errno(char *, int); void print_status(void); void Set_Recv(struct sockaddr *, struct sockaddr *); void Set_Send(struct sockaddr *, struct sockaddr *, int); int next_word(char **, char *); int get_sockaddr(int, struct sockaddr *); int get_flowspec(int, area_t **, int); int get_tspec(int, area_t **, int); int get_filter(int, area_t **, int); char *fmt_filterspec(rapi_filter_t *); char *rsvp_timestamp(); int asynch_handler(rapi_sid_t, rapi_eventinfo_t, int, int, int, struct sockaddr *, u_char, int, rapi_filter_t *, int, rapi_flowspec_t *, int, rapi_adspec_t *, void *); int Do_rsvp_cmd(int, int); rapi_sid_t rapi_rsvp_cmd(rapi_cmd_t *, int *); int Get_Socket(struct sockaddr *); int tolower(int); void rtap_hexmsg(int, int, net_addr *, u_char *, int); int get_GPIfilter(int, area_t **, int); void set_adspec_p(int, int, int, int); static void Set_INADDR_ANY(net_addr *,struct sockaddr *); void dump_rsvp_stats(); #if defined LABEL int get_LSPfilter(int, area_t **, int); #endif /* * Globals */ #define MAX_NFLWDS 64 #define MAX_T 64 int T = 1; /* Current Thread number */ area_t *Filter_specs[MAX_T]; area_t *Flowspecs[MAX_T]; area_t *snd_template[MAX_T]; area_t *snd_tspec[MAX_T]; area_t *snd_adspec[MAX_T]; rapi_sid_t Sid[MAX_T]; int ttl[MAX_T]; rapi_styleid_t Style[MAX_T]; struct SOCKADDR dest[MAX_T]; struct SOCKADDR src[MAX_T]; struct SOCKADDR rcvr[MAX_T]; int Mode[MAX_T]; #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 */ #define GPI_MODE 0x10 #if defined LABEL #define LSP_MODE 0x20 #endif int protid[MAX_T]; int resv_flags[MAX_T]; /* reservation flags */ int udpsock[MAX_T]; /* Data socket */ static rapi_adspec_t Adspec; extern int rtap_fd; /* Unix socket to rsvpd */ #if defined LABEL extern int cbqfd; #endif #ifdef DATA struct timeval timeout, nexttime; struct timeval Default_interval = {1, 0}; /* Default is 1 per second */ #define MAXDATA_SIZE 1500 #define DEFAULTDATA_SIZE 512 char data_buff[MAXDATA_SIZE]; int data_size[MAX_T] = 0; /* size of data packet to send */ long send_data_bytes[MAX_T] = 0; long send_data_msgs = 0; long recv_data_bytes = 0; long recv_data_msgs = 0; #endif #define MAX_PACKET 1024 u_char packet_buff[MAX_PACKET]; int packet_size; /* For accumulating hexmsg */ #undef FD_SETSIZE #define FD_SETSIZE 32 #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif enum op_codes { /* order must be same as entries cmd_table[].cmd_op below!! */ OP_HELP = 1, OP_QUIT, OP_DEST, OP_SESS, OP_SENDER, OP_RESV, OP_CLOSE, OP_STATUS, OP_DATA, OP_RECV, OP_TTL, OP_CONFIRM, OP_TEMPLATE, OP_AUTH, OP_ASYNC, OP_SLEEP, OP_DLEVEL, OP_DMASK, OP_MEMORY, OP_HEXMSG, OP_ECHO, OP_BUG, OP_NULL, OP_proto, OP_hostport, OP_hp1, OP_hp2, OP_tspec, OP_wf, OP_ff, OP_se, OP_flowspec, OP_filter, OP_adspec,OP_Gadspec, OP_CLadspec, OP_breakbit, OP_hops, OP_BW, OP_minlat, OP_MTU, OP_genparm, OP_Gadparms, OP_Clparms }; /* Following table MUST match enum order of op_codes ! */ struct cmds { char *cmd_verb; int cmd_op; char *cmd_help; } cmd_table[] = { { "?", OP_HELP, "Commands are:\n" }, { "help", OP_HELP, " help | ?\n" }, { "quit", OP_QUIT, " quit\n" }, { "T", OP_HELP, " T <#> | T+ | T- \n" }, #if defined LABEL { "dest", OP_SESS, " dest [gpi] [intserv] [lsp] [/|]\n" }, #else { "dest", OP_SESS, " dest [gpi] [intserv] [/]\n" }, #endif { "session", OP_SESS, " session (same as 'dest')\n" }, { "sender", OP_SENDER, "\ sender [/] []\n" }, { "reserve", OP_RESV, "\ reserve [recv addr] wf [*] |\n\ reserve [rcv addr] ff [ ] ... |\n\ reserve [rcv addr] se [ ...] \n" }, { "close", OP_CLOSE, " close\n" }, { "status", OP_STATUS, " status\n" }, { "data", OP_DATA, " data [<# per sec> []]\n" }, { "receive", OP_RECV, " receive [recv host]\n" }, { "ttl", OP_TTL, " ttl \n" }, { "confirm", OP_CONFIRM, " confirm (Req confirmation)\n" }, { "template", OP_TEMPLATE, " (Not supported)\n"} , #ifdef ISI_TEST /**** auth: experimental subset of policy, incomplete { "auth", OP_AUTH, " auth \n" }, ****/ #endif { "async", OP_ASYNC, " async\n" }, { "sleep", OP_SLEEP, " sleep \n" }, { "dlevel", OP_DLEVEL, " dlevel \n" }, { "dmask", OP_DMASK, " dmask \n" }, #ifdef ISI_TEST { "memory", OP_MEMORY, " memory (=>mallocmap)\n"}, #endif { "hexmsg", OP_HEXMSG, " hexmsg [vif] x\n"}, { "echo", OP_ECHO, " echo \n\n" }, { "bug", OP_BUG, " bug (Toggles on/off)\n" }, { "", OP_NULL, "" } /* MUST BE LAST IN CMD TABLE */ }; char *Other_help = "\ Notes:\n\ Commands 'template' and 'ttl' are optional.\n\ Any command may be preceded by 'T'\n\ \n\ ::= 'tcp' | 'udp' | 'proto' \n\ \n\ ::= \n\ '[' 'g' [ ] ']' |\n\ '[' 'cl' [ ] ']' |\n\ \n\ ::= \n\ '[' 't' [ ] ']'\n\ \n\ ::= \n\ '(' ['br!'] \n\ [ ',' 'G=' '{' ['br!'] [] [] [] [] \n\ [ 'hop'] [ 'bw'] [ 'us'] [ 'mtu'] '}' ] \n\ [ ',' 'CL=' '{' ['br!'] \n\ [ 'hop'] [ 'bw'] [ 'us'] [ 'mtu'] '}' ] \n\ \n\ ::= /\n\ \n\ ::= 'path'|'resv'|'ptear'|'rtear'|'perr'|'rerr'|'confirm'\n\n"; enum { Ahelp = 1, Aotherhelp, Attl, Aunsupported, Asession, Asender, Atspec, Aconfirm, Asleep, Asynch, Aclose, Astatus, Aquit, Adata, Abug, Aflowspec, Afilter, Aresv_init, Aresv_fin, Adlevel, Admask, Arecv, Arcvr, Amemory, Ahexmsg, Aadspec_p, Aadspec }; Pm_inst rtap_mem[400] = { Label( OP_HELP ), Action( Ahelp, NULL, OK), Label( OP_BUG ), Action( Abug, NULL, OK), /* dest|sess [gpi] [intserv] [lsp] [/] */ Label( OP_SESS ), Not_String( "gpi", 2), SetLit( 1, 2), SetLit( 0, 1), Not_String( "intserv", 2), SetLit( 1, 2), SetLit( 0, 1), #if defined LABEL Not_String( "lsp", 2), SetLit( 1, 2), SetLit( 0, 1), #endif IsNot( OP_proto, "Missing: udp|tcp|proto ", ERR ), Not_Host("Bad dest host", ERR), EOL( NULL, 3), Not_Char("/", 3), Not_Integer(NULL, 2), Action( Asession, NULL, OK), Print("Bad dest port", ERR), Label( OP_proto ), Not_String( "udp", 2), SetLit( 17, OK), Not_String( "tcp", 2), SetLit( 6, OK), Not_String( "proto", NO), Not_Integer( "Pm: Bad proto", NO), Go( OK), /* data [<# per sec> []] */ Label( OP_DATA ), #ifdef DATA Not_Integer( NULL, 3), Not_Integer( NULL, 2), Not_EOL("Bad data parms", ERR), Action( Adata, NULL, OK), #else Action( Aunsupported, NULL, OK), #endif /* receive [recv host] */ Label( OP_RECV ), Not_Host(NULL, 1), Action( Arecv, NULL, OK), /* */ Label( OP_TTL ), Not_Integer("Bad TTL parm", ERR), Action( Attl, NULL, OK), /* Generalized */ Label( OP_TEMPLATE ), Action( Aunsupported, NULL, OK), /* [[/]] OR * */ Label( OP_SENDER ), EOL( "", 5), IsNot( OP_hostport, NULL, ERR), InFile( OP_tspec, ".rsvp.profile", 2), IsNot( OP_tspec, "Sender Tspec required", ERR), Is( OP_adspec, "", 1), Action( Asender, NULL, OK), Label( OP_CLOSE), Action( Aclose, NULL, OK), Label( OP_CONFIRM ), /* Turn on confirm flag in next reserv call */ Action( Aconfirm, NULL, OK), Label( OP_ASYNC ), Action( Asynch, NULL, OK), Label( OP_SLEEP ), Not_Integer(NULL, 1), Action( Asleep, NULL, OK ), Label( OP_STATUS ), Action( Astatus, NULL, OK), Label( OP_QUIT ), Action( Aquit, NULL, OK), Label( OP_DLEVEL), Not_Integer( NULL, 1), Action( Adlevel, NULL, OK), Label( OP_DMASK ), Not_Integer( NULL, 1), Action( Admask, NULL, OK), #ifdef ISI_TEST Label( OP_MEMORY ), Action( Amemory, NULL, OK), #endif /* ISI_TEST */ Label( OP_HEXMSG ), Char( "x", 20), Not_String( "path", 2), SetLit( 1, 14), Not_String( "resv", 2), SetLit( 2, 12), Not_String( "perr", 2), SetLit( 3, 10), Not_String( "rerr", 2), SetLit( 4, 8), Not_String( "ptear", 2), SetLit( 5, 6), Not_String( "rtear", 2), SetLit( 6, 4), Not_String( "confirm", 2), SetLit( 7, 2), Print("Bad msg type", ERR), Not_Host( "host?", ERR), Integer( NULL, 2), SetLit( -1, 1), Not_Char( "x", 1), Action( Ahexmsg, NULL, OK), Label( OP_hostport ), /* [host /] port * Needs recursive calls, back-tracking */ Is( OP_hp1, NULL, OK), Is( OP_hp2, NULL, OK), Not_Host( NULL, NO), SetLit( 0, 1), Go( OK), Label( OP_hp1 ), /* host / port */ SetLit( 1, 1), /* Mark: there will be host */ Not_Host( NULL, NO), /* Host entry */ Not_Char( "/", NO), Not_Integer( "Bad port", ERR), Go( OK), Label( OP_hp2 ), /* [(no host /)] port */ SetLit( 0, 1), /* Mark: no host. */ SetLit( 0, 1), /* Space over host entry */ Not_Integer( "Bad port", ERR), Go( OK), Label( OP_RESV ), Not_Char( "?", 2), Action( Aotherhelp, NULL, OK), /* Receiver host is ambiguous with style... don't allow * host names wf, ff, or se. So, must test for style * before we parse host name. */ Action( Aresv_init, NULL, 1), Not_String("wf", 2), Is( OP_wf, NULL, OK), Not_String("ff", 2), Is( OP_ff, NULL, OK), Not_String("se", 2), Is( OP_se, NULL, OK), Not_Host( "Bad style", ERR), Action(Arcvr, NULL, 1), Not_String("wf", 2), Is( OP_wf, NULL, OK), Not_String("ff", 2), Is( OP_ff, NULL, OK), Not_String("se", 2), Is( OP_se, NULL, OK), Print( "Bad style", ERR), Label( OP_wf ), /* * WF parms: ['*'] */ SetLit( RAPI_RSTYLE_WILDCARD, 1), EOL( NULL, 5), Char( "*", 1), InFile( OP_flowspec, ".rsvp.profile", 2), IsNot( OP_flowspec, "Flowspec illegal or missing", ERR), Action( Aflowspec, NULL, 1), Action( Aresv_fin, NULL, OK), Label( OP_ff ), /* * FF parms: { { }*1 }* * really: { }* */ SetLit( RAPI_RSTYLE_FIXED, 1), Not_EOL( NULL, 2), Action( Aresv_fin, NULL, OK), IsNot( OP_filter, "Bad filterspec", ERR), Action( Afilter, NULL, 1), InFile( OP_flowspec, ".rsvp.profile", 2), IsNot( OP_flowspec, "Bad flowspec", ERR), Action( Aflowspec, NULL, -6), /* * SE parms: [ *1 ] */ Label( OP_se ), SetLit( RAPI_RSTYLE_SE, 1), Not_EOL( NULL, 2), Action( Aresv_fin, NULL, OK), IsNot( OP_filter, "Missing filter spec", ERR), Action( Afilter, NULL, 1), Is( OP_filter, NULL, -1), InFile( OP_flowspec, ".rsvp.profile", 2), IsNot( OP_flowspec, "Missing flowspec", ERR), Action( Aflowspec, NULL, -7), Label( OP_tspec ), /* Tspec * '[' 't'

[] ']' */ Not_Char("[", NO), Not_String("t", 2), SetLit(QOS_TSPEC, 2), Print("Unknown service", ERR), Not_Integer("Missing r: TB depth", ERR), Not_Integer("Missing b: TB rate", ERR), Not_Integer("Missing p: Peak rate", ERR), Not_Integer("Missing m: Min policed size", ERR), Not_Integer(NULL, 1), Char("]", 2), Print("Missing ]", ERR), Action(Atspec, NULL, OK), Label( OP_flowspec ), /* '[' 'cl'

[] ']' * '[' 'g'

[] ']' */ Not_Char("[", NO), Not_String("g", 2), SetLit(QOS_GUARANTEED, 4), Not_String("cl", 2), SetLit(QOS_CNTR_LOAD, 4), Print("Unknown service", ERR), Not_Integer("Missing R: Rate", ERR), Not_Integer("Missing S: Slack", ERR), Not_Integer("Missing r: TB depth", ERR), Not_Integer("Missing b: TB rate", ERR), Not_Integer("Missing p: Peak rate", ERR), Not_Integer("Missing m: Min policed size", ERR), Not_Integer(NULL, 1), Char("]", OK), Print("Missing ]", ERR), Label( OP_filter ), /* host [ / port ] */ Not_Host(NULL, NO), WhSp( NULL, OK), Char("/", 2), Print("Bad dest port", ERR), Not_Integer(NULL, -1), Go( OK), Label( OP_adspec ), Char("(", 2), Action(Aadspec, NULL, NO), /* Record null Adspec */ SetLit(GENERAL_INFO, 1), /* General info section */ Is(OP_breakbit, NULL, 1), /* Scan Break bit -- */ /* Also initializes adspec area */ /* Have to recurse now to keep value stack consistent. This is * quite confusing... I need to think of a better way to handle * the value stack. */ Is(OP_genparm, NULL, 1), /* Scan general parms */ Not_Char(")", 2), /* ) => done */ Action(Aadspec, NULL, OK), Char(",", 1), /* Ignore comma */ /* scan for service-specific fragments, if any. */ Is(OP_Gadspec, "", -3), Is(OP_CLadspec,"", -4), /* General info parms MUST be in order; however, suffix strings * are optional. */ Label( OP_genparm ), SetLit(IS_WKP_HOP_CNT, 1), Not_Integer("Missing # hops", ERR), Action(Aadspec_p, NULL, 1), String("hop", 1), SetLit(IS_WKP_PATH_BW, 1), Not_Integer("Missing BW", ERR), Action(Aadspec_p, NULL, 1), String("B/s", 1), SetLit(IS_WKP_MIN_LATENCY, 1), Not_Integer("Missing min lat", ERR), Action(Aadspec_p, NULL, 1), String("usec", 1), SetLit(IS_WKP_COMPOSED_MTU, 1), Not_Integer("Missing MTU", ERR), Action(Aadspec_p, NULL, 1), String("B", OK), Go( OK), Label( OP_hops ), SetLit(IS_WKP_HOP_CNT, 1), Not_Integer(NULL, NO), Not_String("hop", NO), Action(Aadspec_p, NULL, OK), Label( OP_BW ), SetLit(IS_WKP_PATH_BW, 1), Not_Integer(NULL, NO), Not_String("BW", NO), Action(Aadspec_p, NULL, OK), Label( OP_minlat ), SetLit(IS_WKP_MIN_LATENCY, 1), Not_Integer(NULL, NO), Not_String("us", NO), Action(Aadspec_p, NULL, OK), Label( OP_MTU ), SetLit(IS_WKP_COMPOSED_MTU, 1), Not_Integer(NULL, NO), Not_String("mtu", NO), Action(Aadspec_p, NULL, OK), Label( OP_breakbit ), SetLit(0, 1), /* Type = Break bit */ String("br!", 2), SetLit(0, 2), /* Value = break bit */ SetLit(1, 1), Action(Aadspec_p, NULL, OK), Label( OP_Gadspec ), Not_String("G=", NO), Not_String("{", NO), SetLit(GUARANTEED_SERV, 1), Is(OP_breakbit, NULL, 1), /* Break bit -- */ Is(OP_Gadparms, NULL, 1), String("}", OK), Is(OP_hops, NULL, -1), Is(OP_BW, NULL, -2), Is(OP_minlat, NULL, -3), Is(OP_MTU, NULL, -4), Print("Bad Guar override parm", ERR), Label( OP_Gadparms ), SetLit(GUAR_ADSPARM_C, 1), Not_Integer("Missing G parm1", ERR), Not_Integer("Missing G parm2", ERR), Not_Integer("Missing G parm3", ERR), Not_Integer("Missing G parm4", ERR), Action(Aadspec_p, NULL, OK), Label( OP_CLadspec ), Not_String("CL=", NO), Not_String("{", NO), SetLit(CONTROLLED_LOAD_SERV, 1), Is(OP_breakbit, NULL, 1), /* Break bit -- */ String("}", OK), Is(OP_hops, NULL, -1), Is(OP_BW, NULL, -2), Is(OP_minlat, NULL, -3), Is(OP_MTU, NULL, -4), Print("Bad CL override parm", ERR), Label( 0 ) }; /* XXX TEMPORARY! */ void mallocmap() {} int Pm_Action(int op, int vi, int parm) { int i, sid, rc; u_char flags; #ifdef DATA double F_intvl; long I_intvl; #endif #ifdef ISI_TEST void mallocmap(); #endif #ifdef RTAP char *cp; u_char u_ch; #endif switch (op) { case Ahelp: for (i = 0; i < OP_NULL; i++) printf("%s", cmd_table[i].cmd_help); case Aotherhelp: printf(Other_help); break; case Abug: Pm_debug = !Pm_debug; break; case Asession: /* val stack: * gpi?1|0 intserv?1:0 proto desthost [destport] */ flags = 0; if (val0) { flags = RAPI_GPI_SESSION; Mode[T] |= GPI_MODE; } if (val1) flags |= RAPI_USE_INTSERV; #if defined LABEL if(val2) { flags = RAPI_LSP_SESSION; Mode[T] |= LSP_MODE; } protid[T] = val3; get_sockaddr(4, (struct sockaddr *) &dest[T]); #else protid[T] = val2; get_sockaddr(3, (struct sockaddr *) &dest[T]); #endif if (Sid[T] != NULL_SID) { printf("close first\n"); break; } sid = rapi_session((struct sockaddr *)&dest[T], protid[T], flags, (rapi_event_rtn_t) asynch_handler, 0, &rc); if (sid == NULL_SID) print_errno("rsvp_session()", rc); else { Sid[T] = sid; rtap_fd = rapi_getfd(sid); printf("T%d: rapi_session => sid= %d, fd= %d\n", T, sid, rtap_fd); } #ifdef DATA send_data_bytes = recv_data_bytes = 0; send_data_msgs = recv_data_msgs = 0; #endif break; #ifdef DATA case Adata: if (Pm_vi > 0) { F_intvl = atof(val0); I_intvl = (long) rint(1e6/F_intvl); timeout.tv_sec = I_intvl/1000000; timeout.tv_usec = I_intvl%1000000; if (Pm_vi > 1) data_size = val1; else data_size = DEFAULTDATA_SIZE; } gettimeofday(&nexttime, NULL); tvadd(&nexttime, &timeout); break; #endif /* DATA */ case Arecv: if (Sid[T] == NULL_SID) { printf("Must issue dest cmd first\n"); break; } memset(&rcvr[T], 0, sizeof(struct SOCKADDR)); if (Pm_vi > 0) { Append_Val(0); /* No port */ get_sockaddr(vi, (struct sockaddr *) &rcvr[T]); } if (udpsock[T] < 0) udpsock[T] = Get_Socket((struct sockaddr *) &dest[T]); Set_Recv((struct sockaddr *) &dest[T], (struct sockaddr *) &rcvr[T]); break; case Attl: if (Pm_vi > 0) ttl[T] = val0; #ifdef DATA if (( Mode & S_MODE ) && data_size > 0) Set_Send(&dest[T], &src[T], ttl[T]); #endif break; case Aunsupported: printf("Not supported\n"); break; case Asender: /* Sender: value stack is: * [ <1> | <0> ] */ if (Sid[T] == NULL_SID) { printf("Must issue dest cmd first\n"); break; } if (Pm_vi) { /* There are parameters ... not just empty sender. * */ if (!Pm_val[vi]) { /* No host; supply INADDR_ANY of * same type as dest address. */ Set_INADDR_ANY(&Pm_addrs[vi+1], (struct sockaddr *) &dest[T]); } if (Mode[T] & GPI_MODE) { memset(&src[T], 0, sizeof(struct SOCKADDR)); init_Area((area_t **)&snd_template[T], sizeof(rapi_filter_t)); get_GPIfilter(vi+1, &snd_template[T], sizeof(rapi_filter_t)); } else { /* Normal case... */ free_Area(&snd_template[T]); get_sockaddr(vi+1, (struct sockaddr *) &src[T]); } } /* * Make rapi_sender call to RSVP API */ rc = rapi_sender(Sid[T], 0, (Pm_vi>0)? (struct sockaddr *)&src[T]: NULL, #ifdef EX_ROUTE NULL, #endif Area_Data((rapi_filter_t *), snd_template[T]), Area_Data((rapi_tspec_t *), snd_tspec[T]), Area_Data((rapi_adspec_t *), snd_adspec[T]), NULL, /* Policy */ ttl[T] #ifdef LABEL ,0 #endif ); if (rc) print_errno("rsvp_sender()", rc); else printf("rapi_sender() OK\n"); Mode[T] |= S_MODE; break; case Atspec: init_Area((area_t **)&snd_tspec[T], sizeof(rapi_tspec_t)); get_tspec(vi, &snd_tspec[T], sizeof(rapi_tspec_t)); Pm_vi = vi; /* Pop off value stack */ break; case Aadspec_p: /* Adspec parm: * !Value stack is offset by 1; it contains: * (Service#) |> (parm#) (value) * except: * (GUARANTEED) |> (GUAR_ADSPARM_C) (p1) (p2) (p3) (p4) */ set_adspec_p(vi-1, Pm_val[vi-1], Pm_val[vi], 1); Pm_vi -= 2; break; case Aadspec: /* Completed Adspec * */ if (vi < Pm_vi) { Adspec.len = sizeof(Adspec); Adspec.form = RAPI_ADSTYPE_Simplified; init_Area((area_t **)&snd_adspec[T], sizeof(rapi_adspec_t)); Cat_Area(snd_adspec[T], (rapi_hdr_t *) &Adspec); } else if (snd_adspec[T]) { free (snd_adspec[T]); snd_adspec[T] = NULL; } break; case Aclose: if (Sid[T] == NULL_SID) { printf("Already closed\n"); break; } rc = rapi_release(Sid[T]); if (rc) print_errno("rapi_release()", rc); printf("T%d: rapi_release(): sid= %d, fd= %d\n", T, Sid[T], rtap_fd); Sid[T] = NULL_SID; Mode[T] = NO_MODE; if (udpsock[T] >= 0) close(udpsock[T]); /* close data socket */ udpsock[T] = -1; break; case Aconfirm: resv_flags[T] = RAPI_REQ_CONFIRM; break; case Asynch: rc = rapi_dispatch(); if (rc) print_errno("rapi_dispatch()", rc); case Amemory: #if defined(ISI_TEST) && defined(SunOS) mallocmap(); #else printf("Not supported.\n"); #endif break; case Ahexmsg: /* To send arbitrary RSVP message, use: * hexmsg x * * The first 8 bytes of will be * replaced by an RSVP common header. Blanks in * will be ignored. * * If the packet is larger than 100 bytes or for * convenience, can split into multiple lines, ended * with the line show above; e.g., * hexmsg x * hexmsg x * ... * hexmsg [vif] x * * or: * hexmsg x * ... * hexmsg x * hexmsg [vif] * * Val stack: [ ] */ #ifdef RTAP if (packet_size >= MAX_PACKET) { printf("Hex msg too large\n"); break; } u_ch = i = 0; for (cp = Pm_cp; *cp; cp++) { if (isxdigit(*cp)) { #define tohex(c) (isdigit(c)?c-'0':tolower(c)-'a'+10) u_ch = (u_ch<<4)|tohex(*cp); if (++i == 2) { packet_buff[packet_size++] = u_ch; i = u_ch = 0; } } else if ((*cp == ' '||*cp == '#') &&(i)) { printf("Bad hex @ +%d\n", cp-Pm_cp-1); break; } if (*cp == '#') break; } /* Only last line of multi-line message specifies host, * and therefore has Pm_vi > 0. */ if (Pm_vi == 0) break; rtap_hexmsg(val0, val2, &Pm_addrs[1], packet_buff, packet_size); packet_size = 0; #else printf("Unsupported by remote rtap\n"); #endif break; case Asleep: rtap_sleep((Pm_vi > 0)? val0:0); break; case Astatus: print_status(); break; case Aquit: if (Sid[T] != NULL_SID) { rc = rapi_release(Sid[T]); if (rc) print_errno("rapi_release()", rc); printf("Closed sid= %d, fd= %d\n", Sid[T], rtap_fd); } if (udpsock[T] >= 0) close(udpsock[T]); /* close data socket */ #ifdef RTAP dump_rsvp_stats(); #endif exit(0); case Afilter: if (Mode[T] & GPI_MODE) get_GPIfilter(1+vi, &Filter_specs[T], sizeof(rapi_filter_t)); #if defined LABEL else if (Mode[T] & LSP_MODE) get_LSPfilter(1+vi, &Filter_specs[T], sizeof(rapi_filter_t)); #endif else get_filter(1+vi, &Filter_specs[T], sizeof(rapi_filter_t)); Pm_vi = vi+1; break; case Aflowspec: /* Value stack: