Annotation of kernel/bsd/netiso/clnp_input.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*-
                     26:  * Copyright (c) 1991, 1993
                     27:  *     The Regents of the University of California.  All rights reserved.
                     28:  *
                     29:  * Redistribution and use in source and binary forms, with or without
                     30:  * modification, are permitted provided that the following conditions
                     31:  * are met:
                     32:  * 1. Redistributions of source code must retain the above copyright
                     33:  *    notice, this list of conditions and the following disclaimer.
                     34:  * 2. Redistributions in binary form must reproduce the above copyright
                     35:  *    notice, this list of conditions and the following disclaimer in the
                     36:  *    documentation and/or other materials provided with the distribution.
                     37:  * 3. All advertising materials mentioning features or use of this software
                     38:  *    must display the following acknowledgement:
                     39:  *     This product includes software developed by the University of
                     40:  *     California, Berkeley and its contributors.
                     41:  * 4. Neither the name of the University nor the names of its contributors
                     42:  *    may be used to endorse or promote products derived from this software
                     43:  *    without specific prior written permission.
                     44:  *
                     45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     55:  * SUCH DAMAGE.
                     56:  *
                     57:  *     @(#)clnp_input.c        8.1 (Berkeley) 6/10/93
                     58:  */
                     59: 
                     60: /***********************************************************
                     61:                Copyright IBM Corporation 1987
                     62: 
                     63:                       All Rights Reserved
                     64: 
                     65: Permission to use, copy, modify, and distribute this software and its 
                     66: documentation for any purpose and without fee is hereby granted, 
                     67: provided that the above copyright notice appear in all copies and that
                     68: both that copyright notice and this permission notice appear in 
                     69: supporting documentation, and that the name of IBM not be
                     70: used in advertising or publicity pertaining to distribution of the
                     71: software without specific, written prior permission.  
                     72: 
                     73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     79: SOFTWARE.
                     80: 
                     81: ******************************************************************/
                     82: 
                     83: /*
                     84:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     85:  */
                     86: 
                     87: #include <sys/param.h>
                     88: #include <sys/mbuf.h>
                     89: #include <sys/domain.h>
                     90: #include <sys/protosw.h>
                     91: #include <sys/socket.h>
                     92: #include <sys/socketvar.h>
                     93: #include <sys/errno.h>
                     94: #include <sys/time.h>
                     95: 
                     96: #include <net/if.h>
                     97: #include <net/if_types.h>
                     98: #include <net/route.h>
                     99: 
                    100: #include <netiso/iso.h>
                    101: #include <netiso/iso_var.h>
                    102: #include <netiso/iso_snpac.h>
                    103: #include <netiso/clnp.h>
                    104: #include <netiso/clnl.h>
                    105: #include <netiso/esis.h>
                    106: #include <netinet/in_systm.h>
                    107: #include <netinet/ip.h>
                    108: #include <netinet/if_ether.h>
                    109: #include <netiso/eonvar.h>
                    110: #include <netiso/clnp_stat.h>
                    111: #include <netiso/argo_debug.h>
                    112: 
                    113: #if ISO
                    114: u_char         clnp_protox[ISOPROTO_MAX];
                    115: struct clnl_protosw clnl_protox[256];
                    116: int                    clnpqmaxlen = IFQ_MAXLEN;       /* RAH? why is this a variable */
                    117: struct mbuf    *clnp_data_ck();
                    118: 
                    119: int    clnp_input();
                    120: 
                    121: int    esis_input();
                    122: 
                    123: #ifdef ISO_X25ESIS
                    124: int    x25esis_input();
                    125: #endif /* ISO_X25ESIS */
                    126: 
                    127: /*
                    128:  * FUNCTION:           clnp_init
                    129:  *
                    130:  * PURPOSE:                    clnp initialization. Fill in clnp switch tables.
                    131:  *
                    132:  * RETURNS:                    none
                    133:  *
                    134:  * SIDE EFFECTS:       fills in clnp_protox table with correct offsets into
                    135:  *                                     the isosw table.
                    136:  *
                    137:  * NOTES:                      
                    138:  */
                    139: clnp_init()
                    140: {
                    141:        register struct protosw *pr;
                    142: 
                    143:        /*
                    144:         *      CLNP protox initialization
                    145:         */
                    146:        if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0)
                    147:                printf("clnl_init: no raw CLNP\n");
                    148:        else
                    149:                clnp_protox[ISOPROTO_RAW] = pr - isosw;
                    150: 
                    151:        if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0)
                    152:                printf("clnl_init: no tp/clnp\n");
                    153:        else
                    154:                clnp_protox[ISOPROTO_TP] = pr - isosw;
                    155: 
                    156:        /*
                    157:         *      CLNL protox initialization
                    158:         */
                    159:        clnl_protox[ISO8473_CLNP].clnl_input = clnp_input;
                    160: 
                    161:        clnlintrq.ifq_maxlen = clnpqmaxlen;
                    162: }
                    163: 
                    164: /*
                    165:  * FUNCTION:           clnlintr
                    166:  *
                    167:  * PURPOSE:                    Process a packet on the clnl input queue
                    168:  *
                    169:  * RETURNS:                    nothing.
                    170:  *
                    171:  * SIDE EFFECTS:       
                    172:  *
                    173:  * NOTES:                      
                    174:  */
                    175: clnlintr()
                    176: {
                    177:        register struct mbuf            *m;             /* ptr to first mbuf of pkt */
                    178:        register struct clnl_fixed      *clnl;  /* ptr to fixed part of clnl hdr */
                    179:        int                                                     s;              /* save and restore priority */
                    180:        struct clnl_protosw                     *clnlsw;/* ptr to protocol switch */
                    181:        struct snpa_hdr                         sh;             /* subnetwork hdr */
                    182: 
                    183:        /*
                    184:         *      Get next datagram off clnl input queue
                    185:         */
                    186: next:
                    187:        s = splimp();
                    188:        /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh);*/
                    189:        IF_DEQUEUE(&clnlintrq, m);
                    190:        splx(s);
                    191: 
                    192: 
                    193:        if (m == 0)             /* nothing to do */
                    194:                return;
                    195:        if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.rcvif == 0) {
                    196:                m_freem(m);
                    197:                goto next;
                    198:        } else {
                    199:                register struct ifaddr *ifa;
                    200:                for (ifa = m->m_pkthdr.rcvif->if_addrlist; ifa; ifa = ifa->ifa_next)
                    201:                        if (ifa->ifa_addr->sa_family == AF_ISO)
                    202:                                break;
                    203:                if (ifa == 0) {
                    204:                        m_freem(m);
                    205:                        goto next;
                    206:                }
                    207:        }
                    208:        bzero((caddr_t)&sh, sizeof(sh));
                    209:        sh.snh_flags = m->m_flags & (M_MCAST|M_BCAST);
                    210:        switch((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) {
                    211:                extern int ether_output();
                    212:        case IFT_EON:
                    213:                bcopy(mtod(m, caddr_t), (caddr_t)sh.snh_dhost, sizeof(u_long));
                    214:                bcopy(sizeof(u_long) + mtod(m, caddr_t),
                    215:                                        (caddr_t)sh.snh_shost, sizeof(u_long));
                    216:                sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
                    217:                                                                _offsetof(struct eon_hdr, eonh_class)];
                    218:                m->m_data += EONIPLEN;
                    219:                m->m_len -= EONIPLEN;
                    220:                m->m_pkthdr.len -= EONIPLEN;
                    221:                break;
                    222: 
                    223:        default:
                    224:                if (sh.snh_ifp->if_output == ether_output) {
                    225:                        bcopy((caddr_t)(mtod(m, struct ether_header *)->ether_dhost),
                    226:                                (caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost));
                    227:                        m->m_data += sizeof (struct ether_header);
                    228:                        m->m_len -= sizeof (struct ether_header);
                    229:                        m->m_pkthdr.len -= sizeof (struct ether_header);
                    230:                }
                    231:        }
                    232:        IFDEBUG(D_INPUT)
                    233:                int i;
                    234:                printf("clnlintr: src:");
                    235:                for (i=0; i<6; i++)
                    236:                        printf("%x%c", sh.snh_shost[i] & 0xff, (i<5) ? ':' : ' ');
                    237:                printf(" dst:");
                    238:                for (i=0; i<6; i++)
                    239:                        printf("%x%c", sh.snh_dhost[i] & 0xff, (i<5) ? ':' : ' ');
                    240:                printf("\n");
                    241:        ENDDEBUG
                    242: 
                    243:        /*
                    244:         *      Get the fixed part of the clnl header into the first mbuf.
                    245:         *      Drop the packet if this fails.
                    246:         *      Do not call m_pullup if we have a cluster mbuf or the
                    247:         *      data is not there.
                    248:         */
                    249:        if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) &&
                    250:                ((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) {
                    251:                INCSTAT(cns_toosmall);  /* TODO: use clnl stats */
                    252:                goto next;                              /* m_pullup discards mbuf */
                    253:        }
                    254: 
                    255:        clnl = mtod(m, struct clnl_fixed *);
                    256: 
                    257:        /*
                    258:         *      Drop packet if the length of the header is not reasonable.
                    259:         */
                    260:        if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) || 
                    261:                (clnl->cnf_hdr_len > CLNP_HDR_MAX)) {
                    262:                INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
                    263:                m_freem(m);
                    264:                goto next;
                    265:        }
                    266: 
                    267:        /*
                    268:         *      If the header is not contained in this mbuf, make it so.
                    269:         *      Drop packet if this fails.
                    270:         *      Note: m_pullup will allocate a cluster mbuf if necessary
                    271:         */
                    272:        if (clnl->cnf_hdr_len > m->m_len) {
                    273:                if ((m = m_pullup(m, (int)clnl->cnf_hdr_len)) == 0) {
                    274:                        INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
                    275:                        goto next;      /* m_pullup discards mbuf */
                    276:                }
                    277:                clnl = mtod(m, struct clnl_fixed *);
                    278:        }
                    279: 
                    280:        clnlsw = &clnl_protox[clnl->cnf_proto_id];
                    281: 
                    282: 
                    283:        if (clnlsw->clnl_input)
                    284:                (*clnlsw->clnl_input) (m, &sh);
                    285:        else
                    286:                m_freem(m);
                    287: 
                    288:        goto next;
                    289: }
                    290: 
                    291: /*
                    292:  * FUNCTION:           clnp_input
                    293:  *
                    294:  * PURPOSE:                    process an incoming clnp packet
                    295:  *
                    296:  * RETURNS:                    nothing
                    297:  *
                    298:  * SIDE EFFECTS:       increments fields of clnp_stat structure.
                    299:  *                                     
                    300:  * NOTES:
                    301:  *     TODO: I would like to make seg_part a pointer into the mbuf, but 
                    302:  *     will it be correctly aligned?
                    303:  */
                    304: clnp_input(m, shp)
                    305: struct mbuf            *m;             /* ptr to first mbuf of pkt */
                    306: struct snpa_hdr        *shp;   /* subnetwork header */
                    307: {
                    308:        register struct clnp_fixed      *clnp;  /* ptr to fixed part of header */
                    309:        struct sockaddr_iso                     source; /* source address of pkt */
                    310:        struct sockaddr_iso                     target; /* destination address of pkt */
                    311: #define src    source.siso_addr
                    312: #define dst    target.siso_addr
                    313:        caddr_t                                         hoff;   /* current offset in packet */
                    314:        caddr_t                                         hend;   /* address of end of header info */
                    315:        struct clnp_segment                     seg_part; /* segment part of hdr */
                    316:        int                                                     seg_off=0; /* offset of segment part of hdr */
                    317:        int                                                     seg_len;/* length of packet data&hdr in bytes */
                    318:        struct clnp_optidx                      oidx, *oidxp = NULL;    /* option index */
                    319:        extern int                                      iso_systype;    /* used by ESIS config resp */
                    320:        extern struct sockaddr_iso      blank_siso;             /* used for initializing */
                    321:        int                                                     need_afrin = 0; 
                    322:                                                                                /* true if congestion experienced */
                    323:                                                                                /* which means you need afrin nose */
                    324:                                                                                /* spray. How clever! */
                    325: 
                    326:        IFDEBUG(D_INPUT)
                    327:                printf(
                    328:                   "clnp_input: proccessing dg; First mbuf m_len %d, m_type x%x, %s\n", 
                    329:                        m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
                    330:        ENDDEBUG
                    331:        need_afrin = 0;
                    332: 
                    333:        /*
                    334:         *      If no iso addresses have been set, there is nothing
                    335:         *      to do with the packet.
                    336:         */
                    337:        if (iso_ifaddr == NULL) {
                    338:                clnp_discard(m, ADDR_DESTUNREACH);
                    339:                return;
                    340:        }
                    341:        
                    342:        INCSTAT(cns_total);
                    343:        clnp = mtod(m, struct clnp_fixed *);
                    344: 
                    345:        IFDEBUG(D_DUMPIN)
                    346:                struct mbuf *mhead;
                    347:                int                     total_len = 0;
                    348:                printf("clnp_input: clnp header:\n");
                    349:                dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);
                    350:                printf("clnp_input: mbuf chain:\n");
                    351:                for (mhead = m; mhead != NULL; mhead=mhead->m_next) {
                    352:                        printf("m x%x, len %d\n", mhead, mhead->m_len);
                    353:                        total_len += mhead->m_len;
                    354:                }
                    355:                printf("clnp_input: total length of mbuf chain %d:\n", total_len);
                    356:        ENDDEBUG
                    357: 
                    358:        /*
                    359:         *      Compute checksum (if necessary) and drop packet if
                    360:         *      checksum does not match
                    361:         */
                    362:        if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, (int)clnp->cnf_hdr_len)) {
                    363:                INCSTAT(cns_badcsum);
                    364:                clnp_discard(m, GEN_BADCSUM);
                    365:                return;
                    366:        }
                    367: 
                    368:        if (clnp->cnf_vers != ISO8473_V1) {
                    369:                INCSTAT(cns_badvers);
                    370:                clnp_discard(m, DISC_UNSUPPVERS);
                    371:                return;
                    372:        }
                    373: 
                    374: 
                    375:        /* check mbuf data length: clnp_data_ck will free mbuf upon error */
                    376:        CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
                    377:        if ((m = clnp_data_ck(m, seg_len)) == 0)
                    378:                return;
                    379:        
                    380:        clnp = mtod(m, struct clnp_fixed *);
                    381:        hend = (caddr_t)clnp + clnp->cnf_hdr_len;
                    382: 
                    383:        /* 
                    384:         *      extract the source and destination address
                    385:         *      drop packet on failure
                    386:         */
                    387:        source = target = blank_siso;
                    388: 
                    389:        hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
                    390:        CLNP_EXTRACT_ADDR(dst, hoff, hend);
                    391:        if (hoff == (caddr_t)0) {
                    392:                INCSTAT(cns_badaddr);
                    393:                clnp_discard(m, GEN_INCOMPLETE);
                    394:                return;
                    395:        }
                    396:        CLNP_EXTRACT_ADDR(src, hoff, hend);
                    397:        if (hoff == (caddr_t)0) {
                    398:                INCSTAT(cns_badaddr);
                    399:                clnp_discard(m, GEN_INCOMPLETE);
                    400:                return;
                    401:        }
                    402: 
                    403:        IFDEBUG(D_INPUT)
                    404:                printf("clnp_input: from %s", clnp_iso_addrp(&src));
                    405:                printf(" to %s\n", clnp_iso_addrp(&dst));
                    406:        ENDDEBUG
                    407: 
                    408:        /*
                    409:         *      extract the segmentation information, if it is present.
                    410:         *      drop packet on failure
                    411:         */
                    412:        if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
                    413:                (clnp->cnf_type & CNF_SEG_OK)) {
                    414:                if (hoff + sizeof(struct clnp_segment) > hend) {
                    415:                        INCSTAT(cns_noseg);
                    416:                        clnp_discard(m, GEN_INCOMPLETE);
                    417:                        return;
                    418:                } else {
                    419:                        (void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment));
                    420:                        /* make sure segmentation fields are in host order */
                    421:                        seg_part.cng_id = ntohs(seg_part.cng_id);
                    422:                        seg_part.cng_off = ntohs(seg_part.cng_off);
                    423:                        seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
                    424:                        seg_off = hoff - (caddr_t)clnp;
                    425:                        hoff += sizeof(struct clnp_segment);
                    426:                }
                    427:        }
                    428: 
                    429:        /*
                    430:         *      process options if present. If clnp_opt_sanity returns
                    431:         *      false (indicating an error was found in the options) or
                    432:         *      an unsupported option was found
                    433:         *      then drop packet and emit an ER.
                    434:         */
                    435:        if (hoff < hend) {
                    436:                int             errcode;
                    437: 
                    438:                oidxp = &oidx;
                    439:                errcode = clnp_opt_sanity(m, hoff, hend-hoff, oidxp);
                    440: 
                    441:                /* we do not support security */
                    442:                if ((errcode == 0) && (oidxp->cni_securep))
                    443:                        errcode = DISC_UNSUPPSECURE;
                    444: 
                    445:                /* the er option is valid with ER pdus only */
                    446:                if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) && 
                    447:                        ((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
                    448:                        errcode = DISC_UNSUPPOPT;
                    449: 
                    450: #ifdef DECBIT
                    451:                /* check if the congestion experienced bit is set */
                    452:                if (oidxp->cni_qos_formatp) {
                    453:                        caddr_t qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
                    454:                        u_char  qos = *qosp;
                    455: 
                    456:                        need_afrin = ((qos & (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)) ==
                    457:                                (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED));
                    458:                        if (need_afrin)
                    459:                                INCSTAT(cns_congest_rcvd);
                    460:                }
                    461: #endif /* DECBIT */
                    462: 
                    463:                if (errcode != 0) {
                    464:                        clnp_discard(m, (char)errcode);
                    465:                        IFDEBUG(D_INPUT)
                    466:                                printf("clnp_input: dropped (err x%x) due to bad options\n",
                    467:                                        errcode);
                    468:                        ENDDEBUG
                    469:                        return;
                    470:                }
                    471:        }
                    472:        
                    473:        /*
                    474:         *      check if this packet is for us. if not, then forward
                    475:         */
                    476:        if (clnp_ours(&dst) == 0) {
                    477:                IFDEBUG(D_INPUT)
                    478:                        printf("clnp_input: forwarding packet not for us\n");
                    479:                ENDDEBUG
                    480:                clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
                    481:                return;
                    482:        }
                    483: 
                    484:        /*
                    485:         *      ESIS Configuration Response Function
                    486:         *
                    487:         *      If the packet received was sent to the multicast address
                    488:         *      all end systems, then send an esh to the source
                    489:         */
                    490:        if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
                    491:                extern short esis_holding_time;
                    492: 
                    493:                esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
                    494:                        shp->snh_shost, 6, &dst);
                    495:        }
                    496: 
                    497:        /*
                    498:         *      If this is a fragment, then try to reassemble it. If clnp_reass
                    499:         *      returns non NULL, the packet has been reassembled, and should
                    500:         *      be give to TP. Otherwise the fragment has been delt with
                    501:         *      by the reassembly code (either stored or deleted). In either case
                    502:         *      we should have nothing more to do with it.
                    503:         */
                    504:        if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
                    505:                (clnp->cnf_type & CNF_SEG_OK) &&
                    506:                (seg_len != seg_part.cng_tot_len)) {
                    507:                struct mbuf     *m0;
                    508: 
                    509:                if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
                    510:                        m = m0;
                    511:                        clnp = mtod(m, struct clnp_fixed *);
                    512:                        INCSTAT(cns_reassembled);
                    513:                } else {
                    514:                        return;
                    515:                }
                    516:        }
                    517:        
                    518:        /*
                    519:         *      give the packet to the higher layer
                    520:         *
                    521:         *      Note: the total length of packet
                    522:         *      is the total length field of the segmentation part,
                    523:         *      or, if absent, the segment length field of the
                    524:         *      header.
                    525:         */
                    526:        INCSTAT(cns_delivered);
                    527:        switch (clnp->cnf_type & CNF_TYPE) {
                    528:        case CLNP_ER:
                    529:                /*
                    530:                 *      This ER must have the er option.
                    531:                 *      If the option is not present, discard datagram.
                    532:                 */
                    533:                if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
                    534:                        clnp_discard(m, GEN_HDRSYNTAX);
                    535:                } else {
                    536:                        clnp_er_input(m, &src, oidxp->cni_er_reason);
                    537:                }
                    538:                break;
                    539: 
                    540:        case CLNP_DT:
                    541:                (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
                    542:                        clnp->cnf_hdr_len, need_afrin);
                    543:                break;
                    544: 
                    545:        case CLNP_RAW:
                    546:        case CLNP_ECR:
                    547:                IFDEBUG(D_INPUT)
                    548:                        printf("clnp_input: raw input of %d bytes\n",
                    549:                                clnp->cnf_type & CNF_SEG_OK ? seg_part.cng_tot_len : seg_len);
                    550:                ENDDEBUG
                    551:                (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source, &target,
                    552:                                        clnp->cnf_hdr_len);
                    553:                break;
                    554: 
                    555:        case CLNP_EC:
                    556:                IFDEBUG(D_INPUT)
                    557:                        printf("clnp_input: echoing packet\n");
                    558:                ENDDEBUG
                    559:                (void)clnp_echoreply(m,
                    560:                        (clnp->cnf_type & CNF_SEG_OK ? (int)seg_part.cng_tot_len : seg_len),
                    561:                        &source, &target, oidxp);
                    562:                break;
                    563: 
                    564:        default:
                    565:                printf("clnp_input: unknown clnp pkt type %d\n",
                    566:                        clnp->cnf_type & CNF_TYPE);
                    567:                clnp_stat.cns_delivered--;
                    568:                clnp_stat.cns_noproto++;
                    569:                clnp_discard(m, GEN_HDRSYNTAX);
                    570:                break;
                    571:        }
                    572: }
                    573: #endif /* ISO */

unix.superglobalmegacorp.com

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