syscons util remove use kbdcontrol & vidcontrol instead
[unix-history] / usr.sbin / XNSrouted / input.c
CommitLineData
18916298
RG
1/*
2 * Copyright (c) 1985 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This file includes significant work done at Cornell University by
6 * Bill Nesheim. That work included by permission.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38static char sccsid[] = "@(#)input.c 5.9 (Berkeley) 6/1/90";
39#endif /* not lint */
40
41/*
42 * XNS Routing Table Management Daemon
43 */
44#include "defs.h"
45
46struct sockaddr *
47xns_nettosa(net)
48union ns_net net;
49{
50 static struct sockaddr_ns sxn;
51 extern char ether_broadcast_addr[6];
52
53 bzero(&sxn, sizeof (struct sockaddr_ns));
54 sxn.sns_family = AF_NS;
55 sxn.sns_len = sizeof (sxn);
56 sxn.sns_addr.x_net = net;
57 sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr;
58 return( (struct sockaddr *)&sxn);
59
60}
61
62/*
63 * Process a newly received packet.
64 */
65rip_input(from, size)
66 struct sockaddr *from;
67 int size;
68{
69 struct rt_entry *rt;
70 struct netinfo *n;
71 struct interface *ifp;
72 int newsize;
73 struct afswitch *afp;
74
75
76 ifp = 0;
77 TRACE_INPUT(ifp, from, size);
78 if (from->sa_family >= AF_MAX)
79 return;
80 afp = &afswitch[from->sa_family];
81
82 size -= sizeof (u_short) /* command */;
83 n = msg->rip_nets;
84
85 switch (ntohs(msg->rip_cmd)) {
86
87 case RIPCMD_REQUEST:
88 newsize = 0;
89 while (size > 0) {
90 if (size < sizeof (struct netinfo))
91 break;
92 size -= sizeof (struct netinfo);
93
94 /*
95 * A single entry with rip_dst == DSTNETS_ALL and
96 * metric ``infinity'' means ``all routes''.
97 */
98 if (ns_neteqnn(n->rip_dst, ns_anynet) &&
99 ntohs(n->rip_metric) == HOPCNT_INFINITY &&
100 size == 0) {
101 ifp = if_ifwithnet(from);
102 supply(from, 0, ifp);
103 return;
104 }
105 /*
106 * request for specific nets
107 */
108 rt = rtlookup(xns_nettosa(n->rip_dst));
109 if (ftrace) {
110 fprintf(ftrace,
111 "specific request for %s",
112 xns_nettoa(n->rip_dst));
113 fprintf(ftrace,
114 " yields route %x\n",
115 rt);
116 }
117 n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY :
118 min(rt->rt_metric+1, HOPCNT_INFINITY));
119 n++;
120 newsize += sizeof (struct netinfo);
121 }
122 if (newsize > 0) {
123 msg->rip_cmd = htons(RIPCMD_RESPONSE);
124 newsize += sizeof (u_short);
125 /* should check for if with dstaddr(from) first */
126 (*afp->af_output)(0, from, newsize);
127 ifp = if_ifwithnet(from);
128 TRACE_OUTPUT(ifp, from, newsize);
129 if (ftrace) {
130 fprintf(ftrace,
131 "request arrived on interface %s\n",
132 ifp->int_name);
133 }
134 }
135 return;
136
137 case RIPCMD_RESPONSE:
138 /* verify message came from a router */
139 if ((*afp->af_portmatch)(from) == 0)
140 return;
141 (*afp->af_canon)(from);
142 /* are we talking to ourselves? */
143 if (ifp = if_ifwithaddr(from)) {
144 rt = rtfind(from);
145 if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0)
146 addrouteforif(ifp);
147 else
148 rt->rt_timer = 0;
149 return;
150 }
151 /* Update timer for interface on which the packet arrived.
152 * If from other end of a point-to-point link that isn't
153 * in the routing tables, (re-)add the route.
154 */
155 if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) {
156 if(ftrace) fprintf(ftrace, "Got route\n");
157 rt->rt_timer = 0;
158 } else if (ifp = if_ifwithdstaddr(from)) {
159 if(ftrace) fprintf(ftrace, "Got partner\n");
160 addrouteforif(ifp);
161 }
162 for (; size > 0; size -= sizeof (struct netinfo), n++) {
163 struct sockaddr *sa;
164 if (size < sizeof (struct netinfo))
165 break;
166 if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY)
167 continue;
168 rt = rtfind(sa = xns_nettosa(n->rip_dst));
169 if (rt == 0) {
170 rtadd(sa, from, ntohs(n->rip_metric), 0);
171 continue;
172 }
173
174 /*
175 * Update if from gateway and different,
176 * from anywhere and shorter, or getting stale and equivalent.
177 */
178 if ((equal(from, &rt->rt_router) &&
179 ntohs(n->rip_metric) != rt->rt_metric ) ||
180 (unsigned) ntohs(n->rip_metric) < rt->rt_metric ||
181 (rt->rt_timer > (EXPIRE_TIME/2) &&
182 rt->rt_metric == ntohs(n->rip_metric))) {
183 rtchange(rt, from, ntohs(n->rip_metric));
184 rt->rt_timer = 0;
185 }
186 }
187 return;
188 }
189}