]>
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 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1983, 1988, 1993
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgment:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * @(#)defs.h 8.1 (Berkeley) 6/5/93
60 * Routing Table Management Daemon
63 #include <sys/ioctl.h>
68 #include <sys/errno.h>
69 #include <sys/signal.h>
70 #include <sys/syslog.h>
71 #include "pathnames.h"
73 int supplier
= -1; /* process should supply updates */
74 int gateway
= 0; /* 1 if we are a gateway to parts beyond */
76 int bufspace
= 127*1024; /* max. input buffer size to request */
78 struct rip
*msg
= (struct rip
*)packet
;
79 void hup(), rtdeleteall(), sigtrace(), timer();
85 int n
, cc
, nfd
, omask
, tflags
= 0;
87 struct timeval
*tvp
, waittime
;
88 struct itimerval itval
;
89 register struct rip
*query
= msg
;
95 openlog("routed", LOG_PID
| LOG_ODELAY
, LOG_DAEMON
);
96 setlogmask(LOG_UPTO(LOG_WARNING
));
98 openlog("routed", LOG_PID
);
99 #define LOG_UPTO(x) (x)
100 #define setlogmask(x) (x)
102 sp
= getservbyname("router", "udp");
104 fprintf(stderr
, "routed: router/udp: unknown service\n");
107 addr
.sin_family
= AF_INET
;
108 addr
.sin_port
= sp
->s_port
;
109 r
= socket(AF_ROUTE
, SOCK_RAW
, 0);
110 /* later, get smart about lookingforinterfaces */
112 shutdown(r
, 0); /* for now, don't want reponses */
114 fprintf(stderr
, "routed: no routing socket\n");
117 s
= getsocket(AF_INET
, SOCK_DGRAM
, &addr
);
121 while (argc
> 0 && **argv
== '-') {
122 if (strcmp(*argv
, "-s") == 0) {
127 if (strcmp(*argv
, "-q") == 0) {
132 if (strcmp(*argv
, "-t") == 0) {
134 setlogmask(LOG_UPTO(LOG_DEBUG
));
138 if (strcmp(*argv
, "-d") == 0) {
140 setlogmask(LOG_UPTO(LOG_DEBUG
));
144 if (strcmp(*argv
, "-g") == 0) {
150 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
154 if (debug
== 0 && tflags
== 0)
157 * Any extra argument is considered
158 * a tracing log file.
165 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
167 * Collect an initial view of the world by
168 * checking the interface configuration and the gateway kludge
169 * file. Then, send a request packet on all
170 * directly connected networks to find out what
171 * everyone else thinks.
180 query
->rip_cmd
= RIPCMD_REQUEST
;
181 query
->rip_vers
= RIPVERSION
;
182 if (sizeof(query
->rip_nets
[0].rip_dst
.sa_family
) > 1) /* XXX */
183 query
->rip_nets
[0].rip_dst
.sa_family
= htons((u_short
)AF_UNSPEC
);
185 query
->rip_nets
[0].rip_dst
.sa_family
= AF_UNSPEC
;
186 query
->rip_nets
[0].rip_metric
= htonl((u_long
)HOPCNT_INFINITY
);
188 signal(SIGALRM
, timer
);
190 signal(SIGTERM
, hup
);
191 signal(SIGINT
, rtdeleteall
);
192 signal(SIGUSR1
, sigtrace
);
193 signal(SIGUSR2
, sigtrace
);
194 itval
.it_interval
.tv_sec
= TIMER_RATE
;
195 itval
.it_value
.tv_sec
= TIMER_RATE
;
196 itval
.it_interval
.tv_usec
= 0;
197 itval
.it_value
.tv_usec
= 0;
199 if (setitimer(ITIMER_REAL
, &itval
, (struct itimerval
*)NULL
) < 0)
200 syslog(LOG_ERR
, "setitimer: %m\n");
203 nfd
= s
+ 1; /* 1 + max(fd's) */
207 * If we need a dynamic update that was held off,
208 * needupdate will be set, and nextbcast is the time
209 * by which we want select to return. Compute time
210 * until dynamic update should be sent, and select only
211 * until then. If we have already passed nextbcast,
215 waittime
= nextbcast
;
216 timevalsub(&waittime
, &now
);
217 if (waittime
.tv_sec
< 0) {
219 waittime
.tv_usec
= 0;
223 "select until dynamic update %d/%d sec/usec\n",
224 waittime
.tv_sec
, waittime
.tv_usec
);
227 tvp
= (struct timeval
*)NULL
;
228 n
= select(nfd
, &ibits
, 0, 0, tvp
);
231 * Need delayed dynamic update if select returned
232 * nothing and we timed out. Otherwise, ignore
233 * errors (e.g. EINTR).
238 syslog(LOG_ERR
, "select: %m");
240 omask
= sigblock(sigmask(SIGALRM
));
241 if (n
== 0 && needupdate
) {
244 "send delayed dynamic update\n");
245 (void) gettimeofday(&now
,
246 (struct timezone
*)NULL
);
247 toall(supply
, RTS_CHANGED
,
248 (struct interface
*)NULL
);
251 nextbcast
.tv_sec
= 0;
256 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
257 omask
= sigblock(sigmask(SIGALRM
));
260 printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n",
263 (s)/(sizeof(fd_mask) * 8),
264 ((s) % (sizeof(fd_mask) * 8)),
265 (1 << ((s) % (sizeof(fd_mask) * 8))),
266 ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))),
270 if (FD_ISSET(s
, &ibits
))
272 if (ibits
.fds_bits
[s
/32] & (1 << s
))
275 /* handle ICMP redirects */
281 struct timeval
*t1
, *t2
;
284 t1
->tv_sec
+= t2
->tv_sec
;
285 if ((t1
->tv_usec
+= t2
->tv_usec
) > 1000000) {
287 t1
->tv_usec
-= 1000000;
292 struct timeval
*t1
, *t2
;
295 t1
->tv_sec
-= t2
->tv_sec
;
296 if ((t1
->tv_usec
-= t2
->tv_usec
) < 0) {
298 t1
->tv_usec
+= 1000000;
305 struct sockaddr from
;
308 char buf
[MAXPACKETSIZE
+1];
313 fromlen
= sizeof (from
);
314 cc
= recvfrom(fd
, &inbuf
, sizeof (inbuf
), 0, &from
, &fromlen
);
316 if (cc
< 0 && errno
!= EWOULDBLOCK
)
320 if (fromlen
!= sizeof (struct sockaddr_in
))
322 rip_input(&from
, &inbuf
.rip
, cc
);
326 getsocket(domain
, type
, sin
)
328 struct sockaddr_in
*sin
;
332 if ((sock
= socket(domain
, type
, 0)) < 0) {
334 syslog(LOG_ERR
, "socket: %m");
338 if (setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof (on
)) < 0) {
339 syslog(LOG_ERR
, "setsockopt SO_BROADCAST: %m");
345 for (on
= bufspace
; ; on
-= 1024) {
346 if (setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
,
347 &on
, sizeof (on
)) == 0)
350 syslog(LOG_ERR
, "setsockopt SO_RCVBUF: %m");
355 fprintf(ftrace
, "recv buf %d\n", on
);
357 if (bind(sock
, (struct sockaddr
*)sin
, sizeof (*sin
)) < 0) {
359 syslog(LOG_ERR
, "bind: %m");
363 if (fcntl(sock
, F_SETFL
, O_NONBLOCK
) == -1)
364 syslog(LOG_ERR
, "fcntl O_NONBLOCK: %m\n");