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

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

unix.superglobalmegacorp.com

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