]>
git.saurik.com Git - apple/network_cmds.git/blob - routed.tproj/main.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1983, 1988, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgment:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * @(#)defs.h 8.1 (Berkeley) 6/5/93
61 * Routing Table Management Daemon
64 #include <sys/ioctl.h>
70 #include <sys/errno.h>
71 #include <sys/signal.h>
72 #include <sys/syslog.h>
73 #include "pathnames.h"
75 int supplier
= -1; /* process should supply updates */
76 int gateway
= 0; /* 1 if we are a gateway to parts beyond */
78 int bufspace
= 127*1024; /* max. input buffer size to request */
80 struct rip
*msg
= (struct rip
*)packet
;
81 void hup(), rtdeleteall(), sigtrace(), timer();
83 int getsocket(int, int, struct sockaddr_in
*);
85 void timevalsub( struct timeval
*, struct timeval
*);
92 int n
, nfd
, omask
, tflags
= 0;
93 struct timeval
*tvp
, waittime
;
94 struct itimerval itval
;
95 register struct rip
*query
= msg
;
100 openlog("routed", LOG_PID
| LOG_ODELAY
, LOG_DAEMON
);
101 setlogmask(LOG_UPTO(LOG_WARNING
));
103 openlog("routed", LOG_PID
);
104 #define LOG_UPTO(x) (x)
105 #define setlogmask(x) (x)
107 sp
= getservbyname("router", "udp");
109 fprintf(stderr
, "routed: router/udp: unknown service\n");
112 addr
.sin_family
= AF_INET
;
113 addr
.sin_port
= sp
->s_port
;
114 r
= socket(AF_ROUTE
, SOCK_RAW
, 0);
115 /* later, get smart about lookingforinterfaces */
117 shutdown(r
, 0); /* for now, don't want reponses */
119 fprintf(stderr
, "routed: no routing socket\n");
122 s
= getsocket(AF_INET
, SOCK_DGRAM
, &addr
);
126 while (argc
> 0 && **argv
== '-') {
127 if (strcmp(*argv
, "-s") == 0) {
132 if (strcmp(*argv
, "-q") == 0) {
137 if (strcmp(*argv
, "-t") == 0) {
139 setlogmask(LOG_UPTO(LOG_DEBUG
));
143 if (strcmp(*argv
, "-d") == 0) {
145 setlogmask(LOG_UPTO(LOG_DEBUG
));
149 if (strcmp(*argv
, "-g") == 0) {
155 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
159 if (debug
== 0 && tflags
== 0)
162 * Any extra argument is considered
163 * a tracing log file.
170 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
172 * Collect an initial view of the world by
173 * checking the interface configuration and the gateway kludge
174 * file. Then, send a request packet on all
175 * directly connected networks to find out what
176 * everyone else thinks.
185 query
->rip_cmd
= RIPCMD_REQUEST
;
186 query
->rip_vers
= RIPVERSION
;
187 query
->rip_nets
[0].rip_dst
.sa_family
= AF_UNSPEC
;
188 query
->rip_nets
[0].rip_dst
.sa_len
= sizeof (query
->rip_nets
[0].rip_dst
);
189 query
->rip_nets
[0].rip_metric
= htonl((u_long
)HOPCNT_INFINITY
);
190 toall((int (*)())sndmsg
, 0, NULL
);
191 signal(SIGALRM
, timer
);
193 signal(SIGTERM
, hup
);
194 signal(SIGINT
, rtdeleteall
);
195 signal(SIGUSR1
, sigtrace
);
196 signal(SIGUSR2
, sigtrace
);
197 itval
.it_interval
.tv_sec
= TIMER_RATE
;
198 itval
.it_value
.tv_sec
= TIMER_RATE
;
199 itval
.it_interval
.tv_usec
= 0;
200 itval
.it_value
.tv_usec
= 0;
202 if (setitimer(ITIMER_REAL
, &itval
, (struct itimerval
*)NULL
) < 0)
203 syslog(LOG_ERR
, "setitimer: %m\n");
206 nfd
= s
+ 1; /* 1 + max(fd's) */
210 * If we need a dynamic update that was held off,
211 * needupdate will be set, and nextbcast is the time
212 * by which we want select to return. Compute time
213 * until dynamic update should be sent, and select only
214 * until then. If we have already passed nextbcast,
218 waittime
= nextbcast
;
219 timevalsub(&waittime
, &now
);
220 if (waittime
.tv_sec
< 0) {
222 waittime
.tv_usec
= 0;
226 "select until dynamic update %ld/%d sec/usec\n",
227 waittime
.tv_sec
, waittime
.tv_usec
);
230 tvp
= (struct timeval
*)NULL
;
231 n
= select(nfd
, &ibits
, 0, 0, tvp
);
234 * Need delayed dynamic update if select returned
235 * nothing and we timed out. Otherwise, ignore
236 * errors (e.g. EINTR).
241 syslog(LOG_ERR
, "select: %m");
243 omask
= sigblock(sigmask(SIGALRM
));
244 if (n
== 0 && needupdate
) {
247 "send delayed dynamic update\n");
248 (void) gettimeofday(&now
,
249 (struct timezone
*)NULL
);
250 toall((int (*)())supply
, RTS_CHANGED
,
251 (struct interface
*)NULL
);
254 nextbcast
.tv_sec
= 0;
259 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
260 omask
= sigblock(sigmask(SIGALRM
));
263 printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n",
266 (s)/(sizeof(fd_mask) * 8),
267 ((s) % (sizeof(fd_mask) * 8)),
268 (1 << ((s) % (sizeof(fd_mask) * 8))),
269 ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))),
273 if (FD_ISSET(s
, &ibits
))
275 if (ibits
.fds_bits
[s
/32] & (1 << s
))
278 /* handle ICMP redirects */
287 struct timeval
*t1
, *t2
;
290 t1
->tv_sec
+= t2
->tv_sec
;
291 if ((t1
->tv_usec
+= t2
->tv_usec
) > 1000000) {
293 t1
->tv_usec
-= 1000000;
299 struct timeval
*t1
, *t2
;
302 t1
->tv_sec
-= t2
->tv_sec
;
303 if ((t1
->tv_usec
-= t2
->tv_usec
) < 0) {
305 t1
->tv_usec
+= 1000000;
313 struct sockaddr from
;
317 char buf
[MAXPACKETSIZE
+1];
322 fromlen
= sizeof (from
);
323 cc
= recvfrom(fd
, &inbuf
, sizeof (inbuf
), 0, &from
, &fromlen
);
325 if (cc
< 0 && errno
!= EWOULDBLOCK
)
329 if (fromlen
!= sizeof (struct sockaddr_in
))
331 rip_input(&from
, &inbuf
.rip
, cc
);
336 getsocket(domain
, type
, sin
)
338 struct sockaddr_in
*sin
;
342 if ((sock
= socket(domain
, type
, 0)) < 0) {
344 syslog(LOG_ERR
, "socket: %m");
348 if (setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof (on
)) < 0) {
349 syslog(LOG_ERR
, "setsockopt SO_BROADCAST: %m");
355 for (on
= bufspace
; ; on
-= 1024) {
356 if (setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
,
357 &on
, sizeof (on
)) == 0)
360 syslog(LOG_ERR
, "setsockopt SO_RCVBUF: %m");
365 fprintf(ftrace
, "recv buf %d\n", on
);
367 if (bind(sock
, (struct sockaddr
*)sin
, sizeof (*sin
)) < 0) {
369 syslog(LOG_ERR
, "bind: %m");
373 if (fcntl(sock
, F_SETFL
, O_NONBLOCK
) == -1)
374 syslog(LOG_ERR
, "fcntl O_NONBLOCK: %m\n");