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

unix.superglobalmegacorp.com

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