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

📄 nrcmd.c

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

#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "mailbox.h"
#include "netrom.h"
#include "nr4.h"
#include "timer.h"
#include "iface.h"
#include "lapb.h"
#include "cmdparse.h"
#include "session.h"
#include "socket.h"
#include "commands.h"

uint8 Nr4user[AXALEN];

char *Nr4states[] = {
	"Disconn",
	"Conn Pend",
	"Connected",
	"Disc Pend",
	"Listening"
} ;

char *Nr4reasons[] = {
	"Normal",
	"By Peer",
	"Timeout",
	"Reset",
	"Refused"
} ;
static int dobcnodes(int argc,char *argv[],void *p);
static int dointerface(int argc,char *argv[],void *p);
static int donfadd(int argc,char *argv[],void *p);
static int donfdrop(int argc,char *argv[],void *p);
static int donfdump(void);
static int donfmode(int argc,char *argv[],void *p);
static int donodefilter(int argc,char *argv[],void *p);
static void donodetick(void);
static int donodetimer(int argc,char *argv[],void *p);
static int donracktime(int argc,char *argv[],void *p);
static int donrchoketime(int argc,char *argv[],void *p);
static int donrconnect(int argc,char *argv[],void *p);
static int donrirtt(int argc,char *argv[],void *p);
static int donrkick(int argc,char *argv[],void *p);
static int dorouteadd(int argc,char *argv[],void *p);
static int doroutedrop(int argc,char *argv[],void *p);
static int donrqlimit(int argc,char *argv[],void *p);
static int donrreset(int argc,char *argv[],void *p);
static int donrretries(int argc,char *argv[],void *p);
static int donrroute(int argc,char *argv[],void *p);
static int donrstatus(int argc,char *argv[],void *p);
static int donrttl(int argc,char *argv[],void *p);
static int donruser(int argc,char *argv[],void *p);
static int donrverbose(int argc,char *argv[],void *p);
static int donrwindow(int argc,char *argv[],void *p);
static void doobsotick(void);
static int doobsotimer(int argc,char *argv[],void *p);

static struct cmds Nrcmds[] = {
	"acktime",	donracktime,	0, 0,	NULL,
	"bcnodes",	dobcnodes,	0, 2,	"netrom bcnodes <interface>",
	"connect",	donrconnect, 1024, 2,	"netrom connect <node>",
	"choketime",	donrchoketime,	0, 0,	NULL,
	"interface",	dointerface,	0, 4,
		"netrom interface <interface> <alias> <quality>",
	"irtt",		donrirtt,	0, 0,	NULL,
	"kick",		donrkick,	0, 2,	"netrom kick <&nrcb>",
	"nodefilter",	donodefilter,	0, 0,	NULL,
	"nodetimer",	donodetimer,	0, 0,	NULL,
	"obsotimer",	doobsotimer,	0, 0,	NULL,
	"qlimit",	donrqlimit,	0, 0,	NULL,
	"reset",	donrreset,	0, 2,	"netrom reset <&nrcb>",
	"retries",	donrretries,	0, 0,	NULL,
	"route",	donrroute,	0, 0,	NULL,
	"status",	donrstatus,	0, 0,	NULL,
	"ttl",		donrttl,	0, 0,	NULL,
	"user",		donruser,	0, 0,	NULL,
	"verbose",	donrverbose,	0, 0,	NULL,
	"window",	donrwindow,	0, 0,	NULL,
	NULL,
} ;

static struct timer Nodetimer ;	/* timer for nodes broadcasts */
static struct timer Obsotimer ;	/* timer for aging routes */

static int keychar(int c);

/* Command multiplexer */
int
donetrom(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
	return subcmd(Nrcmds,argc,argv,p) ;
}

static struct cmds Routecmds[] = {
	"add",	dorouteadd,	0, 6,
		"netrom route add <alias> <destination> <interface> <quality> <neighbor>",
	"drop",	doroutedrop, 0, 4,
		"netrom route drop <destination> <neighbor> <interface>",
	"info", dorouteinfo, 0, 2,
		"netrom route info <destination>",
	NULL,
} ;

/* Route command multiplexer */
static int
donrroute(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
	if (argc < 2) {
		doroutedump() ;
		return 0 ;
	}
	return subcmd(Routecmds,argc,argv,p) ;
}

/* Dump a list of known routes */
int
doroutedump()
{
	register struct nrroute_tab *rp ;
	register int i, column ;
	char buf[16] ;
	char *cp ;
	
	column = 1 ;
	
	for (i = 0 ; i < NRNUMCHAINS ; i++)
		for (rp = Nrroute_tab[i] ; rp != NULL ; rp = rp->next) {
			strcpy(buf,rp->alias) ;
			/* remove trailing spaces */
			if ((cp = strchr(buf,' ')) == NULL)
				cp = &buf[strlen(buf)] ;
			if (cp != buf)		/* don't include colon for null alias */
				*cp++ = ':' ;
			pax25(cp,rp->call) ;
			printf("%-16s  ",buf) ;
			if (column++ == 4) {
				printf("\n");
				column = 1 ;
			}
		}

	if (column != 1)
		printf("\n") ;
		
	return 0 ;
}

/* print detailed information on an individual route */
int
dorouteinfo(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
	register struct nrroute_tab *rp ;
	register struct nr_bind *bp ;
	register struct nrnbr_tab *np ;
	uint8 dest[AXALEN] ;
	char neighbor[AXBUF] ;

	if (setcall(dest,argv[1]) == -1) {
		printf ("bad destination name\n") ;
		return -1 ;
	}
		
	if ((rp = find_nrroute(dest)) == NULL) {
		printf("no such route\n") ;
		return -1 ;
	}

	for (bp = rp->routes ; bp != NULL ; bp = bp->next) {
		np = bp->via ;
		printf("%1s %3d  %3d  %-8s  %s\n",
		 (bp->flags & NRB_PERMANENT ? "P" :
		 bp->flags & NRB_RECORDED ? "R" : " "),
		 bp->quality,bp->obsocnt,
		 Nrifaces[np->iface].iface->name,
		 pax25(neighbor,np->call));
	}
	return 0 ;
}
		
/* convert a null-terminated alias name to a blank-filled, upcased */
/* version.  Return -1 on failure. */
int
putalias(to,from,complain)
register char *to, *from ;
int complain ;    
{
	int len, i ;
	
	if ((len = strlen(from)) > ALEN) {
		if (complain)
			printf ("alias too long - six characters max\n") ;
		return -1 ;
	}
	
	for (i = 0 ; i < ALEN ; i++) {
		if (i < len) {
			if (islower(*from))
				*to++ = toupper(*from++) ;
			else
				*to++ = *from++ ;
		}
		else
			*to++ = ' ' ;
	}
			
	*to = '\0' ;
	return 0 ;
}

/* Add a route */
static int
dorouteadd(argc, argv,p)
int argc ;
char *argv[] ;
void *p;
{
	char alias[AXALEN] ;
	uint8 dest[AXALEN] ;
	unsigned quality ;
	uint8 neighbor[AXALEN] ;
	register int i ;
	int naddr ;

	/* format alias (putalias prints error message if necessary) */
	if (putalias(alias,argv[1],1) == -1)
		return -1 ;

	/* format destination callsign */
	if (setcall(dest,argv[2]) == -1) {
		printf("bad destination callsign\n") ;
		return -1 ;
	}

	/* find interface */
	for (i = 0 ; i < Nr_numiface ; i++)
		if (!strcmp(Nrifaces[i].iface->name,argv[3]))
			break ;
	if (i == Nr_numiface) {
		printf("Interface \"%s\" not found\n",argv[3]) ;
		return -1 ;
	}
	
	/* get and check quality value */
	if ((quality = atoi(argv[4])) > 255) {
		printf("maximum route quality is 255\n") ;
		return -1 ;
	}

	/* Change from 871225 -- no digis in net/rom table */
	naddr = argc - 5 ;
	if (naddr > 1) {
		printf("Use the ax25 route command to specify digipeaters\n") ;
		return -1 ;
	}
	
	/* format neighbor address string */
	setcall(neighbor,argv[5]) ;

	return nr_routeadd(alias,dest,i,quality,neighbor,1,0) ;
}


/* drop a route */
static int
doroutedrop(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
	uint8 dest[AXALEN], neighbor[AXALEN] ;
	register int i ;

	/* format destination and neighbor callsigns */
	if (setcall(dest,argv[1]) == -1) {
		printf("bad destination callsign\n") ;
		return -1 ;
	}
	if (setcall(neighbor,argv[2]) == -1) {
		printf("bad neighbor callsign\n") ;
		return -1 ;
	}

	/* find interface */
	for (i = 0 ; i < Nr_numiface ; i++)
		if (!strcmp(Nrifaces[i].iface->name,argv[3]))
			break ;
	if (i == Nr_numiface) {
		printf("Interface \"%s\" not found\n",argv[3]) ;
		return -1 ;
	}

	return nr_routedrop(dest,neighbor,i) ;
}
	
	
/* make an interface available to net/rom */
static int
dointerface(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
	int i ;
	register struct iface *ifp ;

	if (Nr_iface == NULL) {
		printf("Attach netrom interface first\n") ;
		return 1 ;
	}
	
	if (Nr_numiface >= NRNUMIFACE) {
		printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
		return 1 ;
	}
	
	if((ifp = if_lookup(argv[1])) == NULL){
		printf("Interface \"%s\" unknown\n",argv[1]);
		return 1;
	}
	for (i = 0 ; i < Nr_numiface ; i++)
		if (Nrifaces[i].iface == ifp) {
			printf("Interface \"%s\" is already registered\n",argv[1]) ;
			return 1 ;
		}
		
	Nrifaces[Nr_numiface].iface = ifp ;

	if (putalias(Nrifaces[Nr_numiface].alias,argv[2],1) == -1)
		return 1 ;
		
	if ((Nrifaces[Nr_numiface].quality = atoi(argv[3])) > 255) {
		printf("Quality cannot be greater than 255\n") ;
		return 1 ;
	}
		
	Nr_numiface++ ;			/* accept this interface */
	return 0 ;
}

/* Broadcast nodes list on named interface. */
static int
dobcnodes(argc,argv,p)
int argc ;
char *argv[] ;
void *p;
{
	register int i ;

	for (i = 0 ; i < Nr_numiface ; i++)
		if (!strcmp(Nrifaces[i].iface->name,argv[1]))
			break ;
	if (i == Nr_numiface) {
		printf("Interface \"%s\" not found\n",argv[1]) ;
		return 1 ;
	}
		
	nr_bcnodes(i) ;
	return 0;
}

/* Set outbound node broadcast interval */
static int
donodetimer(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	if(argc < 2){
		printf("Nodetimer %lu/%lu seconds\n",
			read_timer(&Nodetimer)/1000L,
			dur_timer(&Nodetimer)/1000L);
		return 0;
	}
	stop_timer(&Nodetimer) ;	/* in case it's already running */
	Nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
	Nodetimer.arg = NULL;		/* dummy value */
	set_timer(&Nodetimer,atoi(argv[1])*1000L);/* set timer duration */
	start_timer(&Nodetimer);		/* and fire it up */
	return 0;
}

static void
donodetick()
{
	register int i ;

	for (i = 0 ; i < Nr_numiface ; i++)
		nr_bcnodes(i) ;

	/* Restart timer */
	start_timer(&Nodetimer) ;
}

/* Set timer for aging routes */
static int
doobsotimer(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	if(argc < 2){
		printf("Obsotimer %lu/%lu seconds\n",
			read_timer(&Obsotimer)/1000L,
			dur_timer(&Obsotimer)/1000L);
		return 0;
	}
	stop_timer(&Obsotimer) ;	/* just in case it's already running */
	Obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
	Obsotimer.arg = NULL;		/* dummy value */
	set_timer(&Obsotimer,atoi(argv[1])*1000L);	/* set timer duration */
	start_timer(&Obsotimer);		/* and fire it up */
	return 0;
}


/* Go through the routing table, reducing the obsolescence count of
 * non-permanent routes, and purging them if the count reaches 0
 */
static void
doobsotick()
{
	register struct nrnbr_tab *np ;
	register struct nrroute_tab *rp, *rpnext ;
	register struct nr_bind *bp, *bpnext ;
	int i ;

	for (i = 0 ; i < NRNUMCHAINS ; i++) {
		for (rp = Nrroute_tab[i] ; rp != NULL ; rp = rpnext) {
			rpnext = rp->next ; 	/* save in case we free this route */
			for (bp = rp->routes ; bp != NULL ; bp = bpnext) {
				bpnext = bp->next ;	/* in case we free this binding */
				if (bp->flags & NRB_PERMANENT)	/* don't age these */
					continue ;
				if (--bp->obsocnt == 0) {		/* time's up! */
					if (bp->next != NULL)
						bp->next->prev = bp->prev ;
					if (bp->prev != NULL)
						bp->prev->next = bp->next ;
					else
						rp->routes = bp->next ;
					rp->num_routes-- ;			/* one less binding */
					np = bp->via ;				/* find the neighbor */
					free(bp) ;				/* now we can free the bind */
					/* Check to see if we can free the neighbor */
					if (--np->refcnt == 0) {
						if (np->next != NULL)
							np->next->prev = np->prev ;
						if (np->prev != NULL)
							np->prev->next = np->next ;
						else {
							Nrnbr_tab[nrhash(np->call)] = np->next ;
						}
						free(np) ;	/* free the storage */
					}
				}
			}
			if (rp->num_routes == 0) {		/* did we free them all? */
				if (rp->next != NULL)
					rp->next->prev = rp->prev ;
				if (rp->prev != NULL)
					rp->prev->next = rp->next ;
				else
					Nrroute_tab[i] = rp->next ;

				free(rp) ;
			}
		}
	}

	start_timer(&Obsotimer) ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -