Made all header files idempotent and moved incorrect common data from
[unix-history] / sys / netns / ns_error.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1984, 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
42524852 33 * from: @(#)ns_error.c 7.8 (Berkeley) 6/28/90
8ace4366 34 * $Id: ns_error.c,v 1.3 1993/10/16 19:55:12 rgrimes Exp $
15637ed4
RG
35 */
36
37#include "param.h"
38#include "systm.h"
39#include "malloc.h"
40#include "mbuf.h"
41#include "protosw.h"
42#include "socket.h"
43#include "time.h"
44#include "kernel.h"
45
46#include "../net/route.h"
47
48#include "ns.h"
49#include "ns_pcb.h"
50#include "idp.h"
51#include "ns_error.h"
52
53#ifdef lint
54#define NS_ERRPRINTFS 1
55#endif
56
8ace4366
GW
57struct ns_errstat ns_errstat;
58
15637ed4
RG
59#ifdef NS_ERRPRINTFS
60/*
61 * NS_ERR routines: error generation, receive packet processing, and
62 * routines to turnaround packets back to the originator.
63 */
64int ns_errprintfs = 0;
65#endif
66
67ns_err_x(c)
68{
69 register u_short *w, *lim, *base = ns_errstat.ns_es_codes;
70 u_short x = c;
71
72 /*
73 * zero is a legit error code, handle specially
74 */
75 if (x == 0)
76 return (0);
77 lim = base + NS_ERR_MAX - 1;
78 for (w = base + 1; w < lim; w++) {
79 if (*w == 0)
80 *w = x;
81 if (*w == x)
82 break;
83 }
84 return (w - base);
85}
86
87/*
88 * Generate an error packet of type error
89 * in response to bad packet.
90 */
91
92ns_error(om, type, param)
93 struct mbuf *om;
94 int type;
95{
96 register struct ns_epidp *ep;
97 struct mbuf *m;
98 struct idp *nip;
99 register struct idp *oip = mtod(om, struct idp *);
100 extern int idpcksum;
101
102 /*
103 * If this packet was sent to the echo port,
104 * and nobody was there, just echo it.
105 * (Yes, this is a wart!)
106 */
107 if (type == NS_ERR_NOSOCK &&
108 oip->idp_dna.x_port == htons(2) &&
109 (type = ns_echo(om))==0)
110 return;
111
112#ifdef NS_ERRPRINTFS
113 if (ns_errprintfs)
114 printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
115#endif
116 /*
117 * Don't Generate error packets in response to multicasts.
118 */
119 if (oip->idp_dna.x_host.c_host[0] & 1)
120 goto freeit;
121
122 ns_errstat.ns_es_error++;
123 /*
124 * Make sure that the old IDP packet had 30 bytes of data to return;
125 * if not, don't bother. Also don't EVER error if the old
126 * packet protocol was NS_ERR.
127 */
128 if (oip->idp_len < sizeof(struct idp)) {
129 ns_errstat.ns_es_oldshort++;
130 goto freeit;
131 }
132 if (oip->idp_pt == NSPROTO_ERROR) {
133 ns_errstat.ns_es_oldns_err++;
134 goto freeit;
135 }
136
137 /*
138 * First, formulate ns_err message
139 */
140 m = m_gethdr(M_DONTWAIT, MT_HEADER);
141 if (m == NULL)
142 goto freeit;
143 m->m_len = sizeof(*ep);
144 MH_ALIGN(m, m->m_len);
145 ep = mtod(m, struct ns_epidp *);
146 if ((u_int)type > NS_ERR_TOO_BIG)
147 panic("ns_err_error");
148 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
149 ep->ns_ep_errp.ns_err_num = htons((u_short)type);
150 ep->ns_ep_errp.ns_err_param = htons((u_short)param);
151 bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42);
152 nip = &ep->ns_ep_idp;
153 nip->idp_len = sizeof(*ep);
154 nip->idp_len = htons((u_short)nip->idp_len);
155 nip->idp_pt = NSPROTO_ERROR;
156 nip->idp_tc = 0;
157 nip->idp_dna = oip->idp_sna;
158 nip->idp_sna = oip->idp_dna;
159 if (idpcksum) {
160 nip->idp_sum = 0;
161 nip->idp_sum = ns_cksum(m, sizeof(*ep));
162 } else
163 nip->idp_sum = 0xffff;
164 (void) ns_output(m, (struct route *)0, 0);
165
166freeit:
167 m_freem(om);
168}
169
170ns_printhost(p)
171register struct ns_addr *p;
172{
173
174 printf("<net:%x%x,host:%x%x%x,port:%x>",
175 p->x_net.s_net[0],
176 p->x_net.s_net[1],
177 p->x_host.s_host[0],
178 p->x_host.s_host[1],
179 p->x_host.s_host[2],
180 p->x_port);
181
182}
183
184/*
185 * Process a received NS_ERR message.
186 */
187ns_err_input(m)
188 struct mbuf *m;
189{
190 register struct ns_errp *ep;
191 register struct ns_epidp *epidp = mtod(m, struct ns_epidp *);
192 register int i;
193 int type, code, param;
194
195 /*
196 * Locate ns_err structure in mbuf, and check
197 * that not corrupted and of at least minimum length.
198 */
199#ifdef NS_ERRPRINTFS
200 if (ns_errprintfs) {
201 printf("ns_err_input from ");
202 ns_printhost(&epidp->ns_ep_idp.idp_sna);
203 printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len));
204 }
205#endif
206 i = sizeof (struct ns_epidp);
207 if (((m->m_flags & M_EXT) || m->m_len < i) &&
208 (m = m_pullup(m, i)) == 0) {
209 ns_errstat.ns_es_tooshort++;
210 return;
211 }
212 ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp);
213 type = ntohs(ep->ns_err_num);
214 param = ntohs(ep->ns_err_param);
215 ns_errstat.ns_es_inhist[ns_err_x(type)]++;
216
217#ifdef NS_ERRPRINTFS
218 /*
219 * Message type specific processing.
220 */
221 if (ns_errprintfs)
222 printf("ns_err_input, type %d param %d\n", type, param);
223#endif
224 if (type >= NS_ERR_TOO_BIG) {
225 goto badcode;
226 }
227 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
228 switch (type) {
229
230 case NS_ERR_UNREACH_HOST:
231 code = PRC_UNREACH_NET;
232 goto deliver;
233
234 case NS_ERR_TOO_OLD:
235 code = PRC_TIMXCEED_INTRANS;
236 goto deliver;
237
238 case NS_ERR_TOO_BIG:
239 code = PRC_MSGSIZE;
240 goto deliver;
241
242 case NS_ERR_FULLUP:
243 code = PRC_QUENCH;
244 goto deliver;
245
246 case NS_ERR_NOSOCK:
247 code = PRC_UNREACH_PORT;
248 goto deliver;
249
250 case NS_ERR_UNSPEC_T:
251 case NS_ERR_BADSUM_T:
252 case NS_ERR_BADSUM:
253 case NS_ERR_UNSPEC:
254 code = PRC_PARAMPROB;
255 goto deliver;
256
257 deliver:
258 /*
259 * Problem with datagram; advise higher level routines.
260 */
261#ifdef NS_ERRPRINTFS
262 if (ns_errprintfs)
263 printf("deliver to protocol %d\n",
264 ep->ns_err_idp.idp_pt);
265#endif
266 switch(ep->ns_err_idp.idp_pt) {
267 case NSPROTO_SPP:
268 spp_ctlinput(code, (caddr_t)ep);
269 break;
270
271 default:
272 idp_ctlinput(code, (caddr_t)ep);
273 }
274
275 goto freeit;
276
277 default:
278 badcode:
279 ns_errstat.ns_es_badcode++;
280 goto freeit;
281
282 }
283freeit:
284 m_freem(m);
285}
286
287#ifdef notdef
288u_long
289nstime()
290{
291 int s = splclock();
292 u_long t;
293
294 t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
295 splx(s);
296 return (htonl(t));
297}
298#endif
299
300ns_echo(m)
301struct mbuf *m;
302{
303 register struct idp *idp = mtod(m, struct idp *);
304 register struct echo {
305 struct idp ec_idp;
306 u_short ec_op; /* Operation, 1 = request, 2 = reply */
307 } *ec = (struct echo *)idp;
308 struct ns_addr temp;
309
310 if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
311 if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
312
313 ec->ec_op = htons(2);
314
315 temp = idp->idp_dna;
316 idp->idp_dna = idp->idp_sna;
317 idp->idp_sna = temp;
318
319 if (idp->idp_sum != 0xffff) {
320 idp->idp_sum = 0;
321 idp->idp_sum = ns_cksum(m,
322 (int)(((ntohs(idp->idp_len) - 1)|1)+1));
323 }
324 (void) ns_output(m, (struct route *)0, NS_FORWARDING);
325 return(0);
326}