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