Annotation of Net2/netiso/clnp_er.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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