add ioctl to resynch bad sector table; no union in kernel or standalone
[unix-history] / usr / src / sys / netns / ns_error.c
CommitLineData
8ae0e4b4 1/*
d5678156 2 * Copyright (c) 1984, 1988 Regents of the University of California.
240edf1f 3 * All rights reserved.
8ae0e4b4 4 *
240edf1f
KS
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
11 *
dc9ba710 12 * @(#)ns_error.c 7.5 (Berkeley) %G%
8ae0e4b4 13 */
bedb3747
KS
14
15#include "param.h"
16#include "systm.h"
17#include "mbuf.h"
18#include "protosw.h"
19#include "socket.h"
20#include "time.h"
21#include "kernel.h"
22
23#include "../net/route.h"
24
25#include "ns.h"
26#include "ns_pcb.h"
27#include "idp.h"
28#include "ns_error.h"
29
f97be0c9
KS
30#ifdef lint
31#define NS_ERRPRINTFS 1
32#endif
33
bedb3747
KS
34#ifdef NS_ERRPRINTFS
35/*
36 * NS_ERR routines: error generation, receive packet processing, and
233a75ef 37 * routines to turnaround packets back to the originator.
bedb3747
KS
38 */
39int ns_errprintfs = 0;
40#endif
41
dc9ba710 42ns_err_x(c)
d5678156
KS
43{
44 register u_short *w, *lim, *base = ns_errstat.ns_es_codes;
45 u_short x = c;
46
47 /*
48 * zero is a legit error code, handle specially
49 */
50 if (x == 0)
51 return (0);
52 lim = base + NS_ERR_MAX - 1;
53 for (w = base + 1; w < lim; w++) {
54 if (*w == 0)
55 *w = x;
56 if (*w == x)
57 break;
58 }
59 return (w - base);
60}
61
bedb3747
KS
62/*
63 * Generate an error packet of type error
64 * in response to bad packet.
65 */
66
67ns_error(om, type, param)
68 struct mbuf *om;
69 int type;
70{
71 register struct ns_epidp *ep;
72 struct mbuf *m;
73 struct idp *nip;
74 register struct idp *oip = mtod(om, struct idp *);
75 extern int idpcksum;
76
233a75ef
KS
77 /*
78 * If this packet was sent to the echo port,
79 * and nobody was there, just echo it.
80 * (Yes, this is a wart!)
81 */
82 if (type==NS_ERR_NOSOCK &&
83 oip->idp_dna.x_port==htons(2) &&
84 (type = ns_echo(oip)==0))
85 return;
86
bedb3747
KS
87#ifdef NS_ERRPRINTFS
88 if (ns_errprintfs)
89 printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
90#endif
9fa7f9e6
KS
91 /*
92 * Don't Generate error packets in response to multicasts.
93 */
94 if (oip->idp_dna.x_host.c_host[0] & 1)
95 goto free;
96
bedb3747
KS
97 ns_errstat.ns_es_error++;
98 /*
99 * Make sure that the old IDP packet had 30 bytes of data to return;
100 * if not, don't bother. Also don't EVER error if the old
101 * packet protocol was NS_ERR.
102 */
103 if (oip->idp_len < sizeof(struct idp)) {
104 ns_errstat.ns_es_oldshort++;
105 goto free;
106 }
107 if (oip->idp_pt == NSPROTO_ERROR) {
108 ns_errstat.ns_es_oldns_err++;
109 goto free;
110 }
111
112 /*
113 * First, formulate ns_err message
114 */
115 m = m_get(M_DONTWAIT, MT_HEADER);
116 if (m == NULL)
117 goto free;
118 m->m_len = sizeof(*ep);
119 m->m_off = MMAXOFF - m->m_len;
120 ep = mtod(m, struct ns_epidp *);
121 if ((u_int)type > NS_ERR_TOO_BIG)
122 panic("ns_err_error");
123 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
f97be0c9
KS
124 ep->ns_ep_errp.ns_err_num = htons((u_short)type);
125 ep->ns_ep_errp.ns_err_param = htons((u_short)param);
bedb3747
KS
126 bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42);
127 nip = &ep->ns_ep_idp;
128 nip->idp_len = sizeof(*ep);
129 nip->idp_len = htons((u_short)nip->idp_len);
130 nip->idp_pt = NSPROTO_ERROR;
131 nip->idp_tc = 0;
132 nip->idp_dna = oip->idp_sna;
133 nip->idp_sna = oip->idp_dna;
134 if (idpcksum) {
135 nip->idp_sum = 0;
136 nip->idp_sum = ns_cksum(dtom(nip), sizeof(*ep));
137 } else
138 nip->idp_sum = 0xffff;
f97be0c9 139 (void) ns_output(dtom(nip), (struct route *)0, 0);
bedb3747
KS
140
141free:
142 m_freem(dtom(oip));
143}
144
bedb3747
KS
145ns_printhost(p)
146register struct ns_addr *p;
147{
148
149 printf("<net:%x%x,host:%x%x%x,port:%x>",
150 p->x_net.s_net[0],
151 p->x_net.s_net[1],
152 p->x_host.s_host[0],
153 p->x_host.s_host[1],
154 p->x_host.s_host[2],
155 p->x_port);
156
157}
158
159/*
160 * Process a received NS_ERR message.
161 */
162ns_err_input(m)
163 struct mbuf *m;
164{
165 register struct ns_errp *ep;
166 register struct ns_epidp *epidp = mtod(m, struct ns_epidp *);
167 register int i;
168 int type, code, param;
bedb3747
KS
169
170 /*
171 * Locate ns_err structure in mbuf, and check
172 * that not corrupted and of at least minimum length.
173 */
174#ifdef NS_ERRPRINTFS
175 if (ns_errprintfs) {
176 printf("ns_err_input from ");
177 ns_printhost(&epidp->ns_ep_idp.idp_sna);
178 printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len));
179 }
180#endif
181 i = sizeof (struct ns_epidp);
182 if ((m->m_off > MMAXOFF || m->m_len < i) &&
183 (m = m_pullup(m, i)) == 0) {
184 ns_errstat.ns_es_tooshort++;
185 return;
186 }
187 ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp);
188 type = ntohs(ep->ns_err_num);
189 param = ntohs(ep->ns_err_param);
9fa7f9e6 190 ns_errstat.ns_es_inhist[ns_err_x(type)]++;
bedb3747
KS
191
192#ifdef NS_ERRPRINTFS
193 /*
194 * Message type specific processing.
195 */
196 if (ns_errprintfs)
197 printf("ns_err_input, type %d param %d\n", type, param);
198#endif
199 if (type >= NS_ERR_TOO_BIG) {
200 goto badcode;
201 }
202 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
203 switch (type) {
204
205 case NS_ERR_UNREACH_HOST:
206 code = PRC_UNREACH_NET;
207 goto deliver;
208
209 case NS_ERR_TOO_OLD:
210 code = PRC_TIMXCEED_INTRANS;
211 goto deliver;
212
213 case NS_ERR_TOO_BIG:
214 code = PRC_MSGSIZE;
215 goto deliver;
216
217 case NS_ERR_FULLUP:
218 code = PRC_QUENCH;
219 goto deliver;
220
221 case NS_ERR_NOSOCK:
222 code = PRC_UNREACH_PORT;
223 goto deliver;
224
225 case NS_ERR_UNSPEC_T:
226 case NS_ERR_BADSUM_T:
227 case NS_ERR_BADSUM:
228 case NS_ERR_UNSPEC:
229 code = PRC_PARAMPROB;
230 goto deliver;
231
232 deliver:
233 /*
234 * Problem with datagram; advise higher level routines.
235 */
236#ifdef NS_ERRPRINTFS
237 if (ns_errprintfs)
238 printf("deliver to protocol %d\n",
239 ep->ns_err_idp.idp_pt);
240#endif
241 switch(ep->ns_err_idp.idp_pt) {
242 case NSPROTO_SPP:
243 spp_ctlinput(code, (caddr_t)ep);
244 break;
245
246 default:
247 idp_ctlinput(code, (caddr_t)ep);
248 }
249
250 goto free;
251
252 default:
253 badcode:
254 ns_errstat.ns_es_badcode++;
255 goto free;
256
257 }
258free:
259 m_freem(m);
260}
233a75ef 261
58bca61d 262#ifdef notdef
bedb3747
KS
263u_long
264nstime()
265{
aaf09736 266 int s = splclock();
bedb3747
KS
267 u_long t;
268
269 t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
270 splx(s);
271 return (htonl(t));
272}
58bca61d 273#endif
233a75ef
KS
274
275ns_echo(idp)
276register struct idp *idp;
277{
278 struct mbuf *m = dtom(idp);
279 register struct echo {
280 struct idp ec_idp;
281 u_short ec_op; /* Operation, 1 = request, 2 = reply */
282 } *ec = (struct echo *)idp;
283 struct ns_addr temp;
284
285 if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
286 if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
287
288 ec->ec_op = htons(2);
289
290 temp = idp->idp_dna;
291 idp->idp_dna = idp->idp_sna;
292 idp->idp_sna = temp;
293
294 if (idp->idp_sum != 0xffff) {
295 idp->idp_sum = 0;
58bca61d
MK
296 idp->idp_sum = ns_cksum(m,
297 (int)(((ntohs(idp->idp_len) - 1)|1)+1));
233a75ef 298 }
8011f5df 299 (void) ns_output(m, (struct route *)0, NS_FORWARDING);
233a75ef
KS
300 return(0);
301}