136370Ssklower /*********************************************************** 236370Ssklower Copyright IBM Corporation 1987 336370Ssklower 436370Ssklower All Rights Reserved 536370Ssklower 636370Ssklower Permission to use, copy, modify, and distribute this software and its 736370Ssklower documentation for any purpose and without fee is hereby granted, 836370Ssklower provided that the above copyright notice appear in all copies and that 936370Ssklower both that copyright notice and this permission notice appear in 1036370Ssklower supporting documentation, and that the name of IBM not be 1136370Ssklower used in advertising or publicity pertaining to distribution of the 1236370Ssklower software without specific, written prior permission. 1336370Ssklower 1436370Ssklower IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1536370Ssklower ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 1636370Ssklower IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1736370Ssklower ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 1836370Ssklower WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 1936370Ssklower ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 2036370Ssklower SOFTWARE. 2136370Ssklower 2236370Ssklower ******************************************************************/ 2336370Ssklower 2436370Ssklower /* 2536370Ssklower * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison 2636370Ssklower */ 27*36766Ssklower /* $Header: /var/src/sys/netiso/RCS/clnp_input.c,v 5.1 89/02/09 16:20:32 hagens Exp $ */ 28*36766Ssklower /* $Source: /var/src/sys/netiso/RCS/clnp_input.c,v $ */ 29*36766Ssklower /* @(#)clnp_input.c 7.3 (Berkeley) 02/14/89 */ 3036370Ssklower 3136370Ssklower #ifndef lint 32*36766Ssklower static char *rcsid = "$Header: /var/src/sys/netiso/RCS/clnp_input.c,v 5.1 89/02/09 16:20:32 hagens Exp $"; 3336370Ssklower #endif lint 3436370Ssklower 3536370Ssklower #include "../h/types.h" 3636370Ssklower #include "../h/param.h" 3736370Ssklower #include "../h/mbuf.h" 3836370Ssklower #include "../h/domain.h" 3936370Ssklower #include "../h/protosw.h" 4036370Ssklower #include "../h/socket.h" 4136370Ssklower #include "../h/socketvar.h" 4236370Ssklower #include "../h/errno.h" 4336370Ssklower #include "../h/time.h" 4436370Ssklower 4536370Ssklower #include "../net/if.h" 4636370Ssklower #include "../net/route.h" 4736370Ssklower 4836370Ssklower #include "../netiso/iso.h" 4936370Ssklower #include "../netiso/iso_var.h" 5036370Ssklower #include "../netiso/iso_snpac.h" 5136370Ssklower #include "../netiso/clnp.h" 5236370Ssklower #include "../netiso/clnl.h" 5336370Ssklower #include "../netiso/esis.h" 5436370Ssklower #include "../netiso/clnp_stat.h" 5536370Ssklower #include "../netiso/argo_debug.h" 5636370Ssklower 5736370Ssklower #ifdef ISO 5836370Ssklower u_char clnp_protox[ISOPROTO_MAX]; 5936370Ssklower struct clnl_protosw clnl_protox[256]; 6036370Ssklower int clnpqmaxlen = IFQ_MAXLEN; /* RAH? why is this a variable */ 6136370Ssklower struct mbuf *clnp_data_ck(); 6236370Ssklower 6336370Ssklower int clnp_input(); 6436370Ssklower 6536370Ssklower int esis_input(); 6636370Ssklower 6736370Ssklower #ifdef ISO_X25ESIS 6836370Ssklower int x25esis_input(); 6936370Ssklower #endif ISO_X25ESIS 7036370Ssklower 7136370Ssklower /* 7236370Ssklower * FUNCTION: clnp_init 7336370Ssklower * 7436370Ssklower * PURPOSE: clnp initialization. Fill in clnp switch tables. 7536370Ssklower * 7636370Ssklower * RETURNS: none 7736370Ssklower * 7836370Ssklower * SIDE EFFECTS: fills in clnp_protox table with correct offsets into 7936370Ssklower * the isosw table. 8036370Ssklower * 8136370Ssklower * NOTES: 8236370Ssklower */ 8336370Ssklower clnp_init() 8436370Ssklower { 8536370Ssklower register struct protosw *pr; 8636370Ssklower 8736370Ssklower /* 8836370Ssklower * CLNP protox initialization 8936370Ssklower */ 9036370Ssklower if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0) 9136370Ssklower printf("clnl_init: no raw CLNP\n"); 9236370Ssklower else 9336370Ssklower clnp_protox[ISOPROTO_RAW] = pr - isosw; 9436370Ssklower 9536370Ssklower if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0) 9636370Ssklower printf("clnl_init: no tp/clnp\n"); 9736370Ssklower else 9836370Ssklower clnp_protox[ISOPROTO_TP] = pr - isosw; 9936370Ssklower 10036370Ssklower /* 10136370Ssklower * CLNL protox initialization 10236370Ssklower */ 10336370Ssklower clnl_protox[ISO8473_CLNP].clnl_input = clnp_input; 10436370Ssklower 10536370Ssklower clnlintrq.ifq_maxlen = clnpqmaxlen; 10636370Ssklower } 10736370Ssklower 10836370Ssklower /* 10936370Ssklower * FUNCTION: clnlintr 11036370Ssklower * 11136370Ssklower * PURPOSE: Process a packet on the clnl input queue 11236370Ssklower * 11336370Ssklower * RETURNS: nothing. 11436370Ssklower * 11536370Ssklower * SIDE EFFECTS: 11636370Ssklower * 11736370Ssklower * NOTES: 11836370Ssklower */ 11936370Ssklower clnlintr() 12036370Ssklower { 12136370Ssklower register struct mbuf *m; /* ptr to first mbuf of pkt */ 12236370Ssklower register struct clnl_fixed *clnl; /* ptr to fixed part of clnl hdr */ 12336370Ssklower struct ifnet *ifp; /* ptr to interface pkt arrived on */ 12436370Ssklower int s; /* save and restore priority */ 12536370Ssklower struct clnl_protosw *clnlsw;/* ptr to protocol switch */ 12636370Ssklower struct snpa_hdr sh; /* subnetwork hdr */ 12736370Ssklower 12836370Ssklower /* 12936370Ssklower * Get next datagram off clnl input queue 13036370Ssklower */ 13136370Ssklower next: 13236370Ssklower s = splimp(); 13336370Ssklower 13436765Ssklower /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh);*/ 13536765Ssklower IF_DEQUEUE(&clnlintrq, m); 13636370Ssklower 13736765Ssklower 13836765Ssklower splx(s); 13936765Ssklower if (m == 0) /* nothing to do */ 14036765Ssklower return; 14136765Ssklower if (m->m_flags & M_PKTHDR == 0) { 14236765Ssklower m_freem(m); 14336765Ssklower goto next; 14436765Ssklower } 14536765Ssklower bcopy((caddr_t)(mtod(m, struct llc_etherhdr *)->dst), 14636765Ssklower (caddr_t)sh.snh_dhost, 2*sizeof(sh.snh_dhost)); 14736765Ssklower m->m_data += sizeof (struct llc_etherhdr); 14836765Ssklower m->m_len -= sizeof (struct llc_etherhdr); 14936765Ssklower m->m_pkthdr.len -= sizeof (struct llc_etherhdr); 15036765Ssklower sh.snh_ifp = m->m_pkthdr.rcvif; 15136370Ssklower IFDEBUG(D_INPUT) 15236370Ssklower int i; 15336370Ssklower printf("clnlintr: src:"); 15436370Ssklower for (i=0; i<6; i++) 15536370Ssklower printf("%x%c", sh.snh_shost[i] & 0xff, (i<5) ? ':' : ' '); 15636370Ssklower printf(" dst:"); 15736370Ssklower for (i=0; i<6; i++) 15836370Ssklower printf("%x%c", sh.snh_dhost[i] & 0xff, (i<5) ? ':' : ' '); 15936370Ssklower printf("\n"); 16036370Ssklower ENDDEBUG 16136370Ssklower 16236370Ssklower /* 16336370Ssklower * Get the fixed part of the clnl header into the first mbuf. 16436370Ssklower * Drop the packet if this fails. 16536370Ssklower * Do not call m_pullup if we have a cluster mbuf or the 16636370Ssklower * data is not there. 16736370Ssklower */ 16836370Ssklower if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) && 16936370Ssklower ((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) { 17036370Ssklower INCSTAT(cns_toosmall); /* TODO: use clnl stats */ 17136370Ssklower goto next; /* m_pullup discards mbuf */ 17236370Ssklower } 17336370Ssklower 17436370Ssklower clnl = mtod(m, struct clnl_fixed *); 17536370Ssklower 17636370Ssklower /* 17736370Ssklower * Drop packet if the length of the header is not reasonable. 17836370Ssklower */ 17936370Ssklower if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) || 18036370Ssklower (clnl->cnf_hdr_len > CLNP_HDR_MAX)) { 18136370Ssklower INCSTAT(cns_badhlen); /* TODO: use clnl stats */ 18236370Ssklower m_freem(m); 18336370Ssklower goto next; 18436370Ssklower } 18536370Ssklower 18636370Ssklower /* 18736370Ssklower * If the header is not contained in this mbuf, make it so. 18836370Ssklower * Drop packet if this fails. 18936370Ssklower * Note: m_pullup will allocate a cluster mbuf if necessary 19036370Ssklower */ 19136370Ssklower if (clnl->cnf_hdr_len > m->m_len) { 19236370Ssklower if ((m = m_pullup(m, clnl->cnf_hdr_len)) == 0) { 19336370Ssklower INCSTAT(cns_badhlen); /* TODO: use clnl stats */ 19436370Ssklower goto next; /* m_pullup discards mbuf */ 19536370Ssklower } 19636370Ssklower clnl = mtod(m, struct clnl_fixed *); 19736370Ssklower } 19836370Ssklower 19936370Ssklower clnlsw = &clnl_protox[clnl->cnf_proto_id]; 20036370Ssklower 20136370Ssklower 20236370Ssklower if (clnlsw->clnl_input) 20336370Ssklower (*clnlsw->clnl_input) (m, &sh); 20436370Ssklower else 20536370Ssklower m_freem(m); 20636370Ssklower 20736370Ssklower goto next; 20836370Ssklower } 20936370Ssklower 21036370Ssklower /* 21136370Ssklower * FUNCTION: clnp_input 21236370Ssklower * 21336370Ssklower * PURPOSE: process an incoming clnp packet 21436370Ssklower * 21536370Ssklower * RETURNS: nothing 21636370Ssklower * 21736370Ssklower * SIDE EFFECTS: increments fields of clnp_stat structure. 21836370Ssklower * 21936370Ssklower * NOTES: 22036370Ssklower * TODO: I would like to make seg_part a pointer into the mbuf, but 22136370Ssklower * will it be correctly aligned? 22236370Ssklower */ 22336370Ssklower int clnp_input(m, shp) 22436370Ssklower struct mbuf *m; /* ptr to first mbuf of pkt */ 22536370Ssklower struct snpa_hdr *shp; /* subnetwork header */ 22636370Ssklower { 22736370Ssklower register struct clnp_fixed *clnp; /* ptr to fixed part of header */ 22836370Ssklower struct iso_addr src; /* source address of pkt */ 22936370Ssklower struct iso_addr dst; /* destination address of pkt */ 23036370Ssklower caddr_t hoff; /* current offset in packet */ 23136370Ssklower caddr_t hend; /* address of end of header info */ 23236370Ssklower struct clnp_segment seg_part; /* segment part of hdr */ 23336370Ssklower int seg_off=0; /* offset of segment part of hdr */ 23436370Ssklower int seg_len;/* length of packet data&hdr in bytes */ 23536370Ssklower struct clnp_optidx oidx, *oidxp = NULL; /* option index */ 23636370Ssklower extern int iso_systype; /* used by ESIS config resp */ 237*36766Ssklower int need_afrin = 0; 238*36766Ssklower /* true if congestion experienced */ 239*36766Ssklower /* which means you need afrin nose */ 240*36766Ssklower /* spray. How clever! */ 24136370Ssklower 24236370Ssklower IFDEBUG(D_INPUT) 24336370Ssklower printf( 244*36766Ssklower "clnp_input: proccessing dg; First mbuf m_len %d, m_type x%x, %s\n", 245*36766Ssklower m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal"); 24636370Ssklower ENDDEBUG 247*36766Ssklower need_afrin = 0; 24836370Ssklower 24936370Ssklower /* 25036370Ssklower * If no iso addresses have been set, there is nothing 25136370Ssklower * to do with the packet. 25236370Ssklower */ 25336370Ssklower if (iso_ifaddr == NULL) { 25436370Ssklower clnp_discard(m, ADDR_DESTUNREACH); 25536370Ssklower return; 25636370Ssklower } 25736370Ssklower 25836370Ssklower INCSTAT(cns_total); 25936370Ssklower clnp = mtod(m, struct clnp_fixed *); 26036370Ssklower 261*36766Ssklower IFDEBUG(D_DUMPIN) 262*36766Ssklower struct mbuf *mhead; 263*36766Ssklower int total_len = 0; 264*36766Ssklower printf("clnp_input: clnp header:\n"); 265*36766Ssklower dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len); 266*36766Ssklower printf("clnp_input: mbuf chain:\n"); 267*36766Ssklower for (mhead = m; mhead != NULL; mhead=mhead->m_next) { 268*36766Ssklower printf("m x%x, len %d\n", mhead, mhead->m_len); 269*36766Ssklower total_len += mhead->m_len; 270*36766Ssklower } 271*36766Ssklower printf("clnp_input: total length of mbuf chain %d:\n", total_len); 272*36766Ssklower ENDDEBUG 273*36766Ssklower 27436370Ssklower /* 27536370Ssklower * Compute checksum (if necessary) and drop packet if 27636370Ssklower * checksum does not match 27736370Ssklower */ 27836370Ssklower if (CKSUM_REQUIRED(clnp) && iso_check_csum(m, clnp->cnf_hdr_len)) { 27936370Ssklower INCSTAT(cns_badcsum); 28036370Ssklower clnp_discard(m, GEN_BADCSUM); 281*36766Ssklower return 0; 28236370Ssklower } 28336370Ssklower 28436370Ssklower if (clnp->cnf_vers != ISO8473_V1) { 28536370Ssklower INCSTAT(cns_badvers); 28636370Ssklower clnp_discard(m, DISC_UNSUPPVERS); 287*36766Ssklower return 0; 28836370Ssklower } 28936370Ssklower 29036370Ssklower 29136370Ssklower /* check mbuf data length: clnp_data_ck will free mbuf upon error */ 29236370Ssklower CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len); 29336370Ssklower if ((m = clnp_data_ck(m, seg_len)) == 0) 294*36766Ssklower return 0; 29536370Ssklower 29636370Ssklower clnp = mtod(m, struct clnp_fixed *); 29736370Ssklower hend = (caddr_t)clnp + clnp->cnf_hdr_len; 29836370Ssklower 29936370Ssklower /* 30036370Ssklower * extract the source and destination address 30136370Ssklower * drop packet on failure 30236370Ssklower */ 30336370Ssklower bzero((caddr_t)&src, sizeof(src)); 30436370Ssklower bzero((caddr_t)&dst, sizeof(dst)); 30536370Ssklower 30636370Ssklower hoff = (caddr_t)clnp + sizeof(struct clnp_fixed); 30736370Ssklower CLNP_EXTRACT_ADDR(dst, hoff, hend); 30836370Ssklower if (hoff == (caddr_t)0) { 30936370Ssklower INCSTAT(cns_badaddr); 31036370Ssklower clnp_discard(m, GEN_INCOMPLETE); 311*36766Ssklower return 0; 31236370Ssklower } 31336370Ssklower CLNP_EXTRACT_ADDR(src, hoff, hend); 31436370Ssklower if (hoff == (caddr_t)0) { 31536370Ssklower INCSTAT(cns_badaddr); 31636370Ssklower clnp_discard(m, GEN_INCOMPLETE); 317*36766Ssklower return 0; 31836370Ssklower } 31936370Ssklower 32036370Ssklower IFDEBUG(D_INPUT) 32136370Ssklower printf("clnp_input: from %s", clnp_iso_addrp(&src)); 32236370Ssklower printf(" to %s\n", clnp_iso_addrp(&dst)); 32336370Ssklower ENDDEBUG 32436370Ssklower 32536370Ssklower /* 32636370Ssklower * extract the segmentation information, if it is present. 32736370Ssklower * drop packet on failure 32836370Ssklower */ 32936370Ssklower if ((clnp->cnf_type != CLNP_ER) && (clnp->cnf_seg_ok)) { 33036370Ssklower if (hoff + sizeof(struct clnp_segment) > hend) { 33136370Ssklower INCSTAT(cns_noseg); 33236370Ssklower clnp_discard(m, GEN_INCOMPLETE); 333*36766Ssklower return 0; 33436370Ssklower } else { 33536370Ssklower (void) bcopy(hoff, (caddr_t)&seg_part, sizeof(struct clnp_segment)); 33636370Ssklower /* make sure segmentation fields are in host order */ 33736370Ssklower seg_part.cng_id = ntohs(seg_part.cng_id); 33836370Ssklower seg_part.cng_off = ntohs(seg_part.cng_off); 33936370Ssklower seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len); 34036370Ssklower seg_off = hoff - (caddr_t)clnp; 34136370Ssklower hoff += sizeof(struct clnp_segment); 34236370Ssklower } 34336370Ssklower } 34436370Ssklower 34536370Ssklower /* 34636370Ssklower * process options if present. If clnp_opt_sanity returns 34736370Ssklower * false (indicating an error was found in the options) or 34836370Ssklower * an unsupported option was found 34936370Ssklower * then drop packet and emit an ER. 35036370Ssklower */ 35136370Ssklower if (hoff < hend) { 35236370Ssklower int errcode; 35336370Ssklower 35436370Ssklower oidxp = &oidx; 35536370Ssklower errcode = clnp_opt_sanity(m, hoff, hend-hoff, oidxp); 35636370Ssklower 35736370Ssklower /* we do not support security */ 35836370Ssklower if ((errcode == 0) && (oidxp->cni_securep)) 35936370Ssklower errcode = DISC_UNSUPPSECURE; 36036370Ssklower 36136370Ssklower /* the er option is valid with ER pdus only */ 36236370Ssklower if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) && 36336370Ssklower (clnp->cnf_type != CLNP_ER)) 36436370Ssklower errcode = DISC_UNSUPPOPT; 36536370Ssklower 366*36766Ssklower #ifdef DECBIT 367*36766Ssklower /* check if the congestion experienced bit is set */ 368*36766Ssklower if (oidxp->cni_qos_formatp) { 369*36766Ssklower caddr_t qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp); 370*36766Ssklower u_char qos = *qosp; 371*36766Ssklower 372*36766Ssklower need_afrin = ((qos & (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)) == 373*36766Ssklower (CLNPOVAL_GLOBAL|CLNPOVAL_CONGESTED)); 374*36766Ssklower if (need_afrin) 375*36766Ssklower INCSTAT(cns_congest_rcvd); 376*36766Ssklower } 377*36766Ssklower #endif DECBIT 378*36766Ssklower 37936370Ssklower if (errcode != 0) { 38036370Ssklower clnp_discard(m, (char)errcode); 38136370Ssklower IFDEBUG(D_INPUT) 38236370Ssklower printf("clnp_input: dropped (err x%x) due to bad options\n", 38336370Ssklower errcode); 38436370Ssklower ENDDEBUG 385*36766Ssklower return 0; 38636370Ssklower } 38736370Ssklower } 38836370Ssklower 38936370Ssklower /* 39036370Ssklower * check if this packet is for us. if not, then forward 39136370Ssklower */ 39236370Ssklower if (clnp_ours(&dst) == 0) { 39336370Ssklower IFDEBUG(D_INPUT) 39436370Ssklower printf("clnp_input: forwarding packet not for us\n"); 39536370Ssklower ENDDEBUG 39636370Ssklower clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp); 397*36766Ssklower return 0; 39836370Ssklower } 39936370Ssklower 40036370Ssklower /* 40136370Ssklower * ESIS Configuration Response Function 40236370Ssklower * 40336370Ssklower * If the packet received was sent to the multicast address 40436370Ssklower * all end systems, then send an esh to the source 40536370Ssklower */ 40636370Ssklower if ((IS_MULTICAST(shp->snh_dhost)) && (iso_systype == SNPA_ES)) { 40736370Ssklower extern short esis_holding_time; 40836370Ssklower 40936370Ssklower esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time, 41036370Ssklower shp->snh_shost, 6); 41136370Ssklower } 41236370Ssklower 41336370Ssklower /* 41436370Ssklower * If this is a fragment, then try to reassemble it. If clnp_reass 41536370Ssklower * returns non NULL, the packet has been reassembled, and should 41636370Ssklower * be give to TP. Otherwise the fragment has been delt with 41736370Ssklower * by the reassembly code (either stored or deleted). In either case 41836370Ssklower * we should have nothing more to do with it. 41936370Ssklower */ 42036370Ssklower if ((clnp->cnf_type != CLNP_ER) && (clnp->cnf_seg_ok) && 42136370Ssklower (seg_len != seg_part.cng_tot_len)) { 42236370Ssklower struct mbuf *m0; 42336370Ssklower 42436370Ssklower if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) { 42536370Ssklower m = m0; 42636370Ssklower clnp = mtod(m, struct clnp_fixed *); 42736370Ssklower } else { 428*36766Ssklower return 0; 42936370Ssklower } 43036370Ssklower } 43136370Ssklower 43236370Ssklower /* 43336370Ssklower * give the packet to the higher layer 43436370Ssklower * 43536370Ssklower * Note: the total length of packet 43636370Ssklower * is the total length field of the segmentation part, 43736370Ssklower * or, if absent, the segment length field of the 43836370Ssklower * header. 43936370Ssklower */ 44036370Ssklower switch (clnp->cnf_type) { 44136370Ssklower case CLNP_ER: 44236370Ssklower /* 44336370Ssklower * This ER must have the er option. 44436370Ssklower * If the option is not present, discard datagram. 44536370Ssklower */ 44636370Ssklower if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) { 44736370Ssklower clnp_discard(m, GEN_HDRSYNTAX); 44836370Ssklower } else { 44936370Ssklower clnp_er_input(m, &src, oidxp->cni_er_reason); 45036370Ssklower } 45136370Ssklower break; 45236370Ssklower 45336370Ssklower case CLNP_DT: 454*36766Ssklower if (need_afrin) { 455*36766Ssklower /* NOTE: do this before TP gets the packet so tp ack can use info*/ 456*36766Ssklower IFDEBUG(D_INPUT) 457*36766Ssklower printf("clnp_input: Calling tpclnp_ctlinput(%s)\n", 458*36766Ssklower clnp_iso_addrp(&src)); 459*36766Ssklower ENDDEBUG 460*36766Ssklower tpclnp_ctlinput1(PRC_QUENCH2, &src); 461*36766Ssklower } 46236370Ssklower (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &src, &dst, 46336370Ssklower clnp->cnf_hdr_len); 46436370Ssklower break; 46536370Ssklower 46636370Ssklower case CLNP_RAW: 46736370Ssklower case CLNP_ECR: 46836370Ssklower IFDEBUG(D_INPUT) 46936370Ssklower printf("clnp_input: raw input of %d bytes\n", 47036370Ssklower clnp->cnf_seg_ok ? seg_part.cng_tot_len : seg_len); 47136370Ssklower ENDDEBUG 47236370Ssklower (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &src, &dst, 47336370Ssklower clnp->cnf_hdr_len); 47436370Ssklower break; 47536370Ssklower 47636370Ssklower case CLNP_EC: 47736370Ssklower IFDEBUG(D_INPUT) 47836370Ssklower printf("clnp_input: echoing packet\n"); 47936370Ssklower ENDDEBUG 48036370Ssklower /* 48136370Ssklower * Switch the source and destination address, 48236370Ssklower */ 48336370Ssklower hoff = (caddr_t)clnp + sizeof(struct clnp_fixed); 48436370Ssklower CLNP_INSERT_ADDR(hoff, &src); 48536370Ssklower CLNP_INSERT_ADDR(hoff, &dst); 48636370Ssklower clnp->cnf_type = CLNP_ECR; 48736370Ssklower 48836370Ssklower /* 48936370Ssklower * Forward back to sender 49036370Ssklower */ 49136370Ssklower clnp_forward(m, clnp->cnf_seg_ok ? seg_part.cng_tot_len : seg_len, 49236370Ssklower &src, oidxp, seg_off, shp); 49336370Ssklower break; 49436370Ssklower 49536370Ssklower default: 49636370Ssklower printf("clnp_input: unknown clnp pkt type %d\n", clnp->cnf_type); 49736370Ssklower clnp_discard(m, GEN_HDRSYNTAX); 49836370Ssklower break; 49936370Ssklower } 50036370Ssklower } 50136370Ssklower #endif ISO 502