]>
git.saurik.com Git - apple/network_cmds.git/blob - routed.tproj/main.c
d1d6fac6f828cce6541950d2d66101f731c1241b
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1983, 1988, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgment:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * @(#)defs.h 8.1 (Berkeley) 6/5/93
62 * Routing Table Management Daemon
65 #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();
87 int n
, cc
, nfd
, omask
, tflags
= 0;
89 struct timeval
*tvp
, waittime
;
90 struct itimerval itval
;
91 register struct rip
*query
= msg
;
97 openlog("routed", LOG_PID
| LOG_ODELAY
, LOG_DAEMON
);
98 setlogmask(LOG_UPTO(LOG_WARNING
));
100 openlog("routed", LOG_PID
);
101 #define LOG_UPTO(x) (x)
102 #define setlogmask(x) (x)
104 sp
= getservbyname("router", "udp");
106 fprintf(stderr
, "routed: router/udp: unknown service\n");
109 addr
.sin_family
= AF_INET
;
110 addr
.sin_port
= sp
->s_port
;
111 r
= socket(AF_ROUTE
, SOCK_RAW
, 0);
112 /* later, get smart about lookingforinterfaces */
114 shutdown(r
, 0); /* for now, don't want reponses */
116 fprintf(stderr
, "routed: no routing socket\n");
119 s
= getsocket(AF_INET
, SOCK_DGRAM
, &addr
);
123 while (argc
> 0 && **argv
== '-') {
124 if (strcmp(*argv
, "-s") == 0) {
129 if (strcmp(*argv
, "-q") == 0) {
134 if (strcmp(*argv
, "-t") == 0) {
136 setlogmask(LOG_UPTO(LOG_DEBUG
));
140 if (strcmp(*argv
, "-d") == 0) {
142 setlogmask(LOG_UPTO(LOG_DEBUG
));
146 if (strcmp(*argv
, "-g") == 0) {
152 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
156 if (debug
== 0 && tflags
== 0)
159 * Any extra argument is considered
160 * a tracing log file.
167 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
169 * Collect an initial view of the world by
170 * checking the interface configuration and the gateway kludge
171 * file. Then, send a request packet on all
172 * directly connected networks to find out what
173 * everyone else thinks.
182 query
->rip_cmd
= RIPCMD_REQUEST
;
183 query
->rip_vers
= RIPVERSION
;
184 if (sizeof(query
->rip_nets
[0].rip_dst
.sa_family
) > 1) /* XXX */
185 query
->rip_nets
[0].rip_dst
.sa_family
= htons((u_short
)AF_UNSPEC
);
187 query
->rip_nets
[0].rip_dst
.sa_family
= AF_UNSPEC
;
188 query
->rip_nets
[0].rip_metric
= htonl((u_long
)HOPCNT_INFINITY
);
190 signal(SIGALRM
, timer
);
192 signal(SIGTERM
, hup
);
193 signal(SIGINT
, rtdeleteall
);
194 signal(SIGUSR1
, sigtrace
);
195 signal(SIGUSR2
, sigtrace
);
196 itval
.it_interval
.tv_sec
= TIMER_RATE
;
197 itval
.it_value
.tv_sec
= TIMER_RATE
;
198 itval
.it_interval
.tv_usec
= 0;
199 itval
.it_value
.tv_usec
= 0;
201 if (setitimer(ITIMER_REAL
, &itval
, (struct itimerval
*)NULL
) < 0)
202 syslog(LOG_ERR
, "setitimer: %m\n");
205 nfd
= s
+ 1; /* 1 + max(fd's) */
209 * If we need a dynamic update that was held off,
210 * needupdate will be set, and nextbcast is the time
211 * by which we want select to return. Compute time
212 * until dynamic update should be sent, and select only
213 * until then. If we have already passed nextbcast,
217 waittime
= nextbcast
;
218 timevalsub(&waittime
, &now
);
219 if (waittime
.tv_sec
< 0) {
221 waittime
.tv_usec
= 0;
225 "select until dynamic update %d/%d sec/usec\n",
226 waittime
.tv_sec
, waittime
.tv_usec
);
229 tvp
= (struct timeval
*)NULL
;
230 n
= select(nfd
, &ibits
, 0, 0, tvp
);
233 * Need delayed dynamic update if select returned
234 * nothing and we timed out. Otherwise, ignore
235 * errors (e.g. EINTR).
240 syslog(LOG_ERR
, "select: %m");
242 omask
= sigblock(sigmask(SIGALRM
));
243 if (n
== 0 && needupdate
) {
246 "send delayed dynamic update\n");
247 (void) gettimeofday(&now
,
248 (struct timezone
*)NULL
);
249 toall(supply
, RTS_CHANGED
,
250 (struct interface
*)NULL
);
253 nextbcast
.tv_sec
= 0;
258 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
259 omask
= sigblock(sigmask(SIGALRM
));
262 printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n",
265 (s)/(sizeof(fd_mask) * 8),
266 ((s) % (sizeof(fd_mask) * 8)),
267 (1 << ((s) % (sizeof(fd_mask) * 8))),
268 ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))),
272 if (FD_ISSET(s
, &ibits
))
274 if (ibits
.fds_bits
[s
/32] & (1 << s
))
277 /* handle ICMP redirects */
283 struct timeval
*t1
, *t2
;
286 t1
->tv_sec
+= t2
->tv_sec
;
287 if ((t1
->tv_usec
+= t2
->tv_usec
) > 1000000) {
289 t1
->tv_usec
-= 1000000;
294 struct timeval
*t1
, *t2
;
297 t1
->tv_sec
-= t2
->tv_sec
;
298 if ((t1
->tv_usec
-= t2
->tv_usec
) < 0) {
300 t1
->tv_usec
+= 1000000;
307 struct sockaddr from
;
310 char buf
[MAXPACKETSIZE
+1];
315 fromlen
= sizeof (from
);
316 cc
= recvfrom(fd
, &inbuf
, sizeof (inbuf
), 0, &from
, &fromlen
);
318 if (cc
< 0 && errno
!= EWOULDBLOCK
)
322 if (fromlen
!= sizeof (struct sockaddr_in
))
324 rip_input(&from
, &inbuf
.rip
, cc
);
328 getsocket(domain
, type
, sin
)
330 struct sockaddr_in
*sin
;
334 if ((sock
= socket(domain
, type
, 0)) < 0) {
336 syslog(LOG_ERR
, "socket: %m");
340 if (setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof (on
)) < 0) {
341 syslog(LOG_ERR
, "setsockopt SO_BROADCAST: %m");
347 for (on
= bufspace
; ; on
-= 1024) {
348 if (setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
,
349 &on
, sizeof (on
)) == 0)
352 syslog(LOG_ERR
, "setsockopt SO_RCVBUF: %m");
357 fprintf(ftrace
, "recv buf %d\n", on
);
359 if (bind(sock
, (struct sockaddr
*)sin
, sizeof (*sin
)) < 0) {
361 syslog(LOG_ERR
, "bind: %m");
365 if (fcntl(sock
, F_SETFL
, O_NONBLOCK
) == -1)
366 syslog(LOG_ERR
, "fcntl O_NONBLOCK: %m\n");