#!/bin/sh # this is vxrouted_5.1.1-shar.04 (part 4 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file vxrouted_5.1.1/startup.c continued # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo 'WARNING: not restoring timestamps' fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 4; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping vxrouted_5.1.1/startup.c' else echo 'x - continuing file vxrouted_5.1.1/startup.c' sed 's/^X//' << 'SHAR_EOF' >> 'vxrouted_5.1.1/startup.c' && X /* X * Routing Table Management Daemon X */ #include "defs.h" #include #include /* #include */ X /* struct interface *ifnet; */ /* struct interface **ifnext = &ifnet; */ struct ifnet *rd_ifnet; struct ifnet **ifnext = &rd_ifnet; int lookforinterfaces = 1; int externalinterfaces = 0; /* # of remote and local interfaces */ int foundloopback; /* valid flag for loopaddr */ struct sockaddr loopaddr; /* our address on loopback */ X /* X * Find the network interfaces which have configured themselves. X * If the interface is present but not yet up (for example an X * ARPANET IMP), set the lookforinterfaces flag so we'll X * come back later and look again. X */ rd_ifinit() { X struct interface ifs, *ifp; X int s, n; X char buf[BUFSIZ]; X struct ifconf ifc; X struct ifreq ifreq, *ifr; X struct sockaddr_in *sin; X u_long i; X X if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { X logMsg(" LOG_ERR, socket: %m"); X close(s); X return; X } X ifc.ifc_len = sizeof (buf); X ifc.ifc_buf = buf; X if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { X logMsg(" LOG_ERR, ioctl get interface configuration"); X close(s); X return; X } X ifr = ifc.ifc_req; X lookforinterfaces = 0; X for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) { X bzero((char *)&ifs, sizeof(ifs)); X ifs.int_addr = ifr->ifr_addr; X ifreq = *ifr; X if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { X logMsg(" LOG_ERR, %s: ioctl (get interface flags)", X ifr->ifr_name); X continue; X } X ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE; X if ((ifs.int_flags & IFF_UP) == 0 || X ifr->ifr_addr.sa_family == AF_UNSPEC) { X lookforinterfaces = 1; X continue; X } X /* argh, this'll have to change sometime */ X if (ifs.int_addr.sa_family != AF_INET) X continue; X if (ifs.int_flags & IFF_POINTOPOINT) { X if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { X logMsg(" LOG_ERR, %s: ioctl (get dstaddr)", X ifr->ifr_name); X continue; X } X if (ifr->ifr_addr.sa_family == AF_UNSPEC) { X lookforinterfaces = 1; X continue; X } X ifs.int_dstaddr = ifreq.ifr_dstaddr; X } X /* X * already known to us? X * This allows multiple point-to-point links X * to share a source address (possibly with one X * other link), but assumes that there will not be X * multiple links with the same destination address. X */ X if (ifs.int_flags & IFF_POINTOPOINT) { X if (if_ifwithdstaddr(&ifs.int_dstaddr)) X continue; X } else if (if_ifwithaddr(&ifs.int_addr)) X continue; X if (ifs.int_flags & IFF_LOOPBACK) { X ifs.int_flags |= IFF_PASSIVE; X foundloopback = 1; X loopaddr = ifs.int_addr; X for (ifp = (struct interface *)rd_ifnet; ifp; ifp = ifp->int_next) X if (ifp->int_flags & IFF_POINTOPOINT) X add_ptopt_localrt(ifp); X } X if (ifs.int_flags & IFF_BROADCAST) { X if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { X logMsg(" LOG_ERR, %s: ioctl (get broadaddr)", X ifr->ifr_name); X continue; X } #ifndef sun X ifs.int_broadaddr = ifreq.ifr_broadaddr; #else X ifs.int_broadaddr = ifreq.ifr_addr; #endif X } #ifdef SIOCGIFMETRIC X if (ioctl(s, SIOCGIFMETRIC, (char *)&ifreq) < 0) { X logMsg(" LOG_ERR, %s: ioctl (get metric)", X ifr->ifr_name); X ifs.int_metric = 0; X } else X ifs.int_metric = ifreq.ifr_metric; #else X ifs.int_metric = 0; #endif X /* X * Use a minimum metric of one; X * treat the interface metric (default 0) X * as an increment to the hop count of one. X */ X ifs.int_metric++; X if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) { X logMsg(" LOG_ERR, %s: ioctl (get netmask)", X ifr->ifr_name); X continue; X } X sin = (struct sockaddr_in *)&ifreq.ifr_addr; X ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr); X sin = (struct sockaddr_in *)&ifs.int_addr; X i = ntohl(sin->sin_addr.s_addr); X if (IN_CLASSA(i)) X ifs.int_netmask = IN_CLASSA_NET; X else if (IN_CLASSB(i)) X ifs.int_netmask = IN_CLASSB_NET; X else X ifs.int_netmask = IN_CLASSC_NET; X ifs.int_net = i & ifs.int_netmask; X ifs.int_subnet = i & ifs.int_subnetmask; X if (ifs.int_subnetmask != ifs.int_netmask) X ifs.int_flags |= IFF_SUBNET; X ifp = (struct interface *)malloc(sizeof (struct interface)); X if (ifp == 0) { X printf("routed: out of memory\n"); X break; X } X *ifp = ifs; X /* X * Count the # of directly connected networks X * and point to point links which aren't looped X * back to ourself. This is used below to X * decide if we should be a routing ``supplier''. X */ X if ((ifs.int_flags & IFF_LOOPBACK) == 0 && X ((ifs.int_flags & IFF_POINTOPOINT) == 0 || X if_ifwithaddr(&ifs.int_dstaddr) == 0)) X externalinterfaces++; X /* X * If we have a point-to-point link, we want to act X * as a supplier even if it's our only interface, X * as that's the only way our peer on the other end X * can tell that the link is up. X */ X if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0) X supplier = 1; X ifp->int_name = malloc(strlen(ifr->ifr_name) + 1); X if (ifp->int_name == 0) { X fprintf(stderr, "routed: rd_ifinit: out of memory\n"); X logMsg(" LOG_ERR, routed: rd_ifinit: out of memory\n"); X close(s); X return; X } X strcpy(ifp->int_name, ifr->ifr_name); X *ifnext = (struct ifnet *)ifp; X (struct ifnet *)ifnext = &ifp->int_next; X traceinit(ifp); X addrouteforif(ifp); X } X if (externalinterfaces > 1 && supplier < 0) X supplier = 1; X close(s); } X /* X * Add route for interface if not currently installed. X * Create route to other end if a point-to-point link, X * otherwise a route to this (sub)network. X * INTERNET SPECIFIC. X */ addrouteforif(ifp) X register struct interface *ifp; { X struct sockaddr_in net; X struct sockaddr *dst; X int state; X register struct rt_entry *rt; X X if (ifp->int_flags & IFF_POINTOPOINT) X dst = &ifp->int_dstaddr; X else { X bzero((char *)&net, sizeof (net)); X net.sin_family = AF_INET; X net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY); X dst = (struct sockaddr *)&net; X } X rt = rtfind(dst); X if (rt && X (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE) X return; X if (rt) X rtdelete(rt); X /* X * If interface on subnetted network, X * install route to network as well. X * This is meant for external viewers. X */ X if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) { X struct in_addr subnet; X X subnet = net.sin_addr; X net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); X rt = rtfind(dst); X if (rt == 0) X rtadd(dst, &ifp->int_addr, ifp->int_metric, X ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) | X RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET)); X else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) == X (RTS_INTERNAL|RTS_SUBNET) && X ifp->int_metric < rt->rt_metric) X rtchange(rt, &rt->rt_router, ifp->int_metric); X net.sin_addr = subnet; X } X if (ifp->int_transitions++ > 0) X logMsg(" LOG_ERR, re-installing interface %s", ifp->int_name); X state = ifp->int_flags & X (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET); X if (ifp->int_flags & IFF_POINTOPOINT && X (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) & X ifp->int_netmask) != ifp->int_net) X state &= ~RTS_SUBNET; X if (ifp->int_flags & IFF_LOOPBACK) X state |= RTS_EXTERNAL; X rtadd(dst, &ifp->int_addr, ifp->int_metric, state); X if (ifp->int_flags & IFF_POINTOPOINT && foundloopback) X add_ptopt_localrt(ifp); } X /* X * Add route to local end of point-to-point using loopback. X * If a route to this network is being sent to neighbors on other nets, X * mark this route as subnet so we don't have to propagate it too. X */ add_ptopt_localrt(ifp) X register struct interface *ifp; { X struct rt_entry *rt; X struct sockaddr *dst; X struct sockaddr_in net; X int state; X X state = RTS_INTERFACE | RTS_PASSIVE; X X /* look for route to logical network */ X bzero((char *)&net, sizeof (net)); X net.sin_family = AF_INET; X net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY); X dst = (struct sockaddr *)&net; X rt = rtfind(dst); X if (rt && rt->rt_state & RTS_INTERNAL) X state |= RTS_SUBNET; X X dst = &ifp->int_addr; X if (rt = rtfind(dst)) { X if (rt && rt->rt_state & RTS_INTERFACE) X return; X rtdelete(rt); X } X rtadd(dst, &loopaddr, 1, state); } X /* X * As a concession to the ARPANET we read a list of gateways X * from /etc/gateways and add them to our tables. This file X * exists at each ARPANET gateway and indicates a set of ``remote'' X * gateways (i.e. a gateway which we can't immediately determine X * if it's present or not as we can do for those directly connected X * at the hardware level). If a gateway is marked ``passive'' X * in the file, then we assume it doesn't have a routing process X * of our design and simply assume it's always present. Those X * not marked passive are treated as if they were directly X * connected -- they're added into the interface list so we'll X * send them routing updates. X * X * PASSIVE ENTRIES AREN'T NEEDED OR USED ON GATEWAYS RUNNING EGP. X */ gwkludge() { X struct sockaddr_in dst, gate; X FILE *fp; X char *type, *dname, *gname, *qual, buf[BUFSIZ]; X struct interface *ifp; X int metric, n; X struct rt_entry route; X X return; /* vxworks has not /etc file system */ X fp = fopen("/etc/gateways", "r"); X if (fp == NULL) X return; X qual = buf; X dname = buf + 64; X gname = buf + ((BUFSIZ - 64) / 3); X type = buf + (((BUFSIZ - 64) * 2) / 3); X bzero((char *)&dst, sizeof (dst)); X bzero((char *)&gate, sizeof (gate)); X bzero((char *)&route, sizeof(route)); /* format: {net | host} XX gateway XX metric DD [passive | external]\n */ #define readentry(fp) \ X fscanf((fp), "%s %s gateway %s metric %d %s\n", \ X type, dname, gname, &metric, qual) X for (;;) { X if ((n = readentry(fp)) == EOF) X break; X if (!getnetorhostname(type, dname, &dst)) X continue; X if (!gethostnameornumber(gname, &gate)) X continue; X if (metric == 0) /* XXX */ X metric = 1; X if (strcmp(qual, "passive") == 0) { X /* X * Passive entries aren't placed in our tables, X * only the kernel's, so we don't copy all of the X * external routing information within a net. X * Internal machines should use the default X * route to a suitable gateway (like us). X */ X route.rt_dst = *(struct sockaddr *) &dst; X route.rt_router = *(struct sockaddr *) &gate; X route.rt_flags = RTF_UP; X if (strcmp(type, "host") == 0) X route.rt_flags |= RTF_HOST; X if (metric) X route.rt_flags |= RTF_GATEWAY; X (void) ioctl(rs, SIOCADDRT, (char *)&route.rt_rt); X continue; X } X if (strcmp(qual, "external") == 0) { X /* X * Entries marked external are handled X * by other means, e.g. EGP, X * and are placed in our tables only X * to prevent overriding them X * with something else. X */ X rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE); X continue; X } X /* assume no duplicate entries */ X externalinterfaces++; X ifp = (struct interface *)malloc(sizeof (*ifp)); X bzero((char *)ifp, sizeof (*ifp)); X ifp->int_flags = IFF_REMOTE; X /* can't identify broadcast capability */ X ifp->int_net = inet_netof(dst.sin_addr); X if (strcmp(type, "host") == 0) { X ifp->int_flags |= IFF_POINTOPOINT; X ifp->int_dstaddr = *((struct sockaddr *)&dst); X } X ifp->int_addr = *((struct sockaddr *)&gate); X ifp->int_metric = metric; X ifp->int_next = (struct interface *)rd_ifnet; X rd_ifnet = (struct ifnet *)ifp; X addrouteforif(ifp); X } X fclose(fp); } X getnetorhostname(type, name, sin) X char *type, *name; X struct sockaddr_in *sin; { X X if (strcmp(type, "net") == 0) { /* struct netent *np = getnetbyname(name); */ X struct netent *np = 0; X int n; X X if (np == 0) X n = inet_network(name); X else { X if (np->n_addrtype != AF_INET) X return (0); X n = np->n_net; X /* X * getnetbyname returns right-adjusted value. X */ X if (n < 128) X n <<= IN_CLASSA_NSHIFT; X else if (n < 65536) X n <<= IN_CLASSB_NSHIFT; X else X n <<= IN_CLASSC_NSHIFT; X } X sin->sin_family = AF_INET; X sin->sin_addr = inet_makeaddr(n, INADDR_ANY); X return (1); X } X if (strcmp(type, "host") == 0) { /* struct hostent *hp = gethostbyname(name); */ X struct hostent *hp = 0; X X if (hp == 0) X sin->sin_addr.s_addr = inet_addr(name); X else { X if (hp->h_addrtype != AF_INET) X return (0); X bcopy(hp->h_addr, &sin->sin_addr, hp->h_length); X } X sin->sin_family = AF_INET; X return (1); X } X return (0); } X gethostnameornumber(name, sin) X char *name; X struct sockaddr_in *sin; { X struct hostent *hp; X /* hp = gethostbyname(name); */ X hp = 0; X X if (hp) { X bcopy(hp->h_addr, &sin->sin_addr, hp->h_length); X sin->sin_family = hp->h_addrtype; X return (1); X } X sin->sin_addr.s_addr = inet_addr(name); X sin->sin_family = AF_INET; X return (sin->sin_addr.s_addr != -1); } SHAR_EOF echo 'File vxrouted_5.1.1/startup.c is complete' && $shar_touch -am 0201162294 'vxrouted_5.1.1/startup.c' && chmod 0644 'vxrouted_5.1.1/startup.c' || echo 'restore of vxrouted_5.1.1/startup.c failed' shar_count="`wc -c < 'vxrouted_5.1.1/startup.c'`" test 13884 -eq "$shar_count" || echo "vxrouted_5.1.1/startup.c: original size 13884, current size $shar_count" rm -f _sharnew.tmp fi # ============= vxrouted_5.1.1/table.h ============== if test -f 'vxrouted_5.1.1/table.h' && test X"$1" != X"-c"; then echo 'x - skipping vxrouted_5.1.1/table.h (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting vxrouted_5.1.1/table.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'vxrouted_5.1.1/table.h' && /* X * Copyright (c) 1983 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that the above copyright notice and this paragraph are X * duplicated in all such forms and that any documentation, X * advertising materials, and other materials related to such X * distribution and use acknowledge that the software was developed X * by the University of California, Berkeley. The name of the X * University may not be used to endorse or promote products derived X * from this software without specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. X * X * @(#)table.h 5.6 (Berkeley) 6/18/88 X */ X /* X * Routing table management daemon. X */ X /* X * Routing table structure; differs a bit from kernel tables. X * X * Note: the union below must agree in the first 4 members X * so the ioctl's will work. X */ struct rthash { X struct rt_entry *rt_forw; X struct rt_entry *rt_back; }; X struct rt_entry { X struct rt_entry *rt_forw; X struct rt_entry *rt_back; X union { X struct rtentry rtu_rt; X struct { X u_long rtu_hash; X struct sockaddr rtu_dst; X struct sockaddr rtu_router; X short rtu_flags; X short rtu_state; X int rtu_timer; X int rtu_metric; X int rtu_ifmetric; X struct interface *rtu_ifp; X } rtu_entry; X } rt_rtu; }; X #define rt_rt rt_rtu.rtu_rt /* pass to ioctl */ #define rt_hash rt_rtu.rtu_entry.rtu_hash /* for net or host */ #define rt_dst rt_rtu.rtu_entry.rtu_dst /* match value */ #define rt_router rt_rtu.rtu_entry.rtu_router /* who to forward to */ #define rt_flags rt_rtu.rtu_entry.rtu_flags /* kernel flags */ #define rt_timer rt_rtu.rtu_entry.rtu_timer /* for invalidation */ #define rt_state rt_rtu.rtu_entry.rtu_state /* see below */ #define rt_metric rt_rtu.rtu_entry.rtu_metric /* cost of route */ #define rt_ifmetric rt_rtu.rtu_entry.rtu_ifmetric /* cost of route if */ #define rt_ifp rt_rtu.rtu_entry.rtu_ifp /* interface to take */ X #define ROUTEHASHSIZ 32 /* must be a power of 2 */ #define ROUTEHASHMASK (ROUTEHASHSIZ - 1) X /* X * "State" of routing table entry. X */ #define RTS_CHANGED 0x1 /* route has been altered recently */ #define RTS_EXTERNAL 0x2 /* extern info, not installed or sent */ #define RTS_INTERNAL 0x4 /* internal route, not installed */ #define RTS_PASSIVE IFF_PASSIVE /* don't time out route */ #define RTS_INTERFACE IFF_INTERFACE /* route is for network interface */ #define RTS_REMOTE IFF_REMOTE /* route is for ``remote'' entity */ #define RTS_SUBNET IFF_SUBNET /* route is for network subnet */ X /* X * Flags are same as kernel, with this addition for af_rtflags: X */ #define RTF_SUBNET 0x8000 /* pseudo: route to subnet */ X struct rthash nethash[ROUTEHASHSIZ]; struct rthash hosthash[ROUTEHASHSIZ]; struct rt_entry *rtlookup(); struct rt_entry *rtfind(); SHAR_EOF $shar_touch -am 0218122989 'vxrouted_5.1.1/table.h' && chmod 0644 'vxrouted_5.1.1/table.h' || echo 'restore of vxrouted_5.1.1/table.h failed' shar_count="`wc -c < 'vxrouted_5.1.1/table.h'`" test 2987 -eq "$shar_count" || echo "vxrouted_5.1.1/table.h: original size 2987, current size $shar_count" rm -f _sharnew.tmp fi # ============= vxrouted_5.1.1/tables.c ============== if test -f 'vxrouted_5.1.1/tables.c' && test X"$1" != X"-c"; then echo 'x - skipping vxrouted_5.1.1/tables.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting vxrouted_5.1.1/tables.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'vxrouted_5.1.1/tables.c' && /* X * Copyright (c) 1983, 1988 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that the above copyright notice and this paragraph are X * duplicated in all such forms and that any documentation, X * advertising materials, and other materials related to such X * distribution and use acknowledge that the software was developed X * by the University of California, Berkeley. The name of the X * University may not be used to endorse or promote products derived X * from this software without specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. X */ X #ifndef lint static char sccsid[] = "@(#)tables.c 5.15 (Berkeley) 2/18/89"; #endif /* not lint */ X /* X * Routing Table Management Daemon X */ #include "defs.h" #include #include /* #include */ X #ifndef DEBUG #define DEBUG 0 #endif X int install = !DEBUG; /* if 1 call kernel */ X /* X * Lookup dst in the tables for an exact match. X */ struct rt_entry * rtlookup(dst) X struct sockaddr *dst; { X register struct rt_entry *rt; X register struct rthash *rh; X register u_int hash; X struct afhash h; X int doinghost = 1; X X if (dst->sa_family >= af_max) X return (0); X (*rd_afswitch[dst->sa_family].af_hash)(dst, &h); X hash = h.afh_hosthash; X rh = &hosthash[hash & ROUTEHASHMASK]; again: X for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { X if (rt->rt_hash != hash) X continue; X if (equal(&rt->rt_dst, dst)) X return (rt); X } X if (doinghost) { X doinghost = 0; X hash = h.afh_nethash; X rh = &nethash[hash & ROUTEHASHMASK]; X goto again; X } X return (0); } X struct sockaddr rd_wildcard; /* zero valued cookie for wildcard searches */ X /* X * Find a route to dst as the kernel would. X */ struct rt_entry * rtfind(dst) X struct sockaddr *dst; { X register struct rt_entry *rt; X register struct rthash *rh; X register u_int hash; X struct afhash h; X int af = dst->sa_family; X int doinghost = 1, (*match)(); X X if (af >= af_max) X return (0); X (*rd_afswitch[af].af_hash)(dst, &h); X hash = h.afh_hosthash; X rh = &hosthash[hash & ROUTEHASHMASK]; X again: X for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { X if (rt->rt_hash != hash) X continue; X if (doinghost) { X if (equal(&rt->rt_dst, dst)) X return (rt); X } else { X if (rt->rt_dst.sa_family == af && X (*match)(&rt->rt_dst, dst)) X return (rt); X } X } X if (doinghost) { X doinghost = 0; X hash = h.afh_nethash; X rh = &nethash[hash & ROUTEHASHMASK]; X match = rd_afswitch[af].af_netmatch; X goto again; X } #ifdef notyet X /* X * Check for wildcard gateway, by convention network 0. X */ X if (dst != &rd_wildcard) { X dst = &rd_wildcard, hash = 0; X goto again; X } #endif X return (0); } X rtadd(dst, gate, metric, state) X struct sockaddr *dst, *gate; X int metric, state; { X struct afhash h; X register struct rt_entry *rt; X struct rthash *rh; X int af = dst->sa_family, flags; X u_int hash; X X if (af >= af_max) X return; X (*rd_afswitch[af].af_hash)(dst, &h); X flags = (*rd_afswitch[af].af_rtflags)(dst); X /* X * Subnet flag isn't visible to kernel, move to state. XXX X */ X if (flags & RTF_SUBNET) { X state |= RTS_SUBNET; X flags &= ~RTF_SUBNET; X } X if (flags & RTF_HOST) { X hash = h.afh_hosthash; X rh = &hosthash[hash & ROUTEHASHMASK]; X } else { X hash = h.afh_nethash; X rh = &nethash[hash & ROUTEHASHMASK]; X } X rt = (struct rt_entry *)malloc(sizeof (*rt)); X if (rt == 0) X return; X rt->rt_hash = hash; X rt->rt_dst = *dst; X rt->rt_router = *gate; X rt->rt_timer = 0; X rt->rt_flags = RTF_UP | flags; X rt->rt_state = state | RTS_CHANGED; X rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router); X if (rt->rt_ifp == 0) X rt->rt_ifp = if_ifwithnet(&rt->rt_router); X if ((state & RTS_INTERFACE) == 0) X rt->rt_flags |= RTF_GATEWAY; X rt->rt_metric = metric; X insque(rt, rh); X TRACE_ACTION("ADD", rt); X /* X * If the ioctl fails because the gateway is unreachable X * from this host, discard the entry. This should only X * occur because of an incorrect entry in /etc/gateways. X */ X if (install && (rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 && X ioctl(rs, SIOCADDRT, (char *)&rt->rt_rt) < 0) { X if (errno != EEXIST && gate->sa_family < af_max) X logMsg(" LOG_ERR, adding route to net/host %s through gateway %s: %m\n", X (*rd_afswitch[dst->sa_family].af_format)(dst), X (*rd_afswitch[gate->sa_family].af_format)(gate)); X perror("SIOCADDRT"); X if (errno == ENETUNREACH) { X TRACE_ACTION("DELETE", rt); X remque(rt); X free((char *)rt); X } X } } X rtchange(rt, gate, metric) X struct rt_entry *rt; X struct sockaddr *gate; X short metric; { X int add = 0, delete = 0, newgateway = 0; X struct rtentry oldroute; X X if (!equal(&rt->rt_router, gate)) { X newgateway++; X TRACE_ACTION("CHANGE FROM ", rt); X } else if (metric != rt->rt_metric) X TRACE_NEWMETRIC(rt, metric); X if ((rt->rt_state & RTS_INTERNAL) == 0) { X /* X * If changing to different router, we need to add X * new route and delete old one if in the kernel. X * If the router is the same, we need to delete X * the route if has become unreachable, or re-add X * it if it had been unreachable. X */ X if (newgateway) { X add++; X if (rt->rt_metric != HOPCNT_INFINITY) X delete++; X } else if (metric == HOPCNT_INFINITY) X delete++; X else if (rt->rt_metric == HOPCNT_INFINITY) X add++; X } X if (delete) X oldroute = rt->rt_rt; X if ((rt->rt_state & RTS_INTERFACE) && delete) { X rt->rt_state &= ~RTS_INTERFACE; X rt->rt_flags |= RTF_GATEWAY; X if (metric > rt->rt_metric && delete) X logMsg(" LOG_ERR, %s route to interface %s (timed out)", X add? "changing" : "deleting", X rt->rt_ifp->int_name); X } X if (add) { X rt->rt_router = *gate; X rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router); X if (rt->rt_ifp == 0) X rt->rt_ifp = if_ifwithnet(&rt->rt_router); X } X rt->rt_metric = metric; X rt->rt_state |= RTS_CHANGED; X if (newgateway) X TRACE_ACTION("CHANGE TO ", rt); X if (add && install) X if (ioctl(rs, SIOCADDRT, (char *)&rt->rt_rt) < 0) X perror("SIOCADDRT"); X if (delete && install) X if (ioctl(rs, SIOCDELRT, (char *)&oldroute) < 0) X perror("SIOCDELRT"); } X rtdelete(rt) X struct rt_entry *rt; { X X TRACE_ACTION("DELETE", rt); X if (rt->rt_metric < HOPCNT_INFINITY) { X if ((rt->rt_state & (RTS_INTERFACE|RTS_INTERNAL)) == RTS_INTERFACE) X logMsg(" LOG_ERR, deleting route to interface %s? timed out?", X rt->rt_ifp->int_name); X if (install && X (rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 && X ioctl(rs, SIOCDELRT, (char *)&rt->rt_rt)) X perror("SIOCDELRT"); X } X remque(rt); X free((char *)rt); } X rtdeleteall(sig) X int sig; { X register struct rthash *rh; X register struct rt_entry *rt; X struct rthash *base = hosthash; X int doinghost = 1; X again: X for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { X rt = rh->rt_forw; X for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { X if (rt->rt_state & RTS_INTERFACE || X rt->rt_metric >= HOPCNT_INFINITY) X continue; X TRACE_ACTION("DELETE", rt); X if ((rt->rt_state & (RTS_INTERNAL|RTS_EXTERNAL)) == 0 && X ioctl(rs, SIOCDELRT, (char *)&rt->rt_rt)) X perror("SIOCDELRT"); X } X } X if (doinghost) { X doinghost = 0; X base = nethash; X goto again; X } X exit(sig); } X /* X * If we have an interface to the wide, wide world, X * add an entry for an Internet default route (wildcard) to the internal X * tables and advertise it. This route is not added to the kernel routes, X * but this entry prevents us from listening to other people's defaults X * and installing them in the kernel here. X */ rtdefault() { X extern struct sockaddr inet_default; X X rtadd(&inet_default, &inet_default, 1, X RTS_CHANGED | RTS_PASSIVE | RTS_INTERNAL); } X rd_rtinit() { X register struct rthash *rh; X X for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) X rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; X for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++) X rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; } SHAR_EOF $shar_touch -am 1116154393 'vxrouted_5.1.1/tables.c' && chmod 0644 'vxrouted_5.1.1/tables.c' || echo 'restore of vxrouted_5.1.1/tables.c failed' shar_count="`wc -c < 'vxrouted_5.1.1/tables.c'`" test 8120 -eq "$shar_count" || echo "vxrouted_5.1.1/tables.c: original size 8120, current size $shar_count" rm -f _sharnew.tmp fi # ============= vxrouted_5.1.1/timer.c ============== if test -f 'vxrouted_5.1.1/timer.c' && test X"$1" != X"-c"; then echo 'x - skipping vxrouted_5.1.1/timer.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting vxrouted_5.1.1/timer.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'vxrouted_5.1.1/timer.c' && /* X * Copyright (c) 1983, 1988 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that the above copyright notice and this paragraph are X * duplicated in all such forms and that any documentation, X * advertising materials, and other materials related to such X * distribution and use acknowledge that the software was developed X * by the University of California, Berkeley. The name of the X * University may not be used to endorse or promote products derived X * from this software without specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. X */ X #ifndef lint static char sccsid[] = "@(#)timer.c 5.8 (Berkeley) 2/18/89"; #endif /* not lint */ X /* X * Routing Table Management Daemon X */ #include "defs.h" X int faketime; X /* X * Timer routine. Performs routing information supply X * duties and manages timers on routing table entries. X * Management of the RTS_CHANGED bit assumes that we broadcast X * each time called. X */ timer() { X register struct rthash *rh; X register struct rt_entry *rt; X struct rthash *base = hosthash; X int doinghost = 1, timetobroadcast; X extern int externalinterfaces; X X (void) gettimeofday(&now, (struct timezone *)NULL); X faketime += TIMER_RATE; X if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0) X rd_ifinit(); X timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0; again: X for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { X rt = rh->rt_forw; X for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { X /* X * We don't advance time on a routing entry for X * a passive gateway, or any interface if we're X * not acting as supplier. X */ X if (!(rt->rt_state & RTS_PASSIVE) && X (supplier || !(rt->rt_state & RTS_INTERFACE))) X rt->rt_timer += TIMER_RATE; X if (rt->rt_timer >= GARBAGE_TIME) { X rt = rt->rt_back; X rtdelete(rt->rt_forw); X continue; X } X if (rt->rt_timer >= EXPIRE_TIME && X rt->rt_metric < HOPCNT_INFINITY) X rtchange(rt, &rt->rt_router, HOPCNT_INFINITY); X rt->rt_state &= ~RTS_CHANGED; X } X } X if (doinghost) { X doinghost = 0; X base = nethash; X goto again; X } X if (timetobroadcast) { X toall(supply, 0, (struct interface *)NULL); X lastbcast = now; X lastfullupdate = now; X needupdate = 0; /* cancel any pending dynamic update */ X nextbcast.tv_sec = 0; X } } X /* X * On hangup, let everyone know we're going away. X */ hup() { X register struct rthash *rh; X register struct rt_entry *rt; X struct rthash *base = hosthash; X int doinghost = 1; X X if (supplier) { again: X for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { X rt = rh->rt_forw; X for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) X rt->rt_metric = HOPCNT_INFINITY; X } X if (doinghost) { X doinghost = 0; X base = nethash; X goto again; X } X toall(supply, 0, (struct interface *)NULL); X } X exit(1); } SHAR_EOF $shar_touch -am 1116145593 'vxrouted_5.1.1/timer.c' && chmod 0644 'vxrouted_5.1.1/timer.c' || echo 'restore of vxrouted_5.1.1/timer.c failed' shar_count="`wc -c < 'vxrouted_5.1.1/timer.c'`" test 3059 -eq "$shar_count" || echo "vxrouted_5.1.1/timer.c: original size 3059, current size $shar_count" rm -f _sharnew.tmp fi # ============= vxrouted_5.1.1/trace.c ============== if test -f 'vxrouted_5.1.1/trace.c' && test X"$1" != X"-c"; then echo 'x - skipping vxrouted_5.1.1/trace.c (File already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting vxrouted_5.1.1/trace.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'vxrouted_5.1.1/trace.c' && /* X * Copyright (c) 1983, 1988 Regents of the University of California. X * All rights reserved. X * X * Redistribution and use in source and binary forms are permitted X * provided that the above copyright notice and this paragraph are X * duplicated in all such forms and that any documentation, X * advertising materials, and other materials related to such X * distribution and use acknowledge that the software was developed X * by the University of California, Berkeley. The name of the X * University may not be used to endorse or promote products derived X * from this software without specific prior written permission. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. X */ X #ifndef lint static char sccsid[] = "@(#)trace.c 5.8 (Berkeley) 2/18/89"; #endif /* not lint */ X /* X * Routing Table Management Daemon X */ #define RIPCMDS #include "defs.h" /* #include */ #include #include #include X #define NRECORDS 50 /* size of circular trace buffer */ #ifdef DEBUG FILE *ftrace = stdout; int traceactions = 0; #endif static struct timeval lastlog; static char *savetracename; char intabuf[INET_ADDR_LEN]; X #define O_RDWR 2 /* +1 == FREAD|FWRITE */ X traceinit(ifp) X register struct interface *ifp; { X X if (iftraceinit(ifp, &ifp->int_input) && X iftraceinit(ifp, &ifp->int_output)) X return; X tracehistory = 0; X fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name); } X static iftraceinit(ifp, ifd) X struct interface *ifp; X register struct ifdebug *ifd; { X register struct iftrace *t; X X ifd->ifd_records = X (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace)); X if (ifd->ifd_records == 0) X return (0); X ifd->ifd_front = ifd->ifd_records; X ifd->ifd_count = 0; X for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) { X t->ift_size = 0; X t->ift_packet = 0; X } X ifd->ifd_if = ifp; X return (1); } X traceon(file) X char *file; { X struct stat stbuf; X X if (ftrace != NULL) X return; X if (stat(file, &stbuf) >= 0 && (stbuf.st_mode & S_IFMT) != S_IFREG) X return; X savetracename = file; X (void) gettimeofday(&now, (struct timezone *)NULL); X ftrace = fopen(file, "a"); X if (ftrace == NULL) X return; /* dup2(fileno(ftrace), 1); */ /* dup2(fileno(ftrace), 2); */ X traceactions = 1; X fprintf(ftrace, "Tracing enabled %s\n", ctime((time_t *)&now.tv_sec)); } X traceoff() { X if (!traceactions) X return; X if (ftrace != NULL) { X int fd = open("/dev/null", O_RDWR); X X fprintf(ftrace, "Tracing disabled %s\n", X ctime((time_t *)&now.tv_sec)); X fflush(ftrace); /* (void) dup2(fd, 1); */ /* (void) dup2(fd, 2); */ X (void) close(fd); X fclose(ftrace); X ftrace = NULL; X } X traceactions = 0; X tracehistory = 0; X tracepackets = 0; X tracecontents = 0; } X sigtrace(s) X int s; { X X if (s == SIGUSR2) X traceoff(); X else if (ftrace == NULL && savetracename) X traceon(savetracename); X else X bumploglevel(); } X /* X * Move to next higher level of tracing when -t option processed or X * SIGUSR1 is received. Successive levels are: X * traceactions X * traceactions + tracepackets X * traceactions + tracehistory (packets and contents after change) X * traceactions + tracepackets + tracecontents X */ bumploglevel() { X X (void) gettimeofday(&now, (struct timezone *)NULL); X if (traceactions == 0) { X traceactions++; X if (ftrace) X fprintf(ftrace, "Tracing actions started %s\n", X ctime((time_t *)&now.tv_sec)); X } else if (tracepackets == 0) { X tracepackets++; X tracehistory = 0; X tracecontents = 0; X if (ftrace) X fprintf(ftrace, "Tracing packets started %s\n", X ctime((time_t *)&now.tv_sec)); X } else if (tracehistory == 0) { X tracehistory++; X if (ftrace) X fprintf(ftrace, "Tracing history started %s\n", X ctime((time_t *)&now.tv_sec)); X } else { X tracepackets++; X tracecontents++; X tracehistory = 0; X if (ftrace) X fprintf(ftrace, "Tracing packet contents started %s\n", X ctime((time_t *)&now.tv_sec)); X } X if (ftrace) X fflush(ftrace); } X trace(ifd, who, p, len, m) X register struct ifdebug *ifd; X struct sockaddr *who; X char *p; X int len, m; { X register struct iftrace *t; X X if (ifd->ifd_records == 0) X return; X t = ifd->ifd_front++; X if (ifd->ifd_front >= ifd->ifd_records + NRECORDS) X ifd->ifd_front = ifd->ifd_records; X if (ifd->ifd_count < NRECORDS) X ifd->ifd_count++; X if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) { X free(t->ift_packet); X t->ift_packet = 0; X } X t->ift_stamp = now; X t->ift_who = *who; X if (len > 0 && t->ift_packet == 0) { X t->ift_packet = malloc(len); X if (t->ift_packet == 0) X len = 0; X } X if (len > 0) X bcopy(p, t->ift_packet, len); X t->ift_size = len; X t->ift_metric = m; } X traceaction(fd, action, rt) X FILE *fd; X char *action; X struct rt_entry *rt; { X struct sockaddr_in *dst, *gate; X static struct bits { X int t_bits; X char *t_name; X } flagbits[] = { X { RTF_UP, "UP" }, X { RTF_GATEWAY, "GATEWAY" }, X { RTF_HOST, "HOST" }, X { 0 } X }, statebits[] = { X { RTS_PASSIVE, "PASSIVE" }, X { RTS_REMOTE, "REMOTE" }, X { RTS_INTERFACE,"INTERFACE" }, X { RTS_CHANGED, "CHANGED" }, X { RTS_INTERNAL, "INTERNAL" }, X { RTS_EXTERNAL, "EXTERNAL" }, X { RTS_SUBNET, "SUBNET" }, X { 0 } X }; X register struct bits *p; X register int first; X char *cp; X struct interface *ifp; X X if (fd == NULL) X return; X if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { X fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); X lastlog = now; X } X fprintf(fd, "%s ", action); X dst = (struct sockaddr_in *)&rt->rt_dst; X gate = (struct sockaddr_in *)&rt->rt_router; X inet_ntoa_b(dst->sin_addr,intabuf); X fprintf(fd, "dst %s, ", intabuf); X inet_ntoa_b(gate->sin_addr,intabuf); X fprintf(fd, "router %s, metric %d, flags", X intabuf, rt->rt_metric); X cp = " %s"; X for (first = 1, p = flagbits; p->t_bits > 0; p++) { X if ((rt->rt_flags & p->t_bits) == 0) X continue; X fprintf(fd, cp, p->t_name); X if (first) { X cp = "|%s"; X first = 0; X } X } X fprintf(fd, " state"); X cp = " %s"; X for (first = 1, p = statebits; p->t_bits > 0; p++) { X if ((rt->rt_state & p->t_bits) == 0) X continue; X fprintf(fd, cp, p->t_name); X if (first) { X cp = "|%s"; X first = 0; X } X } X fprintf(fd, " timer %d\n", rt->rt_timer); X if (tracehistory && !tracepackets && X (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) X dumpif(fd, rt->rt_ifp); X fflush(fd); X if (ferror(fd)) X traceoff(); } X tracenewmetric(fd, rt, newmetric) X FILE *fd; X struct rt_entry *rt; X int newmetric; { X struct sockaddr_in *dst, *gate; X X if (fd == NULL) X return; X if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) { X fprintf(fd, "\n%.19s:\n", ctime((time_t *)&now.tv_sec)); X lastlog = now; X } X dst = (struct sockaddr_in *)&rt->rt_dst; X gate = (struct sockaddr_in *)&rt->rt_router; X inet_ntoa_b(dst->sin_addr,intabuf); X fprintf(fd, "CHANGE metric dst %s, ", intabuf); X inet_ntoa_b(gate->sin_addr,intabuf); X fprintf(fd, "router %s, from %d to %d\n", X intabuf, rt->rt_metric, newmetric); X fflush(fd); X if (ferror(fd)) X traceoff(); } X dumpif(fd, ifp) X FILE *fd; X register struct interface *ifp; { X if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { X fprintf(fd, "*** Packet history for interface %s ***\n", X ifp->int_name); #ifdef notneeded X dumptrace(fd, "to", &ifp->int_output); #endif X dumptrace(fd, "from", &ifp->int_input); X fprintf(fd, "*** end packet history ***\n"); X } } X dumptrace(fd, dir, ifd) X FILE *fd; X char *dir; X register struct ifdebug *ifd; { X register struct iftrace *t; X char *cp = !strcmp(dir, "to") ? "Output" : "Input"; X X if (ifd->ifd_front == ifd->ifd_records && X ifd->ifd_front->ift_size == 0) { X fprintf(fd, "%s: no packets.\n", cp); X fflush(fd); X return; X } X fprintf(fd, "%s trace:\n", cp); X t = ifd->ifd_front - ifd->ifd_count; X if (t < ifd->ifd_records) X t += NRECORDS; X for ( ; ifd->ifd_count; ifd->ifd_count--, t++) { X if (t >= ifd->ifd_records + NRECORDS) X t = ifd->ifd_records; X if (t->ift_size == 0) X continue; X dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size, X &t->ift_stamp); X } } X dumppacket(fd, dir, who, cp, size, stamp) X FILE *fd; X struct sockaddr_in *who; /* should be sockaddr */ X char *dir, *cp; X register int size; X struct timeval *stamp; { X register struct rip *msg = (struct rip *)cp; X register struct netinfo *n; X X if (fd == NULL) SHAR_EOF : || echo 'restore of vxrouted_5.1.1/trace.c failed' fi echo 'End of archive part 4' echo 'File vxrouted_5.1.1/trace.c is continued in part 5' echo 5 > _sharseq.tmp exit 0