main.c revision 11840
111820Sjulian/* 211820Sjulian * Copyright (c) 1985, 1993 311820Sjulian * The Regents of the University of California. All rights reserved. 411820Sjulian * 511820Sjulian * Copyright (c) 1995 John Hay. All rights reserved. 611820Sjulian * 711820Sjulian * This file includes significant work done at Cornell University by 811820Sjulian * Bill Nesheim. That work included by permission. 911820Sjulian * 1011820Sjulian * Redistribution and use in source and binary forms, with or without 1111820Sjulian * modification, are permitted provided that the following conditions 1211820Sjulian * are met: 1311820Sjulian * 1. Redistributions of source code must retain the above copyright 1411820Sjulian * notice, this list of conditions and the following disclaimer. 1511820Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1611820Sjulian * notice, this list of conditions and the following disclaimer in the 1711820Sjulian * documentation and/or other materials provided with the distribution. 1811820Sjulian * 3. All advertising materials mentioning features or use of this software 1911820Sjulian * must display the following acknowledgement: 2011820Sjulian * This product includes software developed by the University of 2111820Sjulian * California, Berkeley and its contributors. 2211820Sjulian * 4. Neither the name of the University nor the names of its contributors 2311820Sjulian * may be used to endorse or promote products derived from this software 2411820Sjulian * without specific prior written permission. 2511820Sjulian * 2611820Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2711820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2811820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2911820Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3011820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3111820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3211820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3311820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3411820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3511820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3611820Sjulian * SUCH DAMAGE. 3711820Sjulian * 3811840Sjulian * $Id: main.c,v 1.1 1995/10/26 21:28:19 julian Exp $ 3911820Sjulian */ 4011820Sjulian 4111820Sjulian#ifndef lint 4211820Sjulianstatic char copyright[] = 4311820Sjulian"@(#) Copyright (c) 1985, 1993\n\ 4411820Sjulian The Regents of the University of California. All rights reserved.\n"; 4511820Sjulian#endif /* not lint */ 4611820Sjulian 4711820Sjulian#ifndef lint 4811820Sjulianstatic char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93"; 4911820Sjulian#endif /* not lint */ 5011820Sjulian 5111820Sjulian/* 5211820Sjulian * IPX Routing Information Protocol Daemon 5311820Sjulian */ 5411820Sjulian#include "defs.h" 5511820Sjulian#include <sys/time.h> 5611820Sjulian 5711820Sjulian#include <net/if.h> 5811820Sjulian 5911820Sjulian#include <errno.h> 6011820Sjulian#include <nlist.h> 6111820Sjulian#include <signal.h> 6211820Sjulian#include <paths.h> 6311820Sjulian#include <stdlib.h> 6411820Sjulian#include <unistd.h> 6511820Sjulian 6611820Sjulian#define SAP_PKT 0 6711820Sjulian#define RIP_PKT 1 6811820Sjulian 6911820Sjulianstruct sockaddr_ipx addr; /* Daemon's Address */ 7011820Sjulianint ripsock; /* RIP Socket to listen on */ 7111820Sjulianint sapsock; /* SAP Socket to listen on */ 7211820Sjulianint kmem; 7311820Sjulianint install; /* if 1 call kernel */ 7411820Sjulianint lookforinterfaces; /* if 1 probe kernel for new up interfaces */ 7511820Sjulianint performnlist; /* if 1 check if /kernel has changed */ 7611820Sjulianint externalinterfaces; /* # of remote and local interfaces */ 7711820Sjulianint timeval; /* local idea of time */ 7811820Sjulianint noteremoterequests; /* squawk on requests from non-local nets */ 7911820Sjulianint r; /* Routing socket to install updates with */ 8011820Sjulianstruct sockaddr_ipx ipx_netmask; /* Used in installing routes */ 8111820Sjulian 8211840Sjulianchar packet[MAXPACKETSIZE+sizeof(struct ipx)+1]; 8311820Sjulian 8411820Sjulianchar **argv0; 8511820Sjulian 8611820Sjulianint supplier = -1; /* process should supply updates */ 8711820Sjulianint dosap = 1; /* By default do SAP services. */ 8811820Sjulian 8911840Sjulianstruct rip *msg = (struct rip *) &packet[sizeof (struct ipx)]; 9011820Sjulianstruct sap_packet *sap_msg = 9111840Sjulian (struct sap_packet *) &packet[sizeof (struct ipx)]; 9211820Sjulianvoid hup(), fkexit(), timer(); 9311820Sjulianvoid process(int fd, int pkt_type); 9411820Sjulianint getsocket(int type, int proto, struct sockaddr_ipx *sipx); 9511820Sjulian 9611820Sjulianint 9711820Sjulianmain(argc, argv) 9811820Sjulian int argc; 9911820Sjulian char *argv[]; 10011820Sjulian{ 10111820Sjulian int nfds; 10211820Sjulian fd_set fdvar; 10311820Sjulian 10411820Sjulian argv0 = argv; 10511820Sjulian argv++, argc--; 10611820Sjulian while (argc > 0 && **argv == '-') { 10711820Sjulian if (strcmp(*argv, "-s") == 0) { 10811820Sjulian supplier = 1; 10911820Sjulian argv++, argc--; 11011820Sjulian continue; 11111820Sjulian } 11211820Sjulian if (strcmp(*argv, "-q") == 0) { 11311820Sjulian supplier = 0; 11411820Sjulian argv++, argc--; 11511820Sjulian continue; 11611820Sjulian } 11711820Sjulian if (strcmp(*argv, "-R") == 0) { 11811820Sjulian noteremoterequests++; 11911820Sjulian argv++, argc--; 12011820Sjulian continue; 12111820Sjulian } 12211820Sjulian if (strcmp(*argv, "-S") == 0) { 12311820Sjulian dosap = 0; 12411820Sjulian argv++, argc--; 12511820Sjulian continue; 12611820Sjulian } 12711820Sjulian if (strcmp(*argv, "-t") == 0) { 12811820Sjulian tracepackets++; 12911820Sjulian argv++, argc--; 13011820Sjulian ftrace = stderr; 13111820Sjulian tracing = 1; 13211820Sjulian continue; 13311820Sjulian } 13411820Sjulian if (strcmp(*argv, "-g") == 0) { 13511820Sjulian gateway = 1; 13611820Sjulian argv++, argc--; 13711820Sjulian continue; 13811820Sjulian } 13911820Sjulian if (strcmp(*argv, "-l") == 0) { 14011820Sjulian gateway = -1; 14111820Sjulian argv++, argc--; 14211820Sjulian continue; 14311820Sjulian } 14411820Sjulian fprintf(stderr, 14511820Sjulian "usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); 14611820Sjulian exit(1); 14711820Sjulian } 14811820Sjulian 14911820Sjulian 15011820Sjulian#ifndef DEBUG 15111820Sjulian if (!tracepackets) 15211820Sjulian daemon(0, 0); 15311820Sjulian#endif 15411820Sjulian openlog("IPXrouted", LOG_PID, LOG_DAEMON); 15511820Sjulian 15611820Sjulian addr.sipx_family = AF_IPX; 15711820Sjulian addr.sipx_len = sizeof(addr); 15811820Sjulian addr.sipx_port = htons(IPXPORT_RIP); 15911820Sjulian ipx_anynet.s_net[0] = ipx_anynet.s_net[1] = -1; 16011820Sjulian ipx_netmask.sipx_addr.x_net = ipx_anynet; 16111820Sjulian ipx_netmask.sipx_len = 6; 16211820Sjulian ipx_netmask.sipx_family = AF_IPX; 16311820Sjulian r = socket(AF_ROUTE, SOCK_RAW, 0); 16411820Sjulian /* later, get smart about lookingforinterfaces */ 16511820Sjulian if (r) 16611820Sjulian shutdown(r, 0); /* for now, don't want reponses */ 16711820Sjulian else { 16811820Sjulian fprintf(stderr, "IPXrouted: no routing socket\n"); 16911820Sjulian exit(1); 17011820Sjulian } 17111820Sjulian ripsock = getsocket(SOCK_DGRAM, 0, &addr); 17211820Sjulian if (ripsock < 0) 17311820Sjulian exit(1); 17411820Sjulian 17511820Sjulian if (dosap) { 17611820Sjulian addr.sipx_port = htons(IPXPORT_SAP); 17711820Sjulian sapsock = getsocket(SOCK_DGRAM, 0, &addr); 17811820Sjulian if (sapsock < 0) 17911820Sjulian exit(1); 18011820Sjulian } else 18111820Sjulian sapsock = -1; 18211820Sjulian 18311820Sjulian /* 18411820Sjulian * Any extra argument is considered 18511820Sjulian * a tracing log file. 18611820Sjulian */ 18711820Sjulian if (argc > 0) 18811820Sjulian traceon(*argv); 18911820Sjulian /* 19011820Sjulian * Collect an initial view of the world by 19111820Sjulian * snooping in the kernel. Then, send a request packet on all 19211820Sjulian * directly connected networks to find out what 19311820Sjulian * everyone else thinks. 19411820Sjulian */ 19511820Sjulian rtinit(); 19611820Sjulian sapinit(); 19711820Sjulian ifinit(); 19811820Sjulian if (supplier < 0) 19911820Sjulian supplier = 0; 20011820Sjulian /* request the state of the world */ 20111820Sjulian msg->rip_cmd = htons(RIPCMD_REQUEST); 20211820Sjulian msg->rip_nets[0].rip_dst = ipx_anynet; 20311820Sjulian msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); 20411820Sjulian msg->rip_nets[0].rip_ticks = htons(-1); 20511820Sjulian toall(sndmsg, NULL); 20611820Sjulian 20711820Sjulian if (dosap) { 20811820Sjulian sap_msg->sap_cmd = htons(SAP_REQ); 20911820Sjulian sap_msg->sap[0].ServType = htons(SAP_WILDCARD); 21011820Sjulian toall(sapsndmsg, NULL); 21111820Sjulian } 21211820Sjulian 21311820Sjulian signal(SIGALRM, timer); 21411820Sjulian signal(SIGHUP, hup); 21511820Sjulian signal(SIGINT, hup); 21611820Sjulian signal(SIGEMT, fkexit); 21711820Sjulian timer(); 21811820Sjulian 21911820Sjulian nfds = 1 + max(sapsock, ripsock); 22011820Sjulian 22111820Sjulian for (;;) { 22211820Sjulian FD_ZERO(&fdvar); 22311820Sjulian if (dosap) { 22411820Sjulian FD_SET(sapsock, &fdvar); 22511820Sjulian } 22611820Sjulian FD_SET(ripsock, &fdvar); 22711820Sjulian 22811820Sjulian if(select(nfds, &fdvar, (fd_set *)NULL, (fd_set *)NULL, 22911820Sjulian (struct timeval *)NULL) < 0) { 23011820Sjulian if(errno != EINTR) { 23111820Sjulian perror("during select"); 23211820Sjulian exit(1); 23311820Sjulian } 23411820Sjulian } 23511820Sjulian 23611820Sjulian if(FD_ISSET(ripsock, &fdvar)) 23711820Sjulian process(ripsock, RIP_PKT); 23811820Sjulian 23911820Sjulian if(dosap && FD_ISSET(sapsock, &fdvar)) 24011820Sjulian process(sapsock, SAP_PKT); 24111820Sjulian } 24211820Sjulian} 24311820Sjulian 24411820Sjulianvoid 24511820Sjulianprocess(fd, pkt_type) 24611820Sjulian int fd; 24711820Sjulian int pkt_type; 24811820Sjulian{ 24911820Sjulian struct sockaddr from; 25011820Sjulian int fromlen = sizeof (from), cc, omask; 25111840Sjulian struct ipx *ipxdp = (struct ipx *)packet; 25211820Sjulian 25311820Sjulian cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); 25411820Sjulian if (cc <= 0) { 25511820Sjulian if (cc < 0 && errno != EINTR) 25611820Sjulian syslog(LOG_ERR, "recvfrom: %m"); 25711820Sjulian return; 25811820Sjulian } 25911820Sjulian if (tracepackets > 1 && ftrace) { 26011820Sjulian fprintf(ftrace,"rcv %d bytes on %s ", 26111840Sjulian cc, ipxdp_ntoa(&ipxdp->ipx_dna)); 26211840Sjulian fprintf(ftrace," from %s\n", ipxdp_ntoa(&ipxdp->ipx_sna)); 26311820Sjulian } 26411820Sjulian 26511820Sjulian if (noteremoterequests && 26611840Sjulian !ipx_neteqnn(ipxdp->ipx_sna.x_net, ipx_zeronet) && 26711840Sjulian !ipx_neteq(ipxdp->ipx_sna, ipxdp->ipx_dna)) 26811820Sjulian { 26911820Sjulian syslog(LOG_ERR, 27011820Sjulian "net of interface (%s) != net on ether (%s)!\n", 27111840Sjulian ipxdp_nettoa(ipxdp->ipx_dna.x_net), 27211840Sjulian ipxdp_nettoa(ipxdp->ipx_sna.x_net)); 27311820Sjulian } 27411820Sjulian 27511820Sjulian /* We get the IPX header in front of the RIF packet*/ 27611840Sjulian cc -= sizeof (struct ipx); 27711820Sjulian#define mask(s) (1<<((s)-1)) 27811820Sjulian omask = sigblock(mask(SIGALRM)); 27911820Sjulian switch(pkt_type) { 28011820Sjulian case SAP_PKT: sap_input(&from, cc); 28111820Sjulian break; 28211820Sjulian case RIP_PKT: rip_input(&from, cc); 28311820Sjulian break; 28411820Sjulian } 28511820Sjulian sigsetmask(omask); 28611820Sjulian} 28711820Sjulian 28811820Sjulianint 28911820Sjuliangetsocket(type, proto, sipx) 29011820Sjulian int type, proto; 29111820Sjulian struct sockaddr_ipx *sipx; 29211820Sjulian{ 29311820Sjulian int domain = sipx->sipx_family; 29411820Sjulian int retry, s, on = 1; 29511820Sjulian 29611820Sjulian retry = 1; 29711820Sjulian while ((s = socket(domain, type, proto)) < 0 && retry) { 29811820Sjulian syslog(LOG_ERR, "socket: %m"); 29911820Sjulian sleep(5 * retry); 30011820Sjulian retry <<= 1; 30111820Sjulian } 30211820Sjulian if (retry == 0) 30311820Sjulian return (-1); 30411820Sjulian while (bind(s, (struct sockaddr *)sipx, sizeof (*sipx)) < 0 && retry) { 30511820Sjulian syslog(LOG_ERR, "bind: %m"); 30611820Sjulian sleep(5 * retry); 30711820Sjulian retry <<= 1; 30811820Sjulian } 30911820Sjulian if (retry == 0) 31011820Sjulian return (-1); 31111820Sjulian if (domain==AF_IPX) { 31211840Sjulian struct ipx ipxdp; 31311820Sjulian if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { 31411820Sjulian syslog(LOG_ERR, "setsockopt SEE HEADERS: %m"); 31511820Sjulian exit(1); 31611820Sjulian } 31711820Sjulian if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_RIP) 31811840Sjulian ipxdp.ipx_pt = IPXPROTO_RI; 31911820Sjulian else if (ntohs(sipx->sipx_addr.x_port) == IPXPORT_SAP) 32011840Sjulian ipxdp.ipx_pt = IPXPROTO_SAP; 32111820Sjulian else { 32211820Sjulian syslog(LOG_ERR, "port should be either RIP or SAP"); 32311820Sjulian exit(1); 32411820Sjulian } 32511820Sjulian if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &ipxdp, sizeof(ipxdp))) { 32611820Sjulian syslog(LOG_ERR, "setsockopt SET HEADER: %m"); 32711820Sjulian exit(1); 32811820Sjulian } 32911820Sjulian } 33011820Sjulian if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { 33111820Sjulian syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); 33211820Sjulian exit(1); 33311820Sjulian } 33411820Sjulian return (s); 33511820Sjulian} 33611820Sjulian 33711820Sjulian/* 33811820Sjulian * Fork and exit on EMT-- for profiling. 33911820Sjulian */ 34011820Sjulianvoid 34111820Sjulianfkexit() 34211820Sjulian{ 34311820Sjulian if (fork() == 0) 34411820Sjulian exit(0); 34511820Sjulian} 346