]>
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>
69 #include <sys/errno.h>
70 #include <sys/signal.h>
71 #include <sys/syslog.h>
72 #include "pathnames.h"
74 int supplier
= -1; /* process should supply updates */
75 int gateway
= 0; /* 1 if we are a gateway to parts beyond */
77 int bufspace
= 127*1024; /* max. input buffer size to request */
79 struct rip
*msg
= (struct rip
*)packet
;
80 void hup(), rtdeleteall(), sigtrace(), timer();
86 int n
, cc
, nfd
, omask
, tflags
= 0;
88 struct timeval
*tvp
, waittime
;
89 struct itimerval itval
;
90 register struct rip
*query
= msg
;
96 openlog("routed", LOG_PID
| LOG_ODELAY
, LOG_DAEMON
);
97 setlogmask(LOG_UPTO(LOG_WARNING
));
99 openlog("routed", LOG_PID
);
100 #define LOG_UPTO(x) (x)
101 #define setlogmask(x) (x)
103 sp
= getservbyname("router", "udp");
105 fprintf(stderr
, "routed: router/udp: unknown service\n");
108 addr
.sin_family
= AF_INET
;
109 addr
.sin_port
= sp
->s_port
;
110 r
= socket(AF_ROUTE
, SOCK_RAW
, 0);
111 /* later, get smart about lookingforinterfaces */
113 shutdown(r
, 0); /* for now, don't want reponses */
115 fprintf(stderr
, "routed: no routing socket\n");
118 s
= getsocket(AF_INET
, SOCK_DGRAM
, &addr
);
122 while (argc
> 0 && **argv
== '-') {
123 if (strcmp(*argv
, "-s") == 0) {
128 if (strcmp(*argv
, "-q") == 0) {
133 if (strcmp(*argv
, "-t") == 0) {
135 setlogmask(LOG_UPTO(LOG_DEBUG
));
139 if (strcmp(*argv
, "-d") == 0) {
141 setlogmask(LOG_UPTO(LOG_DEBUG
));
145 if (strcmp(*argv
, "-g") == 0) {
151 "usage: routed [ -s ] [ -q ] [ -t ] [ -g ]\n");
155 if (debug
== 0 && tflags
== 0)
158 * Any extra argument is considered
159 * a tracing log file.
166 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
168 * Collect an initial view of the world by
169 * checking the interface configuration and the gateway kludge
170 * file. Then, send a request packet on all
171 * directly connected networks to find out what
172 * everyone else thinks.
181 query
->rip_cmd
= RIPCMD_REQUEST
;
182 query
->rip_vers
= RIPVERSION
;
183 if (sizeof(query
->rip_nets
[0].rip_dst
.sa_family
) > 1) /* XXX */
184 query
->rip_nets
[0].rip_dst
.sa_family
= htons((u_short
)AF_UNSPEC
);
186 query
->rip_nets
[0].rip_dst
.sa_family
= AF_UNSPEC
;
187 query
->rip_nets
[0].rip_metric
= htonl((u_long
)HOPCNT_INFINITY
);
189 signal(SIGALRM
, timer
);
191 signal(SIGTERM
, hup
);
192 signal(SIGINT
, rtdeleteall
);
193 signal(SIGUSR1
, sigtrace
);
194 signal(SIGUSR2
, sigtrace
);
195 itval
.it_interval
.tv_sec
= TIMER_RATE
;
196 itval
.it_value
.tv_sec
= TIMER_RATE
;
197 itval
.it_interval
.tv_usec
= 0;
198 itval
.it_value
.tv_usec
= 0;
200 if (setitimer(ITIMER_REAL
, &itval
, (struct itimerval
*)NULL
) < 0)
201 syslog(LOG_ERR
, "setitimer: %m\n");
204 nfd
= s
+ 1; /* 1 + max(fd's) */
208 * If we need a dynamic update that was held off,
209 * needupdate will be set, and nextbcast is the time
210 * by which we want select to return. Compute time
211 * until dynamic update should be sent, and select only
212 * until then. If we have already passed nextbcast,
216 waittime
= nextbcast
;
217 timevalsub(&waittime
, &now
);
218 if (waittime
.tv_sec
< 0) {
220 waittime
.tv_usec
= 0;
224 "select until dynamic update %d/%d sec/usec\n",
225 waittime
.tv_sec
, waittime
.tv_usec
);
228 tvp
= (struct timeval
*)NULL
;
229 n
= select(nfd
, &ibits
, 0, 0, tvp
);
232 * Need delayed dynamic update if select returned
233 * nothing and we timed out. Otherwise, ignore
234 * errors (e.g. EINTR).
239 syslog(LOG_ERR
, "select: %m");
241 omask
= sigblock(sigmask(SIGALRM
));
242 if (n
== 0 && needupdate
) {
245 "send delayed dynamic update\n");
246 (void) gettimeofday(&now
,
247 (struct timezone
*)NULL
);
248 toall(supply
, RTS_CHANGED
,
249 (struct interface
*)NULL
);
252 nextbcast
.tv_sec
= 0;
257 (void) gettimeofday(&now
, (struct timezone
*)NULL
);
258 omask
= sigblock(sigmask(SIGALRM
));
261 printf("s %d, ibits %x index %d, mod %d, sh %x, or %x &ibits %x\n",
264 (s)/(sizeof(fd_mask) * 8),
265 ((s) % (sizeof(fd_mask) * 8)),
266 (1 << ((s) % (sizeof(fd_mask) * 8))),
267 ibits.fds_bits[(s)/(sizeof(fd_mask) * 8)] & (1 << ((s) % (sizeof(fd_mask) * 8))),
271 if (FD_ISSET(s
, &ibits
))
273 if (ibits
.fds_bits
[s
/32] & (1 << s
))
276 /* handle ICMP redirects */
282 struct timeval
*t1
, *t2
;
285 t1
->tv_sec
+= t2
->tv_sec
;
286 if ((t1
->tv_usec
+= t2
->tv_usec
) > 1000000) {
288 t1
->tv_usec
-= 1000000;
293 struct timeval
*t1
, *t2
;
296 t1
->tv_sec
-= t2
->tv_sec
;
297 if ((t1
->tv_usec
-= t2
->tv_usec
) < 0) {
299 t1
->tv_usec
+= 1000000;
306 struct sockaddr from
;
309 char buf
[MAXPACKETSIZE
+1];
314 fromlen
= sizeof (from
);
315 cc
= recvfrom(fd
, &inbuf
, sizeof (inbuf
), 0, &from
, &fromlen
);
317 if (cc
< 0 && errno
!= EWOULDBLOCK
)
321 if (fromlen
!= sizeof (struct sockaddr_in
))
323 rip_input(&from
, &inbuf
.rip
, cc
);
327 getsocket(domain
, type
, sin
)
329 struct sockaddr_in
*sin
;
333 if ((sock
= socket(domain
, type
, 0)) < 0) {
335 syslog(LOG_ERR
, "socket: %m");
339 if (setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof (on
)) < 0) {
340 syslog(LOG_ERR
, "setsockopt SO_BROADCAST: %m");
346 for (on
= bufspace
; ; on
-= 1024) {
347 if (setsockopt(sock
, SOL_SOCKET
, SO_RCVBUF
,
348 &on
, sizeof (on
)) == 0)
351 syslog(LOG_ERR
, "setsockopt SO_RCVBUF: %m");
356 fprintf(ftrace
, "recv buf %d\n", on
);
358 if (bind(sock
, (struct sockaddr
*)sin
, sizeof (*sin
)) < 0) {
360 syslog(LOG_ERR
, "bind: %m");
364 if (fcntl(sock
, F_SETFL
, O_NONBLOCK
) == -1)
365 syslog(LOG_ERR
, "fcntl O_NONBLOCK: %m\n");