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