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