Annotation of XNU/bsd/netiso/clnp_input.c, revision 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_input.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: #include <sys/time.h>
        !            92: 
        !            93: #include <net/if.h>
        !            94: #include <net/if_types.h>
        !            95: #include <net/route.h>
        !            96: 
        !            97: #include <netiso/iso.h>
        !            98: #include <netiso/iso_var.h>
        !            99: #include <netiso/iso_snpac.h>
        !           100: #include <netiso/clnp.h>
        !           101: #include <netiso/clnl.h>
        !           102: #include <netiso/esis.h>
        !           103: #include <netinet/in_systm.h>
        !           104: #include <netinet/ip.h>
        !           105: #include <netinet/if_ether.h>
        !           106: #include <netiso/eonvar.h>
        !           107: #include <netiso/clnp_stat.h>
        !           108: #include <netiso/argo_debug.h>
        !           109: 
        !           110: #if ISO
        !           111: u_char         clnp_protox[ISOPROTO_MAX];
        !           112: struct clnl_protosw clnl_protox[256];
        !           113: int                    clnpqmaxlen = IFQ_MAXLEN;       /* RAH? why is this a variable */
        !           114: struct mbuf    *clnp_data_ck();
        !           115: 
        !           116: int    clnp_input();
        !           117: 
        !           118: int    esis_input();
        !           119: 
        !           120: #ifdef ISO_X25ESIS
        !           121: int    x25esis_input();
        !           122: #endif /* ISO_X25ESIS */
        !           123: 
        !           124: /*
        !           125:  * FUNCTION:           clnp_init
        !           126:  *
        !           127:  * PURPOSE:                    clnp initialization. Fill in clnp switch tables.
        !           128:  *
        !           129:  * RETURNS:                    none
        !           130:  *
        !           131:  * SIDE EFFECTS:       fills in clnp_protox table with correct offsets into
        !           132:  *                                     the isosw table.
        !           133:  *
        !           134:  * NOTES:                      
        !           135:  */
        !           136: clnp_init()
        !           137: {
        !           138:        register struct protosw *pr;
        !           139: 
        !           140:        /*
        !           141:         *      CLNP protox initialization
        !           142:         */
        !           143:        if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0)
        !           144:                printf("clnl_init: no raw CLNP\n");
        !           145:        else
        !           146:                clnp_protox[ISOPROTO_RAW] = pr - isosw;
        !           147: 
        !           148:        if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0)
        !           149:                printf("clnl_init: no tp/clnp\n");
        !           150:        else
        !           151:                clnp_protox[ISOPROTO_TP] = pr - isosw;
        !           152: 
        !           153:        /*
        !           154:         *      CLNL protox initialization
        !           155:         */
        !           156:        clnl_protox[ISO8473_CLNP].clnl_input = clnp_input;
        !           157: 
        !           158:        clnlintrq.ifq_maxlen = clnpqmaxlen;
        !           159: }
        !           160: 
        !           161: /*
        !           162:  * FUNCTION:           clnlintr
        !           163:  *
        !           164:  * PURPOSE:                    Process a packet on the clnl input queue
        !           165:  *
        !           166:  * RETURNS:                    nothing.
        !           167:  *
        !           168:  * SIDE EFFECTS:       
        !           169:  *
        !           170:  * NOTES:                      
        !           171:  */
        !           172: clnlintr()
        !           173: {
        !           174:        register struct mbuf            *m;             /* ptr to first mbuf of pkt */
        !           175:        register struct clnl_fixed      *clnl;  /* ptr to fixed part of clnl hdr */
        !           176:        int                                                     s;              /* save and restore priority */
        !           177:        struct clnl_protosw                     *clnlsw;/* ptr to protocol switch */
        !           178:        struct snpa_hdr                         sh;             /* subnetwork hdr */
        !           179: 
        !           180:        /*
        !           181:         *      Get next datagram off clnl input queue
        !           182:         */
        !           183: next:
        !           184:        s = splimp();
        !           185:        /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh);*/
        !           186:        IF_DEQUEUE(&clnlintrq, m);
        !           187:        splx(s);
        !           188: 
        !           189: 
        !           190:        if (m == 0)             /* nothing to do */
        !           191:                return;
        !           192:        if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.rcvif == 0) {
        !           193:                m_freem(m);
        !           194:                goto next;
        !           195:        } else {
        !           196:                register struct ifaddr *ifa;
        !           197:                for (ifa = m->m_pkthdr.rcvif->if_addrlist; ifa; ifa = ifa->ifa_next)
        !           198:                        if (ifa->ifa_addr->sa_family == AF_ISO)
        !           199:                                break;
        !           200:                if (ifa == 0) {
        !           201:                        m_freem(m);
        !           202:                        goto next;
        !           203:                }
        !           204:        }
        !           205:        bzero((caddr_t)&sh, sizeof(sh));
        !           206:        sh.snh_flags = m->m_flags & (M_MCAST|M_BCAST);
        !           207:        switch((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) {
        !           208:                extern int ether_output();
        !           209:        case IFT_EON:
        !           210:                bcopy(mtod(m, caddr_t), (caddr_t)sh.snh_dhost, sizeof(u_long));
        !           211:                bcopy(sizeof(u_long) + mtod(m, caddr_t),
        !           212:                                        (caddr_t)sh.snh_shost, sizeof(u_long));
        !           213:                sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
        !           214:                                                                _offsetof(struct eon_hdr, eonh_class)];
        !           215:                m->m_data += EONIPLEN;
        !           216:                m->m_len -= EONIPLEN;
        !           217:                m->m_pkthdr.len -= EONIPLEN;
        !           218:                break;
        !           219: 
        !           220:        default:
        !           221:                if (sh.snh_ifp->if_output == ether_output) {
        !           222:                        bcopy((caddr_t)(mtod(m, struct ether_header *)->ether_dhost),
        !           223:                                (caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost));
        !           224:                        m->m_data += sizeof (struct ether_header);
        !           225:                        m->m_len -= sizeof (struct ether_header);
        !           226:                        m->m_pkthdr.len -= sizeof (struct ether_header);
        !           227:                }
        !           228:        }
        !           229:        IFDEBUG(D_INPUT)
        !           230:                int i;
        !           231:                printf("clnlintr: src:");
        !           232:                for (i=0; i<6; i++)
        !           233:                        printf("%x%c", sh.snh_shost[i] & 0xff, (i<5) ? ':' : ' ');
        !           234:                printf(" dst:");
        !           235:                for (i=0; i<6; i++)
        !           236:                        printf("%x%c", sh.snh_dhost[i] & 0xff, (i<5) ? ':' : ' ');
        !           237:                printf("\n");
        !           238:        ENDDEBUG
        !           239: 
        !           240:        /*
        !           241:         *      Get the fixed part of the clnl header into the first mbuf.
        !           242:         *      Drop the packet if this fails.
        !           243:         *      Do not call m_pullup if we have a cluster mbuf or the
        !           244:         *      data is not there.
        !           245:         */
        !           246:        if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) &&
        !           247:                ((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) {
        !           248:                INCSTAT(cns_toosmall);  /* TODO: use clnl stats */
        !           249:                goto next;                              /* m_pullup discards mbuf */
        !           250:        }
        !           251: 
        !           252:        clnl = mtod(m, struct clnl_fixed *);
        !           253: 
        !           254:        /*
        !           255:         *      Drop packet if the length of the header is not reasonable.
        !           256:         */
        !           257:        if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) || 
        !           258:                (clnl->cnf_hdr_len > CLNP_HDR_MAX)) {
        !           259:                INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
        !           260:                m_freem(m);
        !           261:                goto next;
        !           262:        }
        !           263: 
        !           264:        /*
        !           265:         *      If the header is not contained in this mbuf, make it so.
        !           266:         *      Drop packet if this fails.
        !           267:         *      Note: m_pullup will allocate a cluster mbuf if necessary
        !           268:         */
        !           269:        if (clnl->cnf_hdr_len > m->m_len) {
        !           270:                if ((m = m_pullup(m, (int)clnl->cnf_hdr_len)) == 0) {
        !           271:                        INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
        !           272:                        goto next;      /* m_pullup discards mbuf */
        !           273:                }
        !           274:                clnl = mtod(m, struct clnl_fixed *);
        !           275:        }
        !           276: 
        !           277:        clnlsw = &clnl_protox[clnl->cnf_proto_id];
        !           278: 
        !           279: 
        !           280:        if (clnlsw->clnl_input)
        !           281:                (*clnlsw->clnl_input) (m, &sh);
        !           282:        else
        !           283:                m_freem(m);
        !           284: 
        !           285:        goto next;
        !           286: }
        !           287: 
        !           288: /*
        !           289:  * FUNCTION:           clnp_input
        !           290:  *
        !           291:  * PURPOSE:                    process an incoming clnp packet
        !           292:  *
        !           293:  * RETURNS:                    nothing
        !           294:  *
        !           295:  * SIDE EFFECTS:       increments fields of clnp_stat structure.
        !           296:  *                                     
        !           297:  * NOTES:
        !           298:  *     TODO: I would like to make seg_part a pointer into the mbuf, but 
        !           299:  *     will it be correctly aligned?
        !           300:  */
        !           301: clnp_input(m, shp)
        !           302: struct mbuf            *m;             /* ptr to first mbuf of pkt */
        !           303: struct snpa_hdr        *shp;   /* subnetwork header */
        !           304: {
        !           305:        register struct clnp_fixed      *clnp;  /* ptr to fixed part of header */
        !           306:        struct sockaddr_iso                     source; /* source address of pkt */
        !           307:        struct sockaddr_iso                     target; /* destination address of pkt */
        !           308: #define src    source.siso_addr
        !           309: #define dst    target.siso_addr
        !           310:        caddr_t                                         hoff;   /* current offset in packet */
        !           311:        caddr_t                                         hend;   /* address of end of header info */
        !           312:        struct clnp_segment                     seg_part; /* segment part of hdr */
        !           313:        int                                                     seg_off=0; /* offset of segment part of hdr */
        !           314:        int                                                     seg_len;/* length of packet data&hdr in bytes */
        !           315:        struct clnp_optidx                      oidx, *oidxp = NULL;    /* option index */
        !           316:        extern int                                      iso_systype;    /* used by ESIS config resp */
        !           317:        extern struct sockaddr_iso      blank_siso;             /* used for initializing */
        !           318:        int                                                     need_afrin = 0; 
        !           319:                                                                                /* true if congestion experienced */
        !           320:                                                                                /* which means you need afrin nose */
        !           321:                                                                                /* spray. How clever! */
        !           322: 
        !           323:        IFDEBUG(D_INPUT)
        !           324:                printf(
        !           325:                   "clnp_input: proccessing dg; First mbuf m_len %d, m_type x%x, %s\n", 
        !           326:                        m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
        !           327:        ENDDEBUG
        !           328:        need_afrin = 0;
        !           329: 
        !           330:        /*
        !           331:         *      If no iso addresses have been set, there is nothing
        !           332:         *      to do with the packet.
        !           333:         */
        !           334:        if (iso_ifaddr == NULL) {
        !           335:                clnp_discard(m, ADDR_DESTUNREACH);
        !           336:                return;
        !           337:        }
        !           338:        
        !           339:        INCSTAT(cns_total);
        !           340:        clnp = mtod(m, struct clnp_fixed *);
        !           341: 
        !           342:        IFDEBUG(D_DUMPIN)
        !           343:                struct mbuf *mhead;
        !           344:                int                     total_len = 0;
        !           345:                printf("clnp_input: clnp header:\n");
        !           346:                dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);
        !           347:                printf("clnp_input: mbuf chain:\n");
        !           348:                for (mhead = m; mhead != NULL; mhead=mhead->m_next) {
        !           349:                        printf("m x%x, len %d\n", mhead, mhead->m_len);
        !           350:                        total_len += mhead->m_len;
        !           351:                }
        !           352:                printf("clnp_input: total length of mbuf chain %d:\n", total_len);
        !           353:        ENDDEBUG
        !           354: 
        !           355:        /*
        !           356:         *      Compute checksum (if necessary) and drop packet if
        !           357:         *      checksum does not match
        !           358:         */
        !           359:        if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, (int)clnp->cnf_hdr_len)) {
        !           360:                INCSTAT(cns_badcsum);
        !           361:                clnp_discard(m, GEN_BADCSUM);
        !           362:                return;
        !           363:        }
        !           364: 
        !           365:        if (clnp->cnf_vers != ISO8473_V1) {
        !           366:                INCSTAT(cns_badvers);
        !           367:                clnp_discard(m, DISC_UNSUPPVERS);
        !           368:                return;
        !           369:        }
        !           370: 
        !           371: 
        !           372:        /* check mbuf data length: clnp_data_ck will free mbuf upon error */
        !           373:        CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
        !           374:        if ((m = clnp_data_ck(m, seg_len)) == 0)
        !           375:                return;
        !           376:        
        !           377:        clnp = mtod(m, struct clnp_fixed *);
        !           378:        hend = (caddr_t)clnp + clnp->cnf_hdr_len;
        !           379: 
        !           380:        /* 
        !           381:         *      extract the source and destination address
        !           382:         *      drop packet on failure
        !           383:         */
        !           384:        source = target = blank_siso;
        !           385: 
        !           386:        hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
        !           387:        CLNP_EXTRACT_ADDR(dst, hoff, hend);
        !           388:        if (hoff == (caddr_t)0) {
        !           389:                INCSTAT(cns_badaddr);
        !           390:                clnp_discard(m, GEN_INCOMPLETE);
        !           391:                return;
        !           392:        }
        !           393:        CLNP_EXTRACT_ADDR(src, hoff, hend);
        !           394:        if (hoff == (caddr_t)0) {
        !           395:                INCSTAT(cns_badaddr);
        !           396:                clnp_discard(m, GEN_INCOMPLETE);
        !           397:                return;
        !           398:        }
        !           399: 
        !           400:        IFDEBUG(D_INPUT)
        !           401:                printf("clnp_input: from %s", clnp_iso_addrp(&src));
        !           402:                printf(" to %s\n", clnp_iso_addrp(&dst));
        !           403:        ENDDEBUG
        !           404: 
        !           405:        /*
        !           406:         *      extract the segmentation information, if it is present.
        !           407:         *      drop packet on failure
        !           408:         */
        !           409:        if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
        !           410:                (clnp->cnf_type & CNF_SEG_OK)) {
        !           411:                if (hoff + sizeof(struct clnp_segment) > hend) {
        !           412:                        INCSTAT(cns_noseg);
        !           413:                        clnp_discard(m, GEN_INCOMPLETE);
        !           414:                        return;
        !           415:                } else {
        !           416:                        (void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment));
        !           417:                        /* make sure segmentation fields are in host order */
        !           418:                        seg_part.cng_id = ntohs(seg_part.cng_id);
        !           419:                        seg_part.cng_off = ntohs(seg_part.cng_off);
        !           420:                        seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
        !           421:                        seg_off = hoff - (caddr_t)clnp;
        !           422:                        hoff += sizeof(struct clnp_segment);
        !           423:                }
        !           424:        }
        !           425: 
        !           426:        /*
        !           427:         *      process options if present. If clnp_opt_sanity returns
        !           428:         *      false (indicating an error was found in the options) or
        !           429:         *      an unsupported option was found
        !           430:         *      then drop packet and emit an ER.
        !           431:         */
        !           432:        if (hoff < hend) {
        !           433:                int             errcode;
        !           434: 
        !           435:                oidxp = &oidx;
        !           436:                errcode = clnp_opt_sanity(m, hoff, hend-hoff, oidxp);
        !           437: 
        !           438:                /* we do not support security */
        !           439:                if ((errcode == 0) && (oidxp->cni_securep))
        !           440:                        errcode = DISC_UNSUPPSECURE;
        !           441: 
        !           442:                /* the er option is valid with ER pdus only */
        !           443:                if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) && 
        !           444:                        ((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
        !           445:                        errcode = DISC_UNSUPPOPT;
        !           446: 
        !           447: #ifdef DECBIT
        !           448:                /* check if the congestion experienced bit is set */
        !           449:                if (oidxp->cni_qos_formatp) {
        !           450:                        caddr_t qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
        !           451:                        u_char  qos = *qosp;
        !           452: 
        !           453:                        need_afrin = ((qos & (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)) ==
        !           454:                                (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED));
        !           455:                        if (need_afrin)
        !           456:                                INCSTAT(cns_congest_rcvd);
        !           457:                }
        !           458: #endif /* DECBIT */
        !           459: 
        !           460:                if (errcode != 0) {
        !           461:                        clnp_discard(m, (char)errcode);
        !           462:                        IFDEBUG(D_INPUT)
        !           463:                                printf("clnp_input: dropped (err x%x) due to bad options\n",
        !           464:                                        errcode);
        !           465:                        ENDDEBUG
        !           466:                        return;
        !           467:                }
        !           468:        }
        !           469:        
        !           470:        /*
        !           471:         *      check if this packet is for us. if not, then forward
        !           472:         */
        !           473:        if (clnp_ours(&dst) == 0) {
        !           474:                IFDEBUG(D_INPUT)
        !           475:                        printf("clnp_input: forwarding packet not for us\n");
        !           476:                ENDDEBUG
        !           477:                clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
        !           478:                return;
        !           479:        }
        !           480: 
        !           481:        /*
        !           482:         *      ESIS Configuration Response Function
        !           483:         *
        !           484:         *      If the packet received was sent to the multicast address
        !           485:         *      all end systems, then send an esh to the source
        !           486:         */
        !           487:        if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
        !           488:                extern short esis_holding_time;
        !           489: 
        !           490:                esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
        !           491:                        shp->snh_shost, 6, &dst);
        !           492:        }
        !           493: 
        !           494:        /*
        !           495:         *      If this is a fragment, then try to reassemble it. If clnp_reass
        !           496:         *      returns non NULL, the packet has been reassembled, and should
        !           497:         *      be give to TP. Otherwise the fragment has been delt with
        !           498:         *      by the reassembly code (either stored or deleted). In either case
        !           499:         *      we should have nothing more to do with it.
        !           500:         */
        !           501:        if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
        !           502:                (clnp->cnf_type & CNF_SEG_OK) &&
        !           503:                (seg_len != seg_part.cng_tot_len)) {
        !           504:                struct mbuf     *m0;
        !           505: 
        !           506:                if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
        !           507:                        m = m0;
        !           508:                        clnp = mtod(m, struct clnp_fixed *);
        !           509:                        INCSTAT(cns_reassembled);
        !           510:                } else {
        !           511:                        return;
        !           512:                }
        !           513:        }
        !           514:        
        !           515:        /*
        !           516:         *      give the packet to the higher layer
        !           517:         *
        !           518:         *      Note: the total length of packet
        !           519:         *      is the total length field of the segmentation part,
        !           520:         *      or, if absent, the segment length field of the
        !           521:         *      header.
        !           522:         */
        !           523:        INCSTAT(cns_delivered);
        !           524:        switch (clnp->cnf_type & CNF_TYPE) {
        !           525:        case CLNP_ER:
        !           526:                /*
        !           527:                 *      This ER must have the er option.
        !           528:                 *      If the option is not present, discard datagram.
        !           529:                 */
        !           530:                if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
        !           531:                        clnp_discard(m, GEN_HDRSYNTAX);
        !           532:                } else {
        !           533:                        clnp_er_input(m, &src, oidxp->cni_er_reason);
        !           534:                }
        !           535:                break;
        !           536: 
        !           537:        case CLNP_DT:
        !           538:                (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
        !           539:                        clnp->cnf_hdr_len, need_afrin);
        !           540:                break;
        !           541: 
        !           542:        case CLNP_RAW:
        !           543:        case CLNP_ECR:
        !           544:                IFDEBUG(D_INPUT)
        !           545:                        printf("clnp_input: raw input of %d bytes\n",
        !           546:                                clnp->cnf_type & CNF_SEG_OK ? seg_part.cng_tot_len : seg_len);
        !           547:                ENDDEBUG
        !           548:                (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source, &target,
        !           549:                                        clnp->cnf_hdr_len);
        !           550:                break;
        !           551: 
        !           552:        case CLNP_EC:
        !           553:                IFDEBUG(D_INPUT)
        !           554:                        printf("clnp_input: echoing packet\n");
        !           555:                ENDDEBUG
        !           556:                (void)clnp_echoreply(m,
        !           557:                        (clnp->cnf_type & CNF_SEG_OK ? (int)seg_part.cng_tot_len : seg_len),
        !           558:                        &source, &target, oidxp);
        !           559:                break;
        !           560: 
        !           561:        default:
        !           562:                printf("clnp_input: unknown clnp pkt type %d\n",
        !           563:                        clnp->cnf_type & CNF_TYPE);
        !           564:                clnp_stat.cns_delivered--;
        !           565:                clnp_stat.cns_noproto++;
        !           566:                clnp_discard(m, GEN_HDRSYNTAX);
        !           567:                break;
        !           568:        }
        !           569: }
        !           570: #endif /* ISO */

unix.superglobalmegacorp.com

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