⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrcmd.c

📁 在51单片机上实现TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:


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 + -