예제 #1
0
int cfg_proc(void)
{
unsigned int	i;
char argv[MAX_ARGS][MAX_ARG_LEN+1];
int	argc = 0;
int arg_idx = 0;

	for(i=0; ch_buf[i]!='\0'; i++)
	{
		if(ch_buf[i]==' '){
			argv[argc][arg_idx]='\0';
			argc++;
			arg_idx=0;
		}
		else {
			if(arg_idx<MAX_ARG_LEN)
			{	
				argv[argc][arg_idx]=ch_buf[i];
				arg_idx++;
			}
		}
	}
	argv[argc][arg_idx]='\0';
	//printf("cfg file arg[0]=%s\n",argv[0]);
	if(!strcmp(argv[0], "version")) {
		int new_ripversion = atoi(argv[1]);
		if(ripversion!=new_ripversion) {
			if(ripversion && new_ripversion == 0){				
				clean();
			}
			if(ripversion==0 && new_ripversion) {
				rtinit();
				ifinit();
				rip_input_init();
				rip_request_send();
			}
			ripversion = new_ripversion;
		}		
	}
	else
	if(!strcmp(argv[0], "network")) {
		// Modified by Mason Yu for bind interface
		//if_chk_add(argv[1]);
#ifndef CONFIG_BOA_WEB_E8B_CH
		if_chk_add(argv[1], atoi(argv[2]), atoi(argv[3]));
#else
		if_chk_add(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
#endif
	}
	else
	if(!strcmp(argv[0], "debug")) {
		debug = 1;
	}

	memset(argv, 0, sizeof(argv));
	return 0;
}
예제 #2
0
void timer(int signum)
{
	register struct rthash *rh;
	register struct rt_entry *rt;
	struct rthash *base = hosthash;
	int doinghost = 1, timetobroadcast;

	(void)signum;

	(void) gettimeofday(&now, (struct timezone *)NULL);
	faketime += TIMER_RATE;
	if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0)
		ifinit();
	timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0;
again:
	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
		rt = rh->rt_forw;
		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
			/*
			 * We don't advance time on a routing entry for
			 * a passive gateway, or any interface if we're
			 * not acting as supplier.
			 */
			if (!(rt->rt_state & RTS_PASSIVE) &&
			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
				rt->rt_timer += TIMER_RATE;
			if (rt->rt_timer >= GARBAGE_TIME) {
				rt = rt->rt_back;
				rtdelete(rt->rt_forw);
				continue;
			}
			if (rt->rt_timer >= EXPIRE_TIME &&
			    rt->rt_metric < HOPCNT_INFINITY)
				rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
			rt->rt_state &= ~RTS_CHANGED;
		}
	}
	if (doinghost) {
		doinghost = 0;
		base = nethash;
		goto again;
	}
	if (timetobroadcast) {
		toall(supply, 0, (struct interface *)NULL);
		lastbcast = now;
		lastfullupdate = now;
		needupdate = 0;		/* cancel any pending dynamic update */
		nextbcast.tv_sec = 0;
	}
#ifdef EMBED
	signal(signum, timer);
#endif
}
예제 #3
0
oskit_error_t 
oskit_freebsd_net_init(oskit_services_t *osenv, oskit_socket_factory_t **f)
#endif
{
	struct proc p;

	OSKIT_FREEBSD_CREATE_CURPROC(p);
#ifdef INDIRECT_OSENV
	freebsd_oskit_osenv_init(osenv);
#endif
	oskit_freebsd_init();



	initialize_netisr_linker_set();
	initialize_domain_linker_set();

        /*
         * Quickly wire in netisrs.
         */
        setup_netisrs((struct linker_set *)&netisr_set);

        /* Initialize mbuf's and protocols. */
        ifinit(0);
	mbinit(0);
        domaininit(0);

	loopattach(0);

	OSKIT_FREEBSD_DESTROY_CURPROC(p);

	/*
	 * register our socket factory
	 */
	*f = &(oskit_freebsd_net_impl.sf);

	return 0;
}
예제 #4
0
파일: rip.c 프로젝트: deepfield/MRT
main () {

   ROUTE_MANAGER = (Route_Manager_Struct *) New_Route_Manager (32);

   ifinit ();

   init_timer_master();

   init_rip ();

   if (init_rip_listen () == -1) {
      printf("\ninit_rip_listen failed!");
      exit (0);
   }

   init_rip_broadcast ();

   /* broadcast request for routes */
   rip_send_request ();

   while (1) 
      mrt_select ();
}
예제 #5
0
/*
 * Timer routine.  Performs routing information supply
 * duties and manages timers on routing and SAP table entries.
 */
void
timer(void)
{
	struct rthash *rh;
	struct rt_entry *rt;
	struct sap_hash *sh;
	struct sap_entry *sap;
	struct sap_hash *sap_base = sap_head;
	int timetobroadcast, ripbroadcast, sapbroadcast;

	timeval += TIMER_RATE;
	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
		ifinit();
	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
	ripbroadcast = supplier && timetobroadcast && 
			(timeval % RIP_INTERVAL) == 0;
	sapbroadcast = timetobroadcast && dosap && !ripbroadcast;

	for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) {
		rt = rh->rt_forw;
		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
			if (rt->rt_clone) {
				struct rt_entry *trt, *prt;
				/*
				 * If a clone expire free it and mark the
				 * main route RTS_CHANGED.
				 */
				prt = rt;
				trt = rt->rt_clone;
				while (trt) {
					trt->rt_timer += TIMER_RATE;
					if (trt->rt_timer >= EXPIRE_TIME) {
						prt->rt_clone = trt->rt_clone;
						free((char *)trt);
						trt = prt->rt_clone;
						rt->rt_state |= RTS_CHANGED;
					} else {
						prt = trt;
						trt = prt->rt_clone;
					}
				}
			}
			/*
			 * We don't advance time on a routing entry for
			 * a passive gateway or that for our only interface. 
			 * The latter is excused because we don't act as
			 * a routing information supplier and hence would
			 * time it out.  This is fair as if it's down
			 * we're cut off from the world anyway and it's
			 * not likely we'll grow any new hardware in
			 * the mean time.
			 */
			if (!(rt->rt_state & RTS_PASSIVE) &&
			    !(rt->rt_state & RTS_INTERFACE))
				rt->rt_timer += TIMER_RATE;
			if (rt->rt_timer >= EXPIRE_TIME) {
				rt->rt_metric = HOPCNT_INFINITY;
				rt->rt_state |= RTS_CHANGED;
			}
			if (rt->rt_timer >= GARBAGE_TIME) {
				rt = rt->rt_back;
				/* Perhaps we should send a REQUEST for this route? */
				rtdelete(rt->rt_forw);
				continue;
			}
			if (rt->rt_state & RTS_CHANGED) {
				rt->rt_state &= ~RTS_CHANGED;
				/* don't send extraneous packets */
				if (!supplier || ripbroadcast)
					continue;
				if ((rt->rt_metric + 1) == HOPCNT_INFINITY)
					continue;
				msg->rip_cmd = htons(RIPCMD_RESPONSE);
				msg->rip_nets[0].rip_dst =
					(satoipx_addr(rt->rt_dst)).x_net;
				msg->rip_nets[0].rip_metric =
				   	htons(min(rt->rt_metric+1, HOPCNT_INFINITY));
				msg->rip_nets[0].rip_ticks = 
					htons(rt->rt_ticks + 1);
				toall(sndmsg, rt, 0);
			}
		}
	}
	if (ripbroadcast)
		toall(supply, NULL, 0);

	/* 
	 * Now do the SAP stuff.
	 */
	for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) {
		sap = sh->forw;
		for (; sap != (struct sap_entry *)sh; sap = sap->forw) {
			if (sap->clone) {
				struct sap_entry *tsap, *psap;
				/*
				 * If a clone expire free it and mark the
				 * main sap entry RTS_CHANGED.
				 */
				psap = sap;
				tsap = sap->clone;
				while (tsap) {
					tsap->timer += TIMER_RATE;
					if (tsap->timer >= EXPIRE_TIME) {
						psap->clone = tsap->clone;
						free((char *)tsap);
						tsap = psap->clone;
						sap->state |= RTS_CHANGED;
					} else {
						psap = tsap;
						tsap = psap->clone;
					}
				}
			}
			sap->timer += TIMER_RATE;
			if (sap->timer >= EXPIRE_TIME) {
				sap->sap.hops = htons(HOPCNT_INFINITY);
				sap->state |= RTS_CHANGED;
			}
			if (sap->timer >= GARBAGE_TIME) {
				sap = sap->back;
				/* Perhaps we should send a REQUEST for this route? */
				sap_delete(sap->forw);
				continue;
			}
			/*
			 * XXX sap_sndmsg on RTS_CHANGED
			 */
			if (sap->state & RTS_CHANGED) {
				sap->state &= ~RTS_CHANGED;
#ifdef notyet
				/* don't send extraneous packets */
				if (!supplier || sapbroadcast)
					continue;
				if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY)
					continue;
				sap_msg->sap_cmd = htons(SAP_RESP);
				sap_msg->sap[0] = sap->sap;
				sap_msg->sap[0].hops =
				    htons(min(sap->sap.hops+1, HOPCNT_INFINITY));
				toall(sapsndmsg, rt, 0);
#endif
			}
		}
	}
	if (sapbroadcast)
		sap_supply_toall(0);
	if (ftrace && sapbroadcast)
		dumpsaptable(ftrace, sap_head);
}
예제 #6
0
파일: ripd.c 프로젝트: carriercomm/myboxfs
int
ripd(int argc, char *argv[])
{
	int n, nfd, tflags = 0, ch;
	struct timeval *tvp, waittime;
	struct itimerval itval;
	struct rip *query = msg;
	fd_set ibits;
	sigset_t sigset, osigset;
	
	while ((ch = getopt(argc, argv, "sqtdg")) != EOF) {
		switch (ch) {
			case 's': supplier = 1; break;
			case 'q': supplier = 0; break;
			case 't': 
				tflags++;
				break;
			case 'd': 
				debug++;
				setlogmask(LOG_UPTO(LOG_DEBUG));
				break;
			case 'g': gateway = 1; break;
			default:
				fprintf(stderr, "%% Incomplete command\r\n");
				return(1);
		}
	}

	getkversion();

	sock = getsocket();
	assert(sock>=0);

	openlog("ripd", LOG_PID | LOG_ODELAY, LOG_DAEMON);

	if (debug == 0 && tflags == 0) {
		switch (fork()) {
			case -1: perror("fork"); exit(1);
			case 0: break;   /* child */
			default: exit(0);  /* parent */
		}
		close(0);
		close(1);
		close(2);
		setsid();
		setlogmask(LOG_UPTO(LOG_WARNING));
	}
	else {
		setlogmask(LOG_UPTO(LOG_DEBUG));
	}
	/* pid */	
	pidfile = fopen( "/var/run/ripd.pid", "w" ) ;
	if (pidfile==NULL)
	{
	    fprintf(stderr,"%% Error write pid\n");
	    return (-1);
	}
	else fprintf(pidfile,"%d", (int) getpid());
	fclose(pidfile);    
	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 * 
	 * Note: because traceon() redirects stderr, anything planning to
	 * crash on startup should do so before this point.
	 */

	if (argc > optind) {
		traceon(argv[optind]);
	}
	while (tflags-- > 0) {
		bumploglevel();
	}

	gettimeofday(&now, NULL);

	/*
	 * Collect an initial view of the world by
	 * checking the interface configuration and the gateway kludge
	 * file.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */

	rtinit();
	ifinit();
	gwkludge();
	if (gateway > 0) {
		rtdefault();
	}
	if (supplier < 0) {
		supplier = 0;
	}
	query->rip_cmd = RIPCMD_REQUEST;
	query->rip_vers = RIPVERSION;
	if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) {
		/* XXX */
		query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC);
	}
	else {
		/* unreachable code (at least on most platforms) */
		query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
	}
	query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY);

	toall(sndmsg, 0, NULL);

	signal(SIGALRM, timer);
	signal(SIGHUP, hup);
	signal(SIGTERM, hup);
	signal(SIGINT, rtdeleteall);
	signal(SIGUSR1, sigtrace);
	signal(SIGUSR2, sigtrace);

	itval.it_interval.tv_sec = TIMER_RATE;
	itval.it_value.tv_sec = TIMER_RATE;
	itval.it_interval.tv_usec = 0;
	itval.it_value.tv_usec = 0;

	srandom(time(NULL) ^ getpid());

	if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) {
		syslog(LOG_ERR, "setitimer: %m\n");
	}

	FD_ZERO(&ibits);
	nfd = sock + 1;			/* 1 + max(fd's) */
	for (;;) {
		FD_SET(sock, &ibits);

		/*
		 * If we need a dynamic update that was held off,
		 * needupdate will be set, and nextbcast is the time
		 * by which we want select to return.  Compute time
		 * until dynamic update should be sent, and select only
		 * until then.  If we have already passed nextbcast,
		 * just poll.
		 */
		if (needupdate) {
			waittime = nextbcast;
			timevalsub(&waittime, &now);
			if (waittime.tv_sec < 0) {
				waittime.tv_sec = 0;
				waittime.tv_usec = 0;
			}
			if (traceactions)
				fprintf(ftrace,
				 "select until dynamic update %ld/%ld sec/usec\n",
				    (long)waittime.tv_sec, (long)waittime.tv_usec);
			tvp = &waittime;
		}
		else {
			tvp = (struct timeval *)NULL;
		}

		n = select(nfd, &ibits, 0, 0, tvp);
		if (n <= 0) {
			/*
			 * Need delayed dynamic update if select returned
			 * nothing and we timed out.  Otherwise, ignore
			 * errors (e.g. EINTR).
			 */
			if (n < 0) {
				if (errno == EINTR)
					continue;
				syslog(LOG_ERR, "select: %m");
			}
			sigemptyset(&sigset);
			sigaddset(&sigset, SIGALRM);
			sigprocmask(SIG_BLOCK, &sigset, &osigset);
			if (n == 0 && needupdate) {
				if (traceactions)
					fprintf(ftrace,
					    "send delayed dynamic update\n");
				(void) gettimeofday(&now,
					    (struct timezone *)NULL);
				toall(supply, RTS_CHANGED,
				    (struct interface *)NULL);
				lastbcast = now;
				needupdate = 0;
				nextbcast.tv_sec = 0;
			}
			sigprocmask(SIG_SETMASK, &osigset, NULL);
			continue;
		}

		gettimeofday(&now, (struct timezone *)NULL);
		sigemptyset(&sigset);
		sigaddset(&sigset, SIGALRM);
		sigprocmask(SIG_BLOCK, &sigset, &osigset);

		if (FD_ISSET(sock, &ibits)) {
			process(sock);
		}

		/* handle ICMP redirects */
		sigprocmask(SIG_SETMASK, &osigset, NULL);
	}
}
예제 #7
0
int
main(int argc, char *argv[])
{
	int s, rtsock, maxfd, ch;
	int once = 0;
	struct timeval *timeout;
	struct fd_set fdset;
	char *argv0;
	const char *opts;

	/*
	 * Initialization
	 */
	argv0 = argv[0];

	/* get option */
	if (argv0 && argv0[strlen(argv0) - 1] != 'd') {
		fflag = 1;
		once = 1;
		opts = "adD";
	} else
		opts = "adDfm1";

	while ((ch = getopt(argc, argv, opts)) != -1) {
		switch (ch) {
		case 'a':
			aflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 'D':
			dflag = 2;
			break;
		case 'f':
			fflag = 1;
			break;
		case 'm':
			mobile_node = 1;
			break;
		case '1':
			once = 1;
			break;
		default:
			usage(argv0);
			/*NOTREACHED*/
		}
	}
	argc -= optind;
	argv += optind;

	if (aflag) {
		int i;

		if (argc != 0) {
			usage(argv0);
			/*NOTREACHED*/
		}

		argv = autoifprobe();
		if (!argv) {
			errx(1, "could not autoprobe interface");
			/*NOTREACHED*/
		}

		for (i = 0; argv[i]; i++)
			;
		argc = i;
	}
	if (argc == 0) {
		usage(argv0);
		/*NOTREACHED*/
	}

	/* set log level */
	if (dflag == 0)
		log_upto = LOG_NOTICE;
	if (!fflag) {
		char *ident;
		ident = strrchr(argv0, '/');
		if (!ident)
			ident = argv0;
		else
			ident++;
		openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON);
		if (log_upto >= 0)
			setlogmask(LOG_UPTO(log_upto));
	}

#ifndef HAVE_ARC4RANDOM
	/* random value initilization */
	srandom((u_long)time(NULL));
#endif

	/* warn if accept_rtadv is down */
	if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
		warnx("kernel is configured not to accept RAs");
	/* warn if forwarding is up */
	if (getinet6sysctl(IPV6CTL_FORWARDING))
		warnx("kernel is configured as a router, not a host");

	/* initialization to dump internal status to a file */
	if (signal(SIGUSR1, rtsold_set_dump_file) == SIG_ERR) {
		errx(1, "failed to set signal for dump status");
		/*NOTREACHED*/
	}

	/*
	 * Open a socket for sending RS and receiving RA.
	 * This should be done before calling ifinit(), since the function
	 * uses the socket.
	 */
	if ((s = sockopen()) < 0) {
		errx(1, "failed to open a socket");
		/*NOTREACHED*/
	}
	maxfd = s;
	if ((rtsock = rtsock_open()) < 0) {
		errx(1, "failed to open a socket");
		/*NOTREACHED*/
	}
	if (rtsock > maxfd)
		maxfd = rtsock;

	/* configuration per interface */
	if (ifinit()) {
		errx(1, "failed to initilizatoin interfaces");
		/*NOTREACHED*/
	}
	while (argc--) {
		if (ifconfig(*argv)) {
			errx(1, "failed to initialize %s", *argv);
			/*NOTREACHED*/
		}
		argv++;
	}

	/* setup for probing default routers */
	if (probe_init()) {
		errx(1, "failed to setup for probing routers");
		/*NOTREACHED*/
	}

	if (!fflag)
		daemon(0, 0);		/* act as a daemon */

	/* dump the current pid */
	if (!once) {
		pid_t pid = getpid();
		FILE *fp;

		if ((fp = fopen(pidfilename, "w")) == NULL)
			warnmsg(LOG_ERR, __func__,
				"failed to open a log file(%s): %s",
				pidfilename, strerror(errno));
		else {
			fprintf(fp, "%d\n", pid);
			fclose(fp);
		}
	}

	FD_ZERO(&fdset);
	FD_SET(s, &fdset);
	FD_SET(rtsock, &fdset);
	while (1) {		/* main loop */
		int e;
		struct fd_set select_fd = fdset;

		if (do_dump) {	/* SIGUSR1 */
			do_dump = 0;
			rtsold_dump_file(dumpfilename);
		}
			
		timeout = rtsol_check_timer();

		if (once) {
			struct ifinfo *ifi;

			/* if we have no timeout, we are done (or failed) */
			if (timeout == NULL)
				break;

			/* if all interfaces have got RA packet, we are done */
			for (ifi = iflist; ifi; ifi = ifi->next) {
				if (ifi->state != IFS_DOWN && ifi->racnt == 0)
					break;
			}
			if (ifi == NULL)
				break;
		}
		e = select(maxfd + 1, &select_fd, NULL, NULL, timeout);
		if (e < 1) {
			if (e < 0 && errno != EINTR) {
				warnmsg(LOG_ERR, __func__, "select: %s",
				       strerror(errno));
			}
			continue;
		}

		/* packet reception */
		if (FD_ISSET(rtsock, &select_fd))
			rtsock_input(rtsock);
		if (FD_ISSET(s, &select_fd))
			rtsol_input(s);
	}
	/* NOTREACHED */

	return 0;
}
예제 #8
0
int
main(int argc, char *argv[])
{
	int _argc = 0;
	char *_argv[5];
	pid_t pid;
	int execed = 0;

	int n, nfd, tflags = 0, ch;
	struct timeval *tvp, waittime;
	struct itimerval itval;
	fd_set ibits;
	sigset_t sigset, osigset;

	while ((ch = getopt(argc, argv, "D012bsqtdg")) != EOF) {
		switch (ch) {
			case 'D':
				execed = 1;
				break;
			case '0': ripversion = 0; break;
			case '1': ripversion = 1; break;
			case '2': ripversion = 2; break;
			case 'b': multicast = 0; break;
			case 's': supplier = 1; break;
			case 'q': supplier = 0; break;
			case 't': 
				tflags++;
				break;
			case 'd': 
				debug++;
				setlogmask(LOG_UPTO(LOG_DEBUG));
				break;
			case 'g': gateway = 1; break;
			default:
				fprintf(stderr, "usage: routed [ -1bsqtdg ]\n");
				exit(1);
		}
	}
	
	// Modified by Mason Yu
	sleep(2);
	/*
	if(!check_pid()) {
		// Commented by Mason Yu
		//write_cfg();
		exit(1);
	}
	*/
	
	if (!execed) {
		if ((pid = vfork()) < 0) {
			fprintf(stderr, "vfork failed\n");
			exit(1);
		} else if (pid != 0) {
			exit(0);
		}
		
		for (_argc=0; _argc < argc; _argc++ )
			_argv[_argc] = argv[_argc];
		_argv[0] = runPath;
		_argv[argc++] = "-D";
		_argv[argc++] = NULL;
		execv(_argv[0], _argv);
		/* Not reached */
		fprintf(stderr, "Couldn't exec\n");
		_exit(1);

	} else {
		setsid();
	}

	getkversion();

	sock = getsocket();
	assert(sock>=0);

	openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);

#if 0
	if (debug == 0 && tflags == 0) {
#ifndef EMBED
		switch (fork()) {
			case -1: perror("fork"); exit(1);
			case 0: break;  /* child */
			default: exit(0);   /* parent */
		}
#endif
		close(0);
		close(1);
		close(2);
		setsid();
		setlogmask(LOG_UPTO(LOG_WARNING));
	}
	else 
#endif
	{
		setlogmask(LOG_UPTO(LOG_DEBUG));
	}

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 * 
	 * Note: because traceon() redirects stderr, anything planning to
	 * crash on startup should do so before this point.
	 */

	if (argc > 1) {
		traceon(argv[argc - 1]);
	}
	while (tflags-- > 0) {
		bumploglevel();
	}

	gettimeofday(&now, NULL);

	/*
	 * Collect an initial view of the world by
	 * checking the interface configuration and the gateway kludge
	 * file.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */
	 read_cfg();
	rtinit();
	ifinit();
	gwkludge();

	if (gateway > 0) {
		rtdefault();
	}

	if (supplier < 0) {
		supplier = 0;
	}

	signal(SIGALRM, timer);
	signal(SIGHUP, hup);
	signal(SIGTERM, hup);
        signal(SIGTERM, terminate_routed); //RTK WiSOC modify for deleting all route entry
	signal(SIGINT, rtdeleteall);
	signal(SIGUSR1, sigtrace);
	signal(SIGUSR2, sigtrace);

	itval.it_interval.tv_sec = TIMER_RATE;
	itval.it_value.tv_sec = TIMER_RATE;
	itval.it_interval.tv_usec = 0;
	itval.it_value.tv_usec = 0;

	srandom(time(NULL) ^ getpid());

	if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) {
		syslog(LOG_ERR, "setitimer: %m\n");
	}
	
	// Kaohj
//#ifdef EMBED //WiSOC we use pid file for system init
	write_pid();
//#endif
	rip_request_send();
	rip_input_init();
	DISPLAY_BANNER;
	FD_ZERO(&ibits);
	nfd = sock + 1;			/* 1 + max(fd's) */
	for (;;) {
		FD_SET(sock, &ibits);

		/*
		 * If we need a dynamic update that was held off,
		 * needupdate will be set, and nextbcast is the time
		 * by which we want select to return.  Compute time
		 * until dynamic update should be sent, and select only
		 * until then.  If we have already passed nextbcast,
		 * just poll.
		 */
		if (needupdate) {
			waittime = nextbcast;
			timevalsub(&waittime, &now);
			if (waittime.tv_sec < 0) {
				waittime.tv_sec = 0;
				waittime.tv_usec = 0;
			}
			if (traceactions)
				fprintf(ftrace,
				 "select until dynamic update %ld/%ld sec/usec\n",
				    (long)waittime.tv_sec, (long)waittime.tv_usec);
			tvp = &waittime;
		}
		else {
			tvp = (struct timeval *)NULL;
		}

		n = select(nfd, &ibits, 0, 0, tvp);
		if (n <= 0) {
			/*
			 * Need delayed dynamic update if select returned
			 * nothing and we timed out.  Otherwise, ignore
			 * errors (e.g. EINTR).
			 */
			if (n < 0) {
				if (errno == EINTR)
					continue;
				syslog(LOG_ERR, "select: %m");
			}
			sigemptyset(&sigset);
			sigaddset(&sigset, SIGALRM);
			sigprocmask(SIG_BLOCK, &sigset, &osigset);
			if (n == 0 && needupdate) {
				if (traceactions)
					fprintf(ftrace,
					    "send delayed dynamic update\n");
				(void) gettimeofday(&now,
					    (struct timezone *)NULL);
				toall(supply, RTS_CHANGED,
				    (struct interface *)NULL);
				lastbcast = now;
				needupdate = 0;
				nextbcast.tv_sec = 0;
			}
			sigprocmask(SIG_SETMASK, &osigset, NULL);
			continue;
		}

		gettimeofday(&now, (struct timezone *)NULL);
		sigemptyset(&sigset);
		sigaddset(&sigset, SIGALRM);
		sigprocmask(SIG_BLOCK, &sigset, &osigset);

		if (FD_ISSET(sock, &ibits)) {
			process(sock);
		}

		/* handle ICMP redirects */
		sigprocmask(SIG_SETMASK, &osigset, NULL);
	}
}
예제 #9
0
struct ifnet *
iface_make(struct ssconfig *ifc)
{
	register struct sana_softc *ssc = NULL;
	register struct IOSana2Req *req;
	struct Sana2DeviceQuery devicequery;

	/* Allocate the request for opening the device */
	if ((req = CreateIOSana2Req(NULL)) == NULL) 
	{
		__log(LOG_ERR, "iface_find(): CreateIOSana2Req failed\n");
	}
	else
	{
		req->ios2_BufferManagement = buffermanagement;

		DSANA(__log(LOG_DEBUG,"Opening device %s unit %ld", ifc->args->a_dev, *ifc->args->a_unit);)
		if (OpenDevice(ifc->args->a_dev, *ifc->args->a_unit, 
			(struct IORequest *)req, 0L))
		{
			sana2perror("OpenDevice", req);
			
			/* Allocate the interface structure */
			ssc = (struct sana_softc *)
			bsd_malloc(sizeof(*ssc) + strlen(ifc->args->a_dev) + 1,
							M_IFNET, M_WAITOK);
  
			if (!ssc)
			{
				__log(LOG_ERR, "iface_find: out of memory\n");
			}
			else
			{
				aligned_bzero_const(ssc, sizeof(*ssc));
			
				/* Save request pointers */
				ssc->ss_dev     = req->ios2_Req.io_Device;
				ssc->ss_unit    = req->ios2_Req.io_Unit;

				ssc->ss_if.if_type = IFT_OTHER;
				ssc->ss_if.if_flags &= ~(IFF_RUNNING|IFF_UP);

				/* Initialize */ 

D(bug("[AROSTCP] if_sana.c: iface_make: Current IP from config = %s\n", ifc->args[0].a_ip));
				ifc->args[0].a_ip = "0.0.0.0";
D(bug("[AROSTCP] if_sana.c: iface_make: IP set to 0.0.0.0\n"));

				ssconfig(ssc, ifc);
	
				NewList((struct List*)&ssc->ss_freereq);

				if_attach((struct ifnet*)ssc);
				ifinit();
	
				ssc->ss_next = ssq;
				ssq = ssc;
			}
		}
		else
		{
			/* Ask for our type, address length, MTU
			* Obl. bitch: nobody tells, WHO is supplying
			* DevQueryFormat and DeviceLevel
			*/
			req->ios2_Req.io_Command   = S2_DEVICEQUERY;
			req->ios2_StatData         = &devicequery;
			devicequery.SizeAvailable  = sizeof(devicequery);
			devicequery.DevQueryFormat = 0L;

			DoIO((struct IORequest *)req);
			if (req->ios2_Req.io_Error)
			{
				sana2perror("S2_DEVICEQUERY", req);
			}
			else
			{
				/* Get Our Station address */
				req->ios2_StatData = NULL;
				req->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
				DoIO((struct IORequest *)req);
		
				if (req->ios2_Req.io_Error)
				{
					sana2perror("S2_GETSTATIONADDRESS", req);
				}
				else
				{
					req->ios2_Req.io_Command = 0;
		  
					/* Allocate the interface structure */
					ssc = (struct sana_softc *)
					bsd_malloc(sizeof(*ssc) + strlen(ifc->args->a_dev) + 1,
									M_IFNET, M_WAITOK);
		  
					if (!ssc)
					{
						__log(LOG_ERR, "iface_find: out of memory\n");
					}
					else
					{
						aligned_bzero_const(ssc, sizeof(*ssc));
			
						/* Save request pointers */
						ssc->ss_dev     = req->ios2_Req.io_Device;
						ssc->ss_unit    = req->ios2_Req.io_Unit;
						ssc->ss_bufmgnt = req->ios2_BufferManagement;
						
						/* Address must be full bytes */
						ssc->ss_if.if_addrlen  = (devicequery.AddrFieldSize + 7) >> 3;
						bcopy(req->ios2_DstAddr, ssc->ss_hwaddr, ssc->ss_if.if_addrlen);
						ssc->ss_if.if_mtu      = devicequery.MTU;
						ssc->ss_maxmtu         = devicequery.MTU;
						ssc->ss_if.if_baudrate = devicequery.BPS;
						ssc->ss_hwtype         = devicequery.HardwareType;	
						
						/* These might be different on different hwtypes */
						ssc->ss_if.if_output = sana_output;
						ssc->ss_if.if_ioctl  = sana_ioctl;
						ssc->ss_if.if_query  = sana_query;

						/* Map SANA-II hardware types to RFC1573 standard */
						switch (ssc->ss_hwtype) 
						{
						case S2WireType_Ethernet:
							ssc->ss_if.if_type = IFT_ETHER;
							break;
						case S2WireType_IEEE802:
							ssc->ss_if.if_type = IFT_IEEE80211;
							break;
						case S2WireType_Arcnet:
							ssc->ss_if.if_type = IFT_ARCNET;
							break;
						case S2WireType_LocalTalk:
							ssc->ss_if.if_type = IFT_LOCALTALK;
							break;
						case S2WireType_PPP:
							ssc->ss_if.if_type = IFT_PPP;
							break;
						case S2WireType_SLIP:
						case S2WireType_CSLIP:
							ssc->ss_if.if_type = IFT_SLIP;
							break;
						case S2WireType_PLIP:
							ssc->ss_if.if_type = IFT_PARA;
							break;
						default:
							ssc->ss_if.if_type = IFT_OTHER;
						}

						/* Initialize */ 
						ssconfig(ssc, ifc);
			
						NewList((struct List*)&ssc->ss_freereq);

						if_attach((struct ifnet*)ssc);
						ifinit();
			
						ssc->ss_next = ssq;
						ssq = ssc;
					}
				}
			}
			if (!ssc)
				CloseDevice((struct IORequest *)req);
		}    
		DeleteIOSana2Req(req);
	}
예제 #10
0
int
main(int argc, char *argv[])
{
	int nfds;
	fd_set fdvar;
	time_t ttime;
	struct itimerval tval;

	argv0 = argv;
	argv++, argc--;
	while (argc > 0 && **argv == '-') {
		if (strcmp(*argv, "-s") == 0) {
			supplier = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-q") == 0) {
			supplier = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-R") == 0) {
			noteremoterequests++;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-S") == 0) {
			dosap = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-t") == 0) {
			tracepackets++;
			argv++, argc--;
			ftrace = stderr;
			tracing = 1; 
			continue;
		}
		if (strcmp(*argv, "-g") == 0) {
			gateway = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-l") == 0) {
			gateway = -1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-N") == 0) {
			dognreply = 0;
			argv++, argc--;
			continue;
		}
		fprintf(stderr,
			"usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n");
		exit(1);
	}
	
	
#ifndef DEBUG
	if (!tracepackets)
		daemon(0, 0);
#endif
	openlog("IPXrouted", LOG_PID, LOG_DAEMON);

	addr.sipx_family = AF_IPX;
	addr.sipx_len = sizeof(addr);
	addr.sipx_port = htons(IPXPORT_RIP);
	ipx_anynet.s_net[0] = ipx_anynet.s_net[1] = -1;
	ipx_netmask.sipx_addr.x_net = ipx_anynet;
	ipx_netmask.sipx_len = 6;
	ipx_netmask.sipx_family = AF_IPX;
	r = socket(AF_ROUTE, SOCK_RAW, 0);
	/* later, get smart about lookingforinterfaces */
	if (r)
		shutdown(r, SHUT_RD); /* for now, don't want reponses */
	else {
		fprintf(stderr, "IPXrouted: no routing socket\n");
		exit(1);
	}
	ripsock = getsocket(SOCK_DGRAM, 0, &addr);
	if (ripsock < 0)
		exit(1);

	if (dosap) {
		addr.sipx_port = htons(IPXPORT_SAP);
		sapsock = getsocket(SOCK_DGRAM, 0, &addr);
		if (sapsock < 0)
			exit(1);
	} else
		sapsock = -1;

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 */
	if (argc > 0)
		traceon(*argv);
	/*
	 * Collect an initial view of the world by
	 * snooping in the kernel.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */
	rtinit();
	sapinit();
	ifinit();
	if (supplier < 0)
		supplier = 0;
	/* request the state of the world */
	msg->rip_cmd = htons(RIPCMD_REQUEST);
	msg->rip_nets[0].rip_dst = ipx_anynet;
	msg->rip_nets[0].rip_metric =  htons(HOPCNT_INFINITY);
	msg->rip_nets[0].rip_ticks =  htons(-1);
	toall(sndmsg, NULL, 0);

	if (dosap) {
		sap_msg->sap_cmd = htons(SAP_REQ);
		sap_msg->sap[0].ServType = htons(SAP_WILDCARD);
		toall(sapsndmsg, NULL, 0);
	}

	signal(SIGALRM, catchtimer);
	signal(SIGHUP, hup);
	signal(SIGINT, hup);
	signal(SIGEMT, fkexit);
	signal(SIGINFO, getinfo);
 
	tval.it_interval.tv_sec = TIMER_RATE;
	tval.it_interval.tv_usec = 0;
	tval.it_value.tv_sec = TIMER_RATE;
	tval.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &tval, NULL);

	nfds = 1 + max(sapsock, ripsock);

	for (;;) {
		if (dobcast) {
			dobcast = 0;
			lastbcast = time(NULL);
			timer();
		}

		FD_ZERO(&fdvar);
		if (dosap) {
			FD_SET(sapsock, &fdvar);
		}
		FD_SET(ripsock, &fdvar);

		if(select(nfds, &fdvar, NULL, NULL, NULL) < 0) {
			if(errno == EINTR)
				continue;
			perror("during select");
			exit(1);
		}

		if(FD_ISSET(ripsock, &fdvar))
			process(ripsock, RIP_PKT);

		if(dosap && FD_ISSET(sapsock, &fdvar))
			process(sapsock, SAP_PKT);

		ttime = time(NULL);
		if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) {
			dobcast = 1;
			syslog(LOG_ERR, "Missed alarm");
		}
	}
}