Change licensing/use notice.
[unix-history] / usr / src / sys / netns / ns_error.c
CommitLineData
8ae0e4b4 1/*
240edf1f
KS
2 * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California.
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 *
12 * @(#)ns_error.c 7.3 (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
42/*
43 * Generate an error packet of type error
44 * in response to bad packet.
45 */
46
47ns_error(om, type, param)
48 struct mbuf *om;
49 int type;
50{
51 register struct ns_epidp *ep;
52 struct mbuf *m;
53 struct idp *nip;
54 register struct idp *oip = mtod(om, struct idp *);
55 extern int idpcksum;
56
233a75ef
KS
57 /*
58 * If this packet was sent to the echo port,
59 * and nobody was there, just echo it.
60 * (Yes, this is a wart!)
61 */
62 if (type==NS_ERR_NOSOCK &&
63 oip->idp_dna.x_port==htons(2) &&
64 (type = ns_echo(oip)==0))
65 return;
66
bedb3747
KS
67#ifdef NS_ERRPRINTFS
68 if (ns_errprintfs)
69 printf("ns_err_error(%x, %d, %d)\n", oip, type, param);
70#endif
9fa7f9e6
KS
71 /*
72 * Don't Generate error packets in response to multicasts.
73 */
74 if (oip->idp_dna.x_host.c_host[0] & 1)
75 goto free;
76
bedb3747
KS
77 ns_errstat.ns_es_error++;
78 /*
79 * Make sure that the old IDP packet had 30 bytes of data to return;
80 * if not, don't bother. Also don't EVER error if the old
81 * packet protocol was NS_ERR.
82 */
83 if (oip->idp_len < sizeof(struct idp)) {
84 ns_errstat.ns_es_oldshort++;
85 goto free;
86 }
87 if (oip->idp_pt == NSPROTO_ERROR) {
88 ns_errstat.ns_es_oldns_err++;
89 goto free;
90 }
91
92 /*
93 * First, formulate ns_err message
94 */
95 m = m_get(M_DONTWAIT, MT_HEADER);
96 if (m == NULL)
97 goto free;
98 m->m_len = sizeof(*ep);
99 m->m_off = MMAXOFF - m->m_len;
100 ep = mtod(m, struct ns_epidp *);
101 if ((u_int)type > NS_ERR_TOO_BIG)
102 panic("ns_err_error");
103 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
f97be0c9
KS
104 ep->ns_ep_errp.ns_err_num = htons((u_short)type);
105 ep->ns_ep_errp.ns_err_param = htons((u_short)param);
bedb3747
KS
106 bcopy((caddr_t)oip, (caddr_t)&ep->ns_ep_errp.ns_err_idp, 42);
107 nip = &ep->ns_ep_idp;
108 nip->idp_len = sizeof(*ep);
109 nip->idp_len = htons((u_short)nip->idp_len);
110 nip->idp_pt = NSPROTO_ERROR;
111 nip->idp_tc = 0;
112 nip->idp_dna = oip->idp_sna;
113 nip->idp_sna = oip->idp_dna;
114 if (idpcksum) {
115 nip->idp_sum = 0;
116 nip->idp_sum = ns_cksum(dtom(nip), sizeof(*ep));
117 } else
118 nip->idp_sum = 0xffff;
f97be0c9 119 (void) ns_output(dtom(nip), (struct route *)0, 0);
bedb3747
KS
120
121free:
122 m_freem(dtom(oip));
123}
124
bedb3747
KS
125ns_printhost(p)
126register struct ns_addr *p;
127{
128
129 printf("<net:%x%x,host:%x%x%x,port:%x>",
130 p->x_net.s_net[0],
131 p->x_net.s_net[1],
132 p->x_host.s_host[0],
133 p->x_host.s_host[1],
134 p->x_host.s_host[2],
135 p->x_port);
136
137}
138
139/*
140 * Process a received NS_ERR message.
141 */
142ns_err_input(m)
143 struct mbuf *m;
144{
145 register struct ns_errp *ep;
146 register struct ns_epidp *epidp = mtod(m, struct ns_epidp *);
147 register int i;
148 int type, code, param;
bedb3747
KS
149
150 /*
151 * Locate ns_err structure in mbuf, and check
152 * that not corrupted and of at least minimum length.
153 */
154#ifdef NS_ERRPRINTFS
155 if (ns_errprintfs) {
156 printf("ns_err_input from ");
157 ns_printhost(&epidp->ns_ep_idp.idp_sna);
158 printf("len %d\n", ntohs(epidp->ns_ep_idp.idp_len));
159 }
160#endif
161 i = sizeof (struct ns_epidp);
162 if ((m->m_off > MMAXOFF || m->m_len < i) &&
163 (m = m_pullup(m, i)) == 0) {
164 ns_errstat.ns_es_tooshort++;
165 return;
166 }
167 ep = &(mtod(m, struct ns_epidp *)->ns_ep_errp);
168 type = ntohs(ep->ns_err_num);
169 param = ntohs(ep->ns_err_param);
9fa7f9e6 170 ns_errstat.ns_es_inhist[ns_err_x(type)]++;
bedb3747
KS
171
172#ifdef NS_ERRPRINTFS
173 /*
174 * Message type specific processing.
175 */
176 if (ns_errprintfs)
177 printf("ns_err_input, type %d param %d\n", type, param);
178#endif
179 if (type >= NS_ERR_TOO_BIG) {
180 goto badcode;
181 }
182 ns_errstat.ns_es_outhist[ns_err_x(type)]++;
183 switch (type) {
184
185 case NS_ERR_UNREACH_HOST:
186 code = PRC_UNREACH_NET;
187 goto deliver;
188
189 case NS_ERR_TOO_OLD:
190 code = PRC_TIMXCEED_INTRANS;
191 goto deliver;
192
193 case NS_ERR_TOO_BIG:
194 code = PRC_MSGSIZE;
195 goto deliver;
196
197 case NS_ERR_FULLUP:
198 code = PRC_QUENCH;
199 goto deliver;
200
201 case NS_ERR_NOSOCK:
202 code = PRC_UNREACH_PORT;
203 goto deliver;
204
205 case NS_ERR_UNSPEC_T:
206 case NS_ERR_BADSUM_T:
207 case NS_ERR_BADSUM:
208 case NS_ERR_UNSPEC:
209 code = PRC_PARAMPROB;
210 goto deliver;
211
212 deliver:
213 /*
214 * Problem with datagram; advise higher level routines.
215 */
216#ifdef NS_ERRPRINTFS
217 if (ns_errprintfs)
218 printf("deliver to protocol %d\n",
219 ep->ns_err_idp.idp_pt);
220#endif
221 switch(ep->ns_err_idp.idp_pt) {
222 case NSPROTO_SPP:
223 spp_ctlinput(code, (caddr_t)ep);
224 break;
225
226 default:
227 idp_ctlinput(code, (caddr_t)ep);
228 }
229
230 goto free;
231
232 default:
233 badcode:
234 ns_errstat.ns_es_badcode++;
235 goto free;
236
237 }
238free:
239 m_freem(m);
240}
233a75ef 241
58bca61d 242#ifdef notdef
bedb3747
KS
243u_long
244nstime()
245{
aaf09736 246 int s = splclock();
bedb3747
KS
247 u_long t;
248
249 t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000;
250 splx(s);
251 return (htonl(t));
252}
58bca61d 253#endif
233a75ef
KS
254
255ns_echo(idp)
256register struct idp *idp;
257{
258 struct mbuf *m = dtom(idp);
259 register struct echo {
260 struct idp ec_idp;
261 u_short ec_op; /* Operation, 1 = request, 2 = reply */
262 } *ec = (struct echo *)idp;
263 struct ns_addr temp;
264
265 if (idp->idp_pt!=NSPROTO_ECHO) return(NS_ERR_NOSOCK);
266 if (ec->ec_op!=htons(1)) return(NS_ERR_UNSPEC);
267
268 ec->ec_op = htons(2);
269
270 temp = idp->idp_dna;
271 idp->idp_dna = idp->idp_sna;
272 idp->idp_sna = temp;
273
274 if (idp->idp_sum != 0xffff) {
275 idp->idp_sum = 0;
58bca61d
MK
276 idp->idp_sum = ns_cksum(m,
277 (int)(((ntohs(idp->idp_len) - 1)|1)+1));
233a75ef 278 }
8011f5df 279 (void) ns_output(m, (struct route *)0, NS_FORWARDING);
233a75ef
KS
280 return(0);
281}