📄 nrcmd.c
字号:
static struct cmds Nfcmds[] = {
"add", donfadd, 0, 3,
"netrom nodefilter add <neighbor> <interface>",
"drop", donfdrop, 0, 3,
"netrom nodefilter drop <neighbor> <interface>",
"mode", donfmode, 0, 0, NULL,
NULL, NULL, 0, 0,
"nodefilter subcommands: add drop mode",
} ;
/* nodefilter command multiplexer */
static int
donodefilter(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
if (argc < 2) {
donfdump() ;
return 0 ;
}
return subcmd(Nfcmds,argc,argv,p) ;
}
/* display a list of <callsign,interface> pairs from the filter
* list.
*/
static int
donfdump()
{
int i, column = 1 ;
struct nrnf_tab *fp ;
char buf[16] ;
for (i = 0 ; i < NRNUMCHAINS ; i++)
for (fp = Nrnf_tab[i] ; fp != NULL ; fp = fp->next) {
pax25(buf,fp->neighbor) ;
printf("%-7s %-8s ",
buf,Nrifaces[fp->iface].iface->name) ;
if (column++ == 4) {
printf("\n");
column = 1 ;
}
}
if (column != 1)
printf("\n") ;
return 0 ;
}
/* add an entry to the filter table */
static int
donfadd(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
uint8 neighbor[AXALEN] ;
register int i ;
/* format callsign */
if (setcall(neighbor,argv[1]) == -1) {
printf("bad neighbor callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < Nr_numiface ; i++)
if (!strcmp(Nrifaces[i].iface->name,argv[2]))
break ;
if (i == Nr_numiface) {
printf("Interface \"%s\" not found\n",argv[2]) ;
return -1 ;
}
return nr_nfadd(neighbor,i) ;
}
/* drop an entry from the filter table */
static int
donfdrop(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
uint8 neighbor[AXALEN] ;
register int i ;
/* format neighbor callsign */
if (setcall(neighbor,argv[1]) == -1) {
printf("bad neighbor callsign\n") ;
return -1 ;
}
/* find interface */
for (i = 0 ; i < Nr_numiface ; i++)
if (!strcmp(Nrifaces[i].iface->name,argv[2]))
break ;
if (i == Nr_numiface) {
printf("Interface \"%s\" not found\n",argv[2]) ;
return -1 ;
}
return nr_nfdrop(neighbor,i) ;
}
/* nodefilter mode subcommand */
static int
donfmode(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
if (argc < 2) {
printf("filter mode is ") ;
switch (Nr_nfmode) {
case NRNF_NOFILTER:
printf("none\n") ;
break ;
case NRNF_ACCEPT:
printf("accept\n") ;
break ;
case NRNF_REJECT:
printf("reject\n") ;
break ;
default:
printf("some strange, unknown value\n") ;
}
return 0 ;
}
switch (argv[1][0]) {
case 'n':
case 'N':
Nr_nfmode = NRNF_NOFILTER ;
break ;
case 'a':
case 'A':
Nr_nfmode = NRNF_ACCEPT ;
break ;
case 'r':
case 'R':
Nr_nfmode = NRNF_REJECT ;
break ;
default:
printf("modes are: none accept reject\n") ;
return -1 ;
}
return 0 ;
}
/* netrom network packet time-to-live initializer */
static int
donrttl(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setshort(&Nr_ttl,"Time to live",argc,argv);
}
/* verbose route broadcast */
static int
donrverbose(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setbool(&Nr_verbose,"Verbose flag",argc,argv);
}
/* Initiate a NET/ROM transport connection */
static int
donrconnect(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
uint8 *np ;
struct sockaddr_nr lsocket, fsocket;
char alias[AXBUF];
struct session *sp;
int s;
/* Get a session descriptor */
if ((sp = newsession(Cmdline,NRSESSION,1)) == NULL) {
printf("Too many sessions\n") ;
return 1 ;
}
sp->inproc = keychar; /* Intercept ^C */
if((s = socket(AF_NETROM,SOCK_SEQPACKET,0)) == -1){
printf("Can't create socket\n");
keywait(NULL,1);
freesession(sp);
return 1;
}
lsocket.nr_family = AF_NETROM;
/* Set up our local username, bind would use Mycall instead */
memcpy(lsocket.nr_addr.user,Nr4user,AXALEN);
/* Putting anything else than Mycall here will not work */
memcpy(lsocket.nr_addr.node,Mycall,AXALEN);
bind(s,(struct sockaddr *)&lsocket,sizeof(struct sockaddr_nr));
/* See if the requested destination could be an alias, and */
/* find and use it if it is. Otherwise assume it is an ax.25 */
/* address. */
if (putalias(alias,argv[1],0) != -1 &&
(np = find_nralias(alias)) != NULL) {
memcpy(fsocket.nr_addr.user,np,AXALEN) ;
memcpy(fsocket.nr_addr.node,np,AXALEN) ;
} else { /* parse ax25 callsign */
/* Only the user callsign of the remote station is never used by */
/* NET/ROM, but it is needed for the psocket() call. */
setcall(fsocket.nr_addr.user,argv[1]);
setcall(fsocket.nr_addr.node,argv[1]);
}
fsocket.nr_family = AF_NETROM;
pax25(alias,fsocket.nr_addr.node);
sp->network = fdopen(s,"r+t");
setvbuf(sp->network,NULL,_IOLBF,BUFSIZ);
if(SETSIG(EABORT)){
keywait(NULL,1);
freesession(sp);
return 1;
}
return tel_connect(sp, (struct sockaddr *)&fsocket, sizeof(struct sockaddr_nr));
}
/* Reset a net/rom connection abruptly */
static int
donrreset(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nr4cb *cb ;
cb = (struct nr4cb *)htol(argv[1]);
if(!nr4valcb(cb)){
printf(Notval);
return 1;
}
reset_nr4(cb);
return 0;
}
/* Force retransmission on a net/rom connection */
static int
donrkick(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct nr4cb *cb ;
cb = (struct nr4cb *)htol(argv[1]);
if (kick_nr4(cb) == -1) {
printf(Notval);
return 1;
} else
return 0;
}
/* netrom transport ACK delay timer */
static int
donracktime(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setlong(&Nr4acktime,"Ack delay time (ms)",argc,argv);
}
/* netrom transport choke timeout */
static int
donrchoketime(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setlong(&Nr4choketime,"Choke timeout (ms)",argc,argv);
}
/* netrom transport initial round trip time */
static int
donrirtt(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setlong(&Nr4irtt,"Initial RTT (ms)",argc,argv);
}
/* netrom transport receive queue length limit. This is the */
/* threshhold at which we will CHOKE the sender. */
static int
donrqlimit(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setshort(&Nr4qlimit,"Queue limit (bytes)",argc,argv);
}
/* Display or change our NET/ROM username */
static int
donruser(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char buf[AXBUF];
if(argc < 2){
pax25(buf,Nr4user);
printf("%s\n",buf);
return 0;
}
if(setcall(Nr4user,argv[1]) == -1)
return -1;
Nr4user[ALEN] |= E;
return 0;
}
/* netrom transport maximum window. This is the largest send and */
/* receive window we may negotiate */
static int
donrwindow(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setshort(&Nr4window,"Window (frames)",argc,argv);
}
/* netrom transport maximum retries. This is used in connect and */
/* disconnect attempts; I haven't decided what to do about actual */
/* data retries yet. */
static int
donrretries(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
return setshort(&Nr4retries,"Retry limit",argc,argv);
}
/* Display the status of NET/ROM connections */
static int
donrstatus(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
int i ;
struct nr4cb *cb ;
char luser[AXBUF], ruser[AXBUF], node[AXBUF] ;
if (argc < 2) {
printf("&CB Snd-W Snd-Q Rcv-Q LUser RUser @Node State\n");
for (i = 0 ; i < NR4MAXCIRC ; i++) {
if ((cb = Nr4circuits[i].ccb) == NULL)
continue ;
pax25(luser,cb->local.user) ;
pax25(ruser,cb->remote.user) ;
pax25(node,cb->remote.node) ;
printf("%9p %3d %5d %5d %9s %9s %-9s %s\n",
cb, cb->nbuffered, len_q(cb->txq),
len_p(cb->rxq), luser, ruser, node,
Nr4states[cb->state]);
}
return 0 ;
}
cb = (struct nr4cb *)htol(argv[1]) ;
if (!nr4valcb(cb)) {
printf(Notval) ;
return 1 ;
}
donrdump(cb) ;
return 0 ;
}
/* Dump one control block */
void
donrdump(cb)
struct nr4cb *cb ;
{
char luser[AXBUF], ruser[AXBUF], node[AXBUF] ;
unsigned seq ;
struct nr4txbuf *b ;
struct timer *t ;
pax25(luser,cb->local.user) ;
pax25(ruser,cb->remote.user) ;
pax25(node,cb->remote.node) ;
printf("Local: %s %d/%d Remote: %s @ %s %d/%d State: %s\n",
luser, cb->mynum, cb->myid, ruser, node,
cb->yournum, cb->yourid, Nr4states[cb->state]) ;
printf("Window: %-5u Rxpect: %-5u RxNext: %-5u RxQ: %-5d %s\n",
cb->window, cb->rxpected, cb->rxpastwin,
len_p(cb->rxq), cb->qfull ? "RxCHOKED" : "") ;
printf(" Unack: %-5u Txpect: %-5u TxNext: %-5u TxQ: %-5d %s\n",
cb->nbuffered, cb->ackxpected, cb->nextosend,
len_q(cb->txq), cb->choked ? "TxCHOKED" : "") ;
printf("TACK: ") ;
if (run_timer(&cb->tack))
printf("%lu", read_timer(&cb->tack)) ;
else
printf("stop") ;
printf("/%lu ms; ", dur_timer(&cb->tack)) ;
printf("TChoke: ") ;
if (run_timer(&cb->tchoke))
printf("%lu", read_timer(&cb->tchoke)) ;
else
printf("stop") ;
printf("/%lu ms; ", dur_timer(&cb->tchoke)) ;
printf("TCD: ") ;
if (run_timer(&cb->tcd))
printf("%lu", read_timer(&cb->tcd)) ;
else
printf("stop") ;
printf("/%lu ms", dur_timer(&cb->tcd)) ;
if (run_timer(&cb->tcd))
printf("; Tries: %u\n", cb->cdtries) ;
else
printf("\n") ;
printf("Backoff Level %u SRTT %ld ms Mean dev %ld ms\n",
cb->blevel, cb->srtt, cb->mdev) ;
/* If we are connected and the send window is open, display */
/* the status of all the buffers and their timers */
if (cb->state == NR4STCON && cb->nextosend != cb->ackxpected) {
printf("TxBuffers: Seq Size Tries Timer\n") ;
for (seq = cb->ackxpected ;
nr4between(cb->ackxpected, seq, cb->nextosend) ;
seq = (seq + 1) & NR4SEQMASK) {
b = &cb->txbufs[seq % cb->window] ;
t = &b->tretry ;
printf(" %3u %3d %5d %lu/%lu\n",
seq, len_p(b->data), b->retries + 1,
read_timer(t), dur_timer(t));
}
}
}
static int
keychar(c)
int c;
{
if(c != CTLC)
return 1; /* Ignore all but ^C */
fprintf(Current->output,"^C\n");
alert(Current->proc,EABORT);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -