]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netiso/clnp_er.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1991, 1993
24 * The Regents of the University of California. All rights reserved.
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
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.
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
54 * @(#)clnp_er.c 8.1 (Berkeley) 6/10/93
57 /***********************************************************
58 Copyright IBM Corporation 1987
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.
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
78 ******************************************************************/
81 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
84 #include <sys/param.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>
93 #include <net/route.h>
95 #include <netiso/iso.h>
96 #include <netiso/iso_var.h>
97 #include <netiso/iso_pcb.h>
99 #include <netiso/clnp.h>
100 #include <netiso/clnp_stat.h>
101 #include <netiso/argo_debug.h>
103 static struct clnp_fixed er_template
= {
104 ISO8473_CLNP
, /* network identifier */
106 ISO8473_V1
, /* version */
109 0, /* segment length */
114 * FUNCTION: clnp_er_input
116 * PURPOSE: Process an ER pdu.
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 */
130 extern u_char clnp_protox
[];
133 printf("clnp_er_input: m x%x, src %s, reason x%x\n", m
,
134 clnp_iso_addrp(src
), reason
);
137 INCSTAT(cns_er_inhist
[clnp_er_index(reason
)]);
160 case ADDR_DESTUNREACH
:
161 cmd
= PRC_UNREACH_HOST
;
163 case ADDR_DESTUNKNOWN
:
164 cmd
= PRC_UNREACH_PROTOCOL
;
166 case SRCRT_UNSPECERR
:
168 case SRCRT_UNKNOWNADDR
:
170 cmd
= PRC_UNREACH_SRCFAIL
;
173 cmd
= PRC_TIMXCEED_INTRANS
;
176 cmd
= PRC_TIMXCEED_REASS
;
179 case DISC_UNSUPPVERS
:
180 case DISC_UNSUPPSECURE
:
181 case DISC_UNSUPPSRCRT
:
182 case DISC_UNSUPPRECRT
:
185 case REASS_INTERFERE
:
186 cmd
= PRC_TIMXCEED_REASS
;
191 * tpclnp_ctlinput1 is called directly so that we don't
192 * have to build an iso_sockaddr out of src.
195 tpclnp_ctlinput1(cmd
, src
);
201 * FUNCTION: clnp_discard
203 * PURPOSE: Discard a clnp datagram
207 * SIDE EFFECTS: Will emit an ER pdu if possible
209 * NOTES: This code assumes that we have previously tried to pull
210 * up the header of the datagram into one mbuf.
212 clnp_discard(m
, reason
)
213 struct mbuf
*m
; /* header of packet to discard */
214 char reason
; /* reason for discard */
217 printf("clnp_discard: m x%x, reason x%x\n", m
, reason
);
221 if (m
->m_len
>= sizeof(struct clnp_fixed
)) {
222 register struct clnp_fixed
*clnp
= mtod(m
, struct clnp_fixed
*);
224 if (((clnp
->cnf_type
& CNF_TYPE
) != CLNP_ER
) &&
225 (clnp
->cnf_type
& CNF_ERR_OK
)) {
226 clnp_emit_er(m
, reason
);
235 * FUNCTION: clnp_emit_er
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
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
251 clnp_emit_er(m
, reason
)
252 struct mbuf
*m
; /* header of packet to discard */
253 char reason
; /* reason for discard */
255 register struct clnp_fixed
*clnp
= mtod(m
, struct clnp_fixed
*);
256 register struct clnp_fixed
*er
;
257 struct route_iso route
;
259 struct sockaddr
*first_hop
;
260 struct iso_addr src
, dst
, *our_addr
;
262 int total_len
; /* total len of dg */
263 struct mbuf
*m0
; /* contains er pdu hdr */
264 struct iso_ifaddr
*ia
= 0;
267 printf("clnp_emit_er: m x%x, hdr len %d\n", m
, clnp
->cnf_hdr_len
);
270 bzero((caddr_t
)&route
, sizeof(route
));
273 * If header length is incorrect, or entire header is not contained
274 * in this mbuf, we punt
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
))
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) {
288 CLNP_EXTRACT_ADDR(src
, hoff
, hend
);
289 if (hoff
== (caddr_t
)0) {
294 * Do not send ER if we generated the packet.
300 * Trim mbuf to hold only the header.
301 * This mbuf will be the 'data' of the er pdu
303 if (m
->m_next
!= NULL
) {
308 if (m
->m_len
> clnp
->cnf_hdr_len
)
309 m_adj(m
, (int)-(m
->m_len
- (int)clnp
->cnf_hdr_len
));
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)
315 /* compute our address based upon firsthop/ifp */
317 our_addr
= &ia
->ia_addr
.siso_addr
;
323 printf("clnp_emit_er: to %s", clnp_iso_addrp(&src
));
324 printf(" from %s\n", clnp_iso_addrp(our_addr
));
328 printf("clnp_emit_er: packet routed to %s\n",
329 clnp_iso_addrp(&((struct sockaddr_iso
*)first_hop
)->siso_addr
));
332 /* allocate mbuf for er pdu header: punt on no space */
333 MGET(m0
, M_DONTWAIT
, MT_HEADER
);
338 er
= mtod(m0
, struct clnp_fixed
*);
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
);
348 * TODO: if complete src rt was specified, then reverse path, and
349 * copy into er as option.
353 *hoff
++ = CLNPOVAL_ERREAS
; /* code */
354 *hoff
++ = 2; /* length */
355 *hoff
++ = reason
; /* discard reason */
356 *hoff
++ = 0; /* error localization = not specified */
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
);
363 /* compute checksum (on header only) */
364 iso_gen_csum(m0
, CLNP_CKSUM_OFF
, (int)er
->cnf_hdr_len
);
366 /* trim packet if too large for interface */
367 if (total_len
> ifp
->if_mtu
)
368 m_adj(m0
, -(total_len
- ifp
->if_mtu
));
371 INCSTAT(cns_er_outhist
[clnp_er_index(reason
)]);
372 (void) (*ifp
->if_output
)(ifp
, m0
, first_hop
, route
.ro_rt
);
379 /* free route if it is a temp */
380 if (route
.ro_rt
!= NULL
)
387 register u_char
*cp
= clnp_er_codes
+ CLNP_ERRORS
;
388 while (cp
> clnp_er_codes
) {
391 return (cp
- clnp_er_codes
);
393 return (CLNP_ERRORS
+ 1);