Annotation of 43BSDReno/sys/netiso/clnp_er.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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