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