2 * Copyright (c) 1985, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1995 John Hay. All rights reserved.
7 * This file includes significant work done at Cornell University by
8 * Bill Nesheim. That work included by permission.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * $FreeBSD: src/usr.sbin/IPXrouted/main.c,v 1.10 1999/08/28 01:15:03 peter Exp $
39 * $DragonFly: src/usr.sbin/IPXrouted/main.c,v 1.4 2007/05/18 17:05:12 dillon Exp $
41 * @(#) Copyright (c) 1985, 1993 The Regents of the University of California. All rights reserved.
42 * @(#)main.c 8.1 (Berkeley) 6/5/93
46 * IPX Routing Information Protocol Daemon
63 struct sockaddr_ipx addr
; /* Daemon's Address */
64 int ripsock
; /* RIP Socket to listen on */
65 int sapsock
; /* SAP Socket to listen on */
67 int install
; /* if 1 call kernel */
68 int lookforinterfaces
; /* if 1 probe kernel for new up interfaces */
69 int performnlist
; /* if 1 check if /kernel has changed */
70 int externalinterfaces
; /* # of remote and local interfaces */
71 int timeval
; /* local idea of time */
72 int noteremoterequests
; /* squawk on requests from non-local nets */
73 int r
; /* Routing socket to install updates with */
74 struct sockaddr_ipx ipx_netmask
; /* Used in installing routes */
76 char packet
[MAXRXPACKETSIZE
+1];
80 int supplier
= -1; /* process should supply updates */
81 int dosap
= 1; /* By default do SAP services. */
82 int dobcast
= 1; /* A RIP/SAP broadcast is needed. */
83 time_t lastbcast
; /* Time of last RIP/SAP broadcast */
85 struct rip
*msg
= (struct rip
*) &packet
[sizeof (struct ipx
)];
86 struct sap_packet
*sap_msg
=
87 (struct sap_packet
*) &packet
[sizeof (struct ipx
)];
88 void hup(), fkexit(), timer();
89 void process(int fd
, int pkt_type
);
90 int getsocket(int type
, int proto
, struct sockaddr_ipx
*sipx
);
95 main(int argc
, char *argv
[])
100 struct itimerval tval
;
104 while (argc
> 0 && **argv
== '-') {
105 if (strcmp(*argv
, "-s") == 0) {
110 if (strcmp(*argv
, "-q") == 0) {
115 if (strcmp(*argv
, "-R") == 0) {
116 noteremoterequests
++;
120 if (strcmp(*argv
, "-S") == 0) {
125 if (strcmp(*argv
, "-t") == 0) {
132 if (strcmp(*argv
, "-g") == 0) {
137 if (strcmp(*argv
, "-l") == 0) {
142 if (strcmp(*argv
, "-N") == 0) {
148 "usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n");
157 openlog("IPXrouted", LOG_PID
, LOG_DAEMON
);
159 addr
.sipx_family
= AF_IPX
;
160 addr
.sipx_len
= sizeof(addr
);
161 addr
.sipx_port
= htons(IPXPORT_RIP
);
162 ipx_anynet
.s_net
[0] = ipx_anynet
.s_net
[1] = -1;
163 ipx_netmask
.sipx_addr
.x_net
= ipx_anynet
;
164 ipx_netmask
.sipx_len
= 6;
165 ipx_netmask
.sipx_family
= AF_IPX
;
166 r
= socket(AF_ROUTE
, SOCK_RAW
, 0);
167 /* later, get smart about lookingforinterfaces */
169 shutdown(r
, SHUT_RD
); /* for now, don't want reponses */
171 fprintf(stderr
, "IPXrouted: no routing socket\n");
174 ripsock
= getsocket(SOCK_DGRAM
, 0, &addr
);
179 addr
.sipx_port
= htons(IPXPORT_SAP
);
180 sapsock
= getsocket(SOCK_DGRAM
, 0, &addr
);
187 * Any extra argument is considered
188 * a tracing log file.
193 * Collect an initial view of the world by
194 * snooping in the kernel. Then, send a request packet on all
195 * directly connected networks to find out what
196 * everyone else thinks.
203 /* request the state of the world */
204 msg
->rip_cmd
= htons(RIPCMD_REQUEST
);
205 msg
->rip_nets
[0].rip_dst
= ipx_anynet
;
206 msg
->rip_nets
[0].rip_metric
= htons(HOPCNT_INFINITY
);
207 msg
->rip_nets
[0].rip_ticks
= htons(-1);
208 toall(sndmsg
, NULL
, 0);
211 sap_msg
->sap_cmd
= htons(SAP_REQ
);
212 sap_msg
->sap
[0].ServType
= htons(SAP_WILDCARD
);
213 toall(sapsndmsg
, NULL
, 0);
216 signal(SIGALRM
, catchtimer
);
219 signal(SIGEMT
, fkexit
);
220 signal(SIGINFO
, getinfo
);
222 tval
.it_interval
.tv_sec
= TIMER_RATE
;
223 tval
.it_interval
.tv_usec
= 0;
224 tval
.it_value
.tv_sec
= TIMER_RATE
;
225 tval
.it_value
.tv_usec
= 0;
226 setitimer(ITIMER_REAL
, &tval
, NULL
);
228 nfds
= 1 + max(sapsock
, ripsock
);
233 lastbcast
= time(NULL
);
239 FD_SET(sapsock
, &fdvar
);
241 FD_SET(ripsock
, &fdvar
);
243 if(select(nfds
, &fdvar
, NULL
, NULL
, NULL
) < 0) {
246 perror("during select");
250 if(FD_ISSET(ripsock
, &fdvar
))
251 process(ripsock
, RIP_PKT
);
253 if(dosap
&& FD_ISSET(sapsock
, &fdvar
))
254 process(sapsock
, SAP_PKT
);
257 if (ttime
> (lastbcast
+ TIMER_RATE
+ (TIMER_RATE
* 2 / 3))) {
259 syslog(LOG_ERR
, "Missed alarm");
265 process(int fd
, int pkt_type
)
267 struct sockaddr from
;
268 int fromlen
= sizeof (from
), cc
, omask
;
269 struct ipx
*ipxdp
= (struct ipx
*)packet
;
271 cc
= recvfrom(fd
, packet
, sizeof (packet
), 0, &from
, &fromlen
);
273 if (cc
< 0 && errno
!= EINTR
)
274 syslog(LOG_ERR
, "recvfrom: %m");
277 if (tracepackets
> 1 && ftrace
) {
278 fprintf(ftrace
,"rcv %d bytes on %s ",
279 cc
, ipxdp_ntoa(&ipxdp
->ipx_dna
));
280 fprintf(ftrace
," from %s\n", ipxdp_ntoa(&ipxdp
->ipx_sna
));
283 if (noteremoterequests
&&
284 !ipx_neteqnn(ipxdp
->ipx_sna
.x_net
, ipx_zeronet
) &&
285 !ipx_neteq(ipxdp
->ipx_sna
, ipxdp
->ipx_dna
))
288 "net of interface (%s) != net on ether (%s)!\n",
289 ipxdp_nettoa(ipxdp
->ipx_dna
.x_net
),
290 ipxdp_nettoa(ipxdp
->ipx_sna
.x_net
));
293 /* We get the IPX header in front of the RIF packet*/
294 cc
-= sizeof (struct ipx
);
295 #define mask(s) (1<<((s)-1))
296 omask
= sigblock(mask(SIGALRM
));
298 case SAP_PKT
: sap_input(&from
, cc
);
300 case RIP_PKT
: rip_input(&from
, cc
);
307 getsocket(int type
, int proto
, struct sockaddr_ipx
*sipx
)
309 int domain
= sipx
->sipx_family
;
310 int retry
, s
, on
= 1;
313 while ((s
= socket(domain
, type
, proto
)) < 0 && retry
) {
314 syslog(LOG_ERR
, "socket: %m");
320 while (bind(s
, (struct sockaddr
*)sipx
, sizeof (*sipx
)) < 0 && retry
) {
321 syslog(LOG_ERR
, "bind: %m");
327 if (domain
==AF_IPX
) {
329 if (setsockopt(s
, 0, SO_HEADERS_ON_INPUT
, &on
, sizeof(on
))) {
330 syslog(LOG_ERR
, "setsockopt SEE HEADERS: %m");
333 if (ntohs(sipx
->sipx_addr
.x_port
) == IPXPORT_RIP
)
334 ipxdp
.ipx_pt
= IPXPROTO_RI
;
335 else if (ntohs(sipx
->sipx_addr
.x_port
) == IPXPORT_SAP
)
337 ipxdp
.ipx_pt
= IPXPROTO_SAP
;
339 ipxdp
.ipx_pt
= IPXPROTO_PXP
;
342 syslog(LOG_ERR
, "port should be either RIP or SAP");
345 if (setsockopt(s
, 0, SO_DEFAULT_HEADERS
, &ipxdp
, sizeof(ipxdp
))) {
346 syslog(LOG_ERR
, "setsockopt SET HEADER: %m");
350 if (setsockopt(s
, SOL_SOCKET
, SO_BROADCAST
, &on
, sizeof (on
)) < 0) {
351 syslog(LOG_ERR
, "setsockopt SO_BROADCAST: %m");
358 * Fork and exit on EMT-- for profiling.
378 fh
= fopen("/var/log/ipxrouted.dmp", "a");
383 dumpsaptable(fh
, sap_head
);