|
|
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) 1991, 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: * @(#)clnp_er.c 8.1 (Berkeley) 6/10/93
55: */
56:
57: /***********************************************************
58: Copyright IBM Corporation 1987
59:
60: All Rights Reserved
61:
62: Permission to use, copy, modify, and distribute this software and its
63: documentation for any purpose and without fee is hereby granted,
64: provided that the above copyright notice appear in all copies and that
65: both that copyright notice and this permission notice appear in
66: supporting documentation, and that the name of IBM not be
67: used in advertising or publicity pertaining to distribution of the
68: software without specific, written prior permission.
69:
70: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
71: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
72: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
73: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
74: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
75: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76: SOFTWARE.
77:
78: ******************************************************************/
79:
80: /*
81: * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
82: */
83:
84: #include <sys/param.h>
85: #include <sys/mbuf.h>
86: #include <sys/domain.h>
87: #include <sys/protosw.h>
88: #include <sys/socket.h>
89: #include <sys/socketvar.h>
90: #include <sys/errno.h>
91:
92: #include <net/if.h>
93: #include <net/route.h>
94:
95: #include <netiso/iso.h>
96: #include <netiso/iso_var.h>
97: #include <netiso/iso_pcb.h>
98: #define CLNP_ER_CODES
99: #include <netiso/clnp.h>
100: #include <netiso/clnp_stat.h>
101: #include <netiso/argo_debug.h>
102:
103: static struct clnp_fixed er_template = {
104: ISO8473_CLNP, /* network identifier */
105: 0, /* length */
106: ISO8473_V1, /* version */
107: CLNP_TTL, /* ttl */
108: CLNP_ER, /* type */
109: 0, /* segment length */
110: 0 /* checksum */
111: };
112:
113: /*
114: * FUNCTION: clnp_er_input
115: *
116: * PURPOSE: Process an ER pdu.
117: *
118: * RETURNS:
119: *
120: * SIDE EFFECTS:
121: *
122: * NOTES:
123: */
124: clnp_er_input(m, src, reason)
125: struct mbuf *m; /* ptr to packet itself */
126: struct iso_addr *src; /* ptr to src of er */
127: u_char reason; /* reason code of er */
128: {
129: int cmd = -1;
130: extern u_char clnp_protox[];
131:
132: IFDEBUG(D_CTLINPUT)
133: printf("clnp_er_input: m x%x, src %s, reason x%x\n", m,
134: clnp_iso_addrp(src), reason);
135: ENDDEBUG
136:
137: INCSTAT(cns_er_inhist[clnp_er_index(reason)]);
138: switch (reason) {
139: case GEN_NOREAS:
140: case GEN_PROTOERR:
141: break;
142: case GEN_BADCSUM:
143: cmd = PRC_PARAMPROB;
144: break;
145: case GEN_CONGEST:
146: cmd = PRC_QUENCH;
147: break;
148: case GEN_HDRSYNTAX:
149: cmd = PRC_PARAMPROB;
150: break;
151: case GEN_SEGNEEDED:
152: cmd = PRC_MSGSIZE;
153: break;
154: case GEN_INCOMPLETE:
155: cmd = PRC_PARAMPROB;
156: break;
157: case GEN_DUPOPT:
158: cmd = PRC_PARAMPROB;
159: break;
160: case ADDR_DESTUNREACH:
161: cmd = PRC_UNREACH_HOST;
162: break;
163: case ADDR_DESTUNKNOWN:
164: cmd = PRC_UNREACH_PROTOCOL;
165: break;
166: case SRCRT_UNSPECERR:
167: case SRCRT_SYNTAX:
168: case SRCRT_UNKNOWNADDR:
169: case SRCRT_BADPATH:
170: cmd = PRC_UNREACH_SRCFAIL;
171: break;
172: case TTL_EXPTRANSIT:
173: cmd = PRC_TIMXCEED_INTRANS;
174: break;
175: case TTL_EXPREASS:
176: cmd = PRC_TIMXCEED_REASS;
177: break;
178: case DISC_UNSUPPOPT:
179: case DISC_UNSUPPVERS:
180: case DISC_UNSUPPSECURE:
181: case DISC_UNSUPPSRCRT:
182: case DISC_UNSUPPRECRT:
183: cmd = PRC_PARAMPROB;
184: break;
185: case REASS_INTERFERE:
186: cmd = PRC_TIMXCEED_REASS;
187: break;
188: }
189:
190: /*
191: * tpclnp_ctlinput1 is called directly so that we don't
192: * have to build an iso_sockaddr out of src.
193: */
194: if (cmd >= 0)
195: tpclnp_ctlinput1(cmd, src);
196:
197: m_freem(m);
198: }
199:
200: /*
201: * FUNCTION: clnp_discard
202: *
203: * PURPOSE: Discard a clnp datagram
204: *
205: * RETURNS: nothing
206: *
207: * SIDE EFFECTS: Will emit an ER pdu if possible
208: *
209: * NOTES: This code assumes that we have previously tried to pull
210: * up the header of the datagram into one mbuf.
211: */
212: clnp_discard(m, reason)
213: struct mbuf *m; /* header of packet to discard */
214: char reason; /* reason for discard */
215: {
216: IFDEBUG(D_DISCARD)
217: printf("clnp_discard: m x%x, reason x%x\n", m, reason);
218: ENDDEBUG
219:
220: if (m != NULL) {
221: if (m->m_len >= sizeof(struct clnp_fixed)) {
222: register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
223:
224: if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
225: (clnp->cnf_type & CNF_ERR_OK)) {
226: clnp_emit_er(m, reason);
227: return;
228: }
229: }
230: m_freem(m);
231: }
232: }
233:
234: /*
235: * FUNCTION: clnp_emit_er
236: *
237: * PURPOSE: Send an ER pdu.
238: * The src of the of the ER pdu is the host that is sending
239: * the ER (ie. us), *not* the original destination of the
240: * packet.
241: *
242: * RETURNS: nothing
243: *
244: * SIDE EFFECTS:
245: *
246: * NOTES: Takes responsibility for freeing mbuf passed
247: * This function may be called with a packet that
248: * was created by us; in this case, do not send
249: * an ER.
250: */
251: clnp_emit_er(m, reason)
252: struct mbuf *m; /* header of packet to discard */
253: char reason; /* reason for discard */
254: {
255: register struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
256: register struct clnp_fixed *er;
257: struct route_iso route;
258: struct ifnet *ifp;
259: struct sockaddr *first_hop;
260: struct iso_addr src, dst, *our_addr;
261: caddr_t hoff, hend;
262: int total_len; /* total len of dg */
263: struct mbuf *m0; /* contains er pdu hdr */
264: struct iso_ifaddr *ia = 0;
265:
266: IFDEBUG(D_DISCARD)
267: printf("clnp_emit_er: m x%x, hdr len %d\n", m, clnp->cnf_hdr_len);
268: ENDDEBUG
269:
270: bzero((caddr_t)&route, sizeof(route));
271:
272: /*
273: * If header length is incorrect, or entire header is not contained
274: * in this mbuf, we punt
275: */
276: if ((clnp->cnf_hdr_len < CLNP_HDR_MIN) ||
277: (clnp->cnf_hdr_len > CLNP_HDR_MAX) ||
278: (clnp->cnf_hdr_len > m->m_len))
279: goto bad;
280:
281: /* extract src, dest address */
282: hend = (caddr_t)clnp + clnp->cnf_hdr_len;
283: hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
284: CLNP_EXTRACT_ADDR(dst, hoff, hend);
285: if (hoff == (caddr_t)0) {
286: goto bad;
287: }
288: CLNP_EXTRACT_ADDR(src, hoff, hend);
289: if (hoff == (caddr_t)0) {
290: goto bad;
291: }
292:
293: /*
294: * Do not send ER if we generated the packet.
295: */
296: if (clnp_ours(&src))
297: goto bad;
298:
299: /*
300: * Trim mbuf to hold only the header.
301: * This mbuf will be the 'data' of the er pdu
302: */
303: if (m->m_next != NULL) {
304: m_freem(m->m_next);
305: m->m_next = NULL;
306: }
307:
308: if (m->m_len > clnp->cnf_hdr_len)
309: m_adj(m, (int)-(m->m_len - (int)clnp->cnf_hdr_len));
310:
311: /* route er pdu: note we send pkt to src of original packet */
312: if (clnp_route(&src, &route, /* flags */0, &first_hop, &ia) != 0)
313: goto bad;
314:
315: /* compute our address based upon firsthop/ifp */
316: if (ia)
317: our_addr = &ia->ia_addr.siso_addr;
318: else
319: goto bad;
320: ifp = ia->ia_ifp;
321:
322: IFDEBUG(D_DISCARD)
323: printf("clnp_emit_er: to %s", clnp_iso_addrp(&src));
324: printf(" from %s\n", clnp_iso_addrp(our_addr));
325: ENDDEBUG
326:
327: IFDEBUG(D_DISCARD)
328: printf("clnp_emit_er: packet routed to %s\n",
329: clnp_iso_addrp(&((struct sockaddr_iso *)first_hop)->siso_addr));
330: ENDDEBUG
331:
332: /* allocate mbuf for er pdu header: punt on no space */
333: MGET(m0, M_DONTWAIT, MT_HEADER);
334: if (m0 == 0)
335: goto bad;
336:
337: m0->m_next = m;
338: er = mtod(m0, struct clnp_fixed *);
339: *er = er_template;
340:
341: /* setup src/dst on er pdu */
342: /* NOTE REVERSAL OF SRC/DST */
343: hoff = (caddr_t)er + sizeof(struct clnp_fixed);
344: CLNP_INSERT_ADDR(hoff, src);
345: CLNP_INSERT_ADDR(hoff, *our_addr);
346:
347: /*
348: * TODO: if complete src rt was specified, then reverse path, and
349: * copy into er as option.
350: */
351:
352: /* add er option */
353: *hoff++ = CLNPOVAL_ERREAS; /* code */
354: *hoff++ = 2; /* length */
355: *hoff++ = reason; /* discard reason */
356: *hoff++ = 0; /* error localization = not specified */
357:
358: /* set length */
359: er->cnf_hdr_len = m0->m_len = (u_char)(hoff - (caddr_t)er);
360: total_len = m0->m_len + m->m_len;
361: HTOC(er->cnf_seglen_msb, er->cnf_seglen_lsb, total_len);
362:
363: /* compute checksum (on header only) */
364: iso_gen_csum(m0, CLNP_CKSUM_OFF, (int)er->cnf_hdr_len);
365:
366: /* trim packet if too large for interface */
367: if (total_len > ifp->if_mtu)
368: m_adj(m0, -(total_len - ifp->if_mtu));
369:
370: /* send packet */
371: INCSTAT(cns_er_outhist[clnp_er_index(reason)]);
372: (void) (*ifp->if_output)(ifp, m0, first_hop, route.ro_rt);
373: goto done;
374:
375: bad:
376: m_freem(m);
377:
378: done:
379: /* free route if it is a temp */
380: if (route.ro_rt != NULL)
381: RTFREE(route.ro_rt);
382: }
383:
384: clnp_er_index(p)
385: u_char p;
386: {
387: register u_char *cp = clnp_er_codes + CLNP_ERRORS;
388: while (cp > clnp_er_codes) {
389: cp--;
390: if (*cp == p)
391: return (cp - clnp_er_codes);
392: }
393: return (CLNP_ERRORS + 1);
394: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.