Äèïëîìíàÿ ðàáîòà: Àëãîðèòìè ìàðøðóòèçàö³¿ â ìåðåæàõ
#include "pathnames.h"
#ifdef sgi
#include "math.h"
#endif
#include <signal.h>
#include <fcntl.h>
#include <sys/file.h>
pid_t mypid;
naddr myaddr; /*
system address */
char myname[MAXHOSTNAMELEN+1];
int supplier; /* supply
or broadcast updates */
int supplier_set;
int ipforwarding = 1; /* kernel
forwarding on */
int default_gateway; /* 1=advertise
default */
int background = 1;
int ridhosts; /*
1=reduce host routes */
int mhome; /*
1=want multi-homed host route */
int advertise_mhome; /* 1=must continue
adverising it */
int auth_ok = 1; /* 1=ignore
auth if we do not care */
struct timeval epoch; /* when started
*/
struct timeval clk, prev_clk;
struct timeval now; /* current idea
of time */
time_t now_stale;
time_t now_expire;
time_t now_garbage;
struct timeval next_bcast; /* next general
broadcast */
struct timeval no_flash = {EPOCH+SUPPLY_INTERVAL}; /* inhibit
flash update */
fd_set fdbits;
int sock_max;
int rip_sock = -1; /* RIP socket
*/
struct interface *rip_sock_mcast; /* current multicast
interface */
int rt_sock; /* routing
socket */
int rt_sock_seqno;
static int get_rip_sock(naddr, int);
static void timevalsub(struct timeval *, struct timeval *, struct
timeval *);
int
main(int argc,
char *argv[])
{
int n, mib[4], off;
size_t len;
char *p, *q;
struct timeval wtime, t2;
time_t dt;
fd_set ibits;
naddr p_net, p_mask;
struct interface *ifp;
struct parm parm;
char *tracename = 0;
/* Some shells are badly broken and send SIGHUP to backgrounded
* processes.
*/
signal(SIGHUP, SIG_IGN);
openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
ftrace = stdout;
gettimeofday(&clk, 0);
prev_clk = clk;
epoch = clk;
epoch.tv_sec -= EPOCH;
now.tv_sec = EPOCH;
now_stale = EPOCH - STALE_TIME;
now_expire = EPOCH - EXPIRE_TIME;
now_garbage = EPOCH - GARBAGE_TIME;
wtime.tv_sec = 0;
(void)gethostname(myname, sizeof(myname)-1);
(void)gethost(myname, &myaddr);
while ((n = getopt(argc, argv, "sqdghmAtT:F:P:")) !=
-1) {
switch (n) {
case 's':
supplier = 1;
supplier_set = 1;
break;
case 'q':
supplier = 0;
supplier_set = 1;
break;
case 'd':
background = 0;
break;
case 'g':
bzero(&parm, sizeof(parm));
parm.parm_d_metric = 1;
p = check_parms(&parm);
if (p != 0)
msglog("bad -g:
%s", p);
else
default_gateway = 1;
break;
case 'h': /* suppress extra
host routes */
ridhosts = 1;
break;
case 'm': /* advertise host
route */
mhome = 1; /* on multi-homed hosts
*/
break;
case 'A':
/* Ignore authentication if we do not
care.
* Crazy as it is, that is what RFC
1723 requires.
*/
auth_ok = 0;
break;
case 't':
new_tracelevel++;
break;
case 'T':
tracename = optarg;
break;
case 'F': /* minimal routes
for SLIP */
n = FAKE_METRIC;
p = strchr(optarg,',');
if (p && *p != '\0') {
n = (int)strtoul(p+1,
&q, 0);
if (*q == '\0'
&& n <=
HOPCNT_INFINITY-1
&& n >= 1)
*p = '\0';
}
if (!getnet(optarg, &p_net,
&p_mask)) {
msglog("bad network;
\"-F %s\"",
optarg);
break;
}
bzero(&parm, sizeof(parm));
parm.parm_net = p_net;
parm.parm_mask = p_mask;
parm.parm_d_metric = n;
p = check_parms(&parm);
if (p != 0)
msglog("bad -F:
%s", p);
break;
case 'P':
/* handle arbirary, (usually)
per-interface
* parameters.
*/
p = parse_parms(optarg, 0);
if (p != 0) {
if (strcasecmp(p,optarg))
msglog("%s
in \"%s\"", p, optarg);
else
msglog("bad
\"-P %s\"", optarg);
}
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (tracename == 0 && argc >= 1) {
tracename = *argv++;
argc--;
}
if (tracename != 0 && tracename[0] == '\0')
goto usage;
if (argc != 0) {
usage:
logbad(0, "usage: routed [-sqdghmAt] [-T
tracefile]"
" [-F net[/mask[,metric]]] [-P parms]");
}
if (geteuid() != 0)
logbad(0, "requires UID 0");
mib[0] = CTL_NET;
mib[1] = PF_INET;
mib[2] = IPPROTO_IP;
mib[3] = IPCTL_FORWARDING;
len = sizeof(ipforwarding);
if (sysctl(mib, 4, &ipforwarding, &len, 0, 0) < 0)
LOGERR("sysctl(IPCTL_FORWARDING)");
if (!ipforwarding) {
if (supplier)
msglog("-s incompatible with
ipforwarding=0");
if (default_gateway) {
msglog("-g incompatible with
ipforwarding=0");
default_gateway = 0;
}
supplier = 0;
supplier_set = 1;
}
if (default_gateway) {
if (supplier_set && !supplier) {
msglog("-g and -q
incompatible");
} else {
supplier = 1;
supplier_set = 1;
}
}
signal(SIGALRM, sigalrm);
if (!background)
signal(SIGHUP, sigterm); /* SIGHUP fatal during
debugging */
signal(SIGTERM, sigterm);
signal(SIGINT, sigterm);
signal(SIGUSR1, sigtrace_on);
signal(SIGUSR2, sigtrace_off);
/* get into the background */
#ifdef sgi
if (0 > _daemonize(background ? 0 :
(_DF_NOCHDIR|_DF_NOFORK),
new_tracelevel == 0 ? -1 :
STDOUT_FILENO,
new_tracelevel == 0 ? -1 :
STDERR_FILENO,
-1))
BADERR(0, "_daemonize()");
#else
if (background && daemon(0, new_tracelevel) < 0)
BADERR(0,"daemon()");
#endif
mypid = getpid();
srandom((int)(clk.tv_sec ^ clk.tv_usec ^ mypid));
/* prepare socket connected to the kernel.
Ñòðàíèöû: 1, 2, 3, 4, 5, 6 |