Annotation of kernel/bsd/netiso/clnp_er.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.