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

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: }

unix.superglobalmegacorp.com

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