1 /* run.c The main command loop
3 * $Id: run.c,v 1.10 1995/03/19 17:21:06 bdale Exp $
5 * Copyright 1991, Michael Westerhof, Sun Microsystems, Inc.
6 * This software may be freely used, distributed, or modified, providing
7 * this header is not removed.
14 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <netinet/in_systm.h>
19 #include <netinet/ip.h>
30 static int find_route();
33 int martian_count = 3;
34 unsigned int martians[] = { 0x7f000001, 0xffffffff, 0x00000000 };
37 /* This is a loop counter for misc stuff. We don't want to burden the
38 I/O system if we don't have to, so this is designed so that we will
39 be able to see if we have to print stats or fflush() no more often
40 than once per second if we are busy. If we are idle, the time value
41 to the select() call will bring the delay up to 10 seconds. So, the
42 stats output and the flush of stdio() should be within 10 seconds of
44 #define SEND_CHECK_CNT 100;
47 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
48 * Open all io, then start running it!
49 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
54 int i, j, nb, more_io, checker;
58 for(i=0;i<ifs_top;i++){
59 if(ifs[i].type == IF_TYPE_NONE)continue;
61 syslog(LOG_DEBUG,"opening interface %s",ifs[i].id);
62 j = ifs[i].ifopen(&ifs[i]);
67 syslog(LOG_DEBUG,"initialization complete");
69 last_send = time(NULL);
78 for(i=0;i<ifs_top;i++){
79 if((ifs[i].type != IF_TYPE_NONE) &&
80 (ifs[i].status & IF_STAT_OPEN)){
81 FD_SET(ifs[i].fd, &readfds);
82 if(ifs[i].status & IF_STAT_CALL_AGAIN)more_io++;
87 wait.tv_sec = 0; /* Don't wait long! */
88 wait.tv_usec = 10000; /* 10 msecs if chars in buffer */
90 wait.tv_sec = 10; /* lets keep things going... */
91 wait.tv_usec = 0; /* but slowly is ok */
92 checker = 0; /* make sure we check the time */
95 nb = select(FD_SETSIZE,&readfds,(fd_set *)0,(fd_set *)0,&wait);
98 if(errno == EINTR)continue; /* Ignore this error */
99 PERR("select in run_it()");
103 for(i=0;i<ifs_top;i++){
104 if((ifs[i].type != IF_TYPE_NONE) &&
105 (ifs[i].status & IF_STAT_OPEN)){
106 if(FD_ISSET(ifs[i].fd, &readfds) ||
107 (ifs[i].status & IF_STAT_CALL_AGAIN)){
108 if(handle(&ifs[i])<0) {
109 PERR("handle in run_it()");
114 } /* for each interface */
117 send_stats(0); /* see if we must */
118 checker = SEND_CHECK_CNT; /* reset counter */
127 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
128 * Handle the read/route/send stuff
129 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
133 struct interface *ifp;
138 unsigned int srcip, dstip;
149 n = ifp->ifread(ifp, &m);
150 if(n <= 0) return n; /* error or packet not yet complete */
154 if(find_route(&m) < 0) {
155 PERR("find_route() failed in handle()");
160 /* this is a really, really rude hack... it will prevent any frames
161 from being switched that have source or destination outside of
164 (void)memcpy( (char *)&srcip, (char *)m.msg + 12, 4);
165 (void)memcpy( (char *)&dstip, (char *)m.msg + 16, 4);
168 syslog(LOG_DEBUG,"from ip %lx, to ip %lx", srcip, dstip);
171 if ((( srcip & 0xff ) != 44) ||
172 (( dstip & 0xff ) != 44)) {
173 m.to_if=NULL; /* drop frame on the floor */
174 if(debugt)tracer(&m); /* Trace the message */
175 return 0; /* No route found */
180 /* if this is Bdale's compilation, we need to be able to go back out
181 the same interface! */
182 if(m.from_if==m.to_if){
183 m.to_if=NULL; /* Can't go out same iface! */
184 m.from_if->looped_in++;
188 if(debugt)tracer(&m); /* Trace the message */
191 PERR("route not found in handle()");
192 return 0; /* No route found */
195 if (m.to_if->ifsend(m.to_if, &m) < 0) {
196 PERR("ifsend() failed in handle()");
205 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
206 * Print a trace of a message
207 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
213 char *fromid, *toid, fbuf[32], tbuf[32];
214 unsigned char *f, *t, *iphdr;
217 fromid = m->from_if->id;
218 ftype = m->from_if->type;
219 f = (unsigned char *)&m->fip;
220 if(ftype == IF_TYPE_IPUDP)
221 (void)sprintf(fbuf,"(%d.%d.%d.%d:%d)",f[0],f[1],f[2],f[3],ntohs(m->fport));
222 else if(ftype == IF_TYPE_IPIP)
223 (void)sprintf(fbuf, "(%d.%d.%d.%d)", f[0], f[1], f[2], f[3]);
228 ttype = m->to_if->type;
229 t = (unsigned char *)&m->tip;
232 ttype = IF_TYPE_NONE;
233 t = (unsigned char *)&m->tip;
235 if(ttype == IF_TYPE_IPUDP)
236 (void)sprintf(tbuf,"(%d.%d.%d.%d:%d)",t[0],t[1],t[2],t[3],ntohs(m->tport));
237 else if(ttype == IF_TYPE_IPIP)
238 (void)sprintf(tbuf, "(%d.%d.%d.%d)",t[0],t[1],t[2],t[3]);
243 syslog(LOG_DEBUG,"%d.%d.%d.%d->%d.%d.%d.%d len %d [%s%s->%s%s]",
244 iphdr[12], iphdr[13], iphdr[14], iphdr[15],
245 iphdr[16], iphdr[17], iphdr[18], iphdr[19],
246 m->length, fromid, fbuf, toid, tbuf);
250 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
251 * find a route for a message
252 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
262 if(m==NULL) return -1; /* major internal problem :-) */
269 (void)memcpy( (char *)&d, (char *)m->msg + 16, 4);
271 for(i=0;i<martian_count;i++){
272 if(d == htonl(martians[i])){ /* Bad address! */
273 m->from_if->martians_in++;
279 for(i=0;i<rts_top;i++){
280 if((rts[i].ipaddr & rts[i].mask) == (d & rts[i].mask)){
281 m->to_if = rts[i].destif;
282 m->tip = rts[i].destaddr;
283 m->tport = rts[i].destport;
293 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
294 * Send the statistics if it's time to do so...
295 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
300 int force; /* non-zero to force a stat print */
307 if(stat_interval==0) return; /* no stat print at all? */
311 if(force==0){ /* if not being forced */
312 if(stat_interval>0){ /* and the interval is > 0 */
313 if(now < (last_send + stat_interval)) return;
321 (void)sprintf(cnow,"%2d/%2d/%2d %2d:%2d:%2d ",t->tm_mon + 1,
322 t->tm_mday,t->tm_year,t->tm_hour,t->tm_min,t->tm_sec);
325 for(i=0;i<ifs_top;i++){
326 if(ifs[i].type == IF_TYPE_NONE)continue;
327 syslog(LOG_DEBUG,"%s%-4s in %4ld out %4ld baddr %ld loop %ld bogus %ld ovrn %ld\n",
328 cnow, ifs[i].id, ifs[i].in, ifs[i].out,
329 ifs[i].martians_in,ifs[i].looped_in,
330 ifs[i].bogus_in, ifs[i].out_overruns);