📄 rtap_cmds.c
字号:
/* * 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 + * <hooks in rsvp_main.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 <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <unistd.h>#include <math.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <errno.h>#include <netdb.h>#include <arpa/inet.h>#include "rsvp_socks.h"#include "rsvp_trans.h"#include "rapi_lib.h"#include "rapi_err.h"#include "rsvp.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();/* * Globals */#define MAX_NFLWDS 64#define MAX_T 64int 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 0x10int 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 */#ifdef DATAstruct timeval timeout, nexttime;struct timeval Default_interval = {1, 0}; /* Default is 1 per second */#define MAXDATA_SIZE 1500#define DEFAULTDATA_SIZE 512char 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 1024u_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))#endifenum 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" }, { "dest", OP_SESS, " dest [gpi] [intserv] <proto> <dest addr>[/<dest port>]\n" }, { "session", OP_SESS, " session (same as 'dest')\n" }, { "sender", OP_SENDER, "\ sender [<src host>/]<src port> <Tspec> [<adspec>]\n" }, { "reserve", OP_RESV, "\ reserve [recv addr] wf [*] <flowspec> |\n\ reserve [rcv addr] ff <filtspec> <flowspec> [<filtspec> <flowspec>] ... |\n\ reserve [rcv addr] se [<filtspec> ...] <flowspec>\n" }, { "close", OP_CLOSE, " close\n" }, { "status", OP_STATUS, " status\n" }, { "data", OP_DATA, " data [<# per sec> [<size>]]\n" }, { "receive", OP_RECV, " receive [recv host]\n" }, { "ttl", OP_TTL, " ttl <integer>\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 <user credential string>\n" }, ****/#endif { "async", OP_ASYNC, " async\n" }, { "sleep", OP_SLEEP, " sleep <seconds>\n" }, { "dlevel", OP_DLEVEL, " dlevel <logging level>\n" }, { "dmask", OP_DMASK, " dmask <debug mask>\n" },#ifdef ISI_TEST { "memory", OP_MEMORY, " memory (=>mallocmap)\n"},#endif { "hexmsg", OP_HEXMSG, " hexmsg <type> <host> [vif] x<hex string>\n"}, { "echo", OP_ECHO, " echo <text>\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<thread#><sp>'\n\\n\<proto> ::= 'tcp' | 'udp' | 'proto' <integer>\n\\n\<Flowspec> ::= \n\ '[' 'g' <R> <S> <r(Bps)> <b(B)> <p(Bps)> <m(B)> [ <M(B)> ] ']' |\n\ '[' 'cl' <r(Bps)> <b(B)> <p(Bps)> <m(B)> [ <M(B)> ] ']' |\n\\n\<Tspec> ::= \n\ '[' 't' <r(Bps)> <b(B)> <p(Bps)> <m(B)> [ <M(B)> ] ']'\n\\n\<Adspec> ::= \n\ '(' ['br!'] <h#> <bw#> <minlat> <mtu> \n\ [ ',' 'G=' '{' ['br!'] [<Ctot>] [<Dtot>] [<Csum>] [<Dsum>] \n\ [<h#> 'hop'] [<bw#> 'bw'] [<minlat> 'us'] [<mtu> 'mtu'] '}' ] \n\ [ ',' 'CL=' '{' ['br!'] \n\ [<h#> 'hop'] [<bw#> 'bw'] [<minlat> 'us'] [<mtu> 'mtu'] '}' ] \n\\n\<Filtspec> ::= <host name|number>/<port #|GPI>\n\\n\<type> ::= '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] <proto> <dest addr>[/<dest port>] */ Label( OP_SESS ), Not_String( "gpi", 2), SetLit( 1, 2), SetLit( 0, 1), Not_String( "intserv", 2), SetLit( 1, 2), SetLit( 0, 1), IsNot( OP_proto, "Missing: udp|tcp|proto <int>", 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> [<size>]] */ 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), /* <ttl value> */ Label( OP_TTL ), Not_Integer("Bad TTL parm", ERR), Action( Attl, NULL, OK), /* Generalized <sender template> */ Label( OP_TEMPLATE ), Action( Aunsupported, NULL, OK), /* [[<sender host>/]<port>] <tspec> OR * <empty> */ 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: ['*'] <flowspec> */ 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: { { <filtspec> }*1 <flowspec> }* * really: { <filtspec> <flowspec> }* */ 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: [ <filtspec>*1 <flowspec> ] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -