summaryrefslogtreecommitdiffstats
path: root/sys/netiso/tp_iso.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netiso/tp_iso.c')
-rw-r--r--sys/netiso/tp_iso.c693
1 files changed, 693 insertions, 0 deletions
diff --git a/sys/netiso/tp_iso.c b/sys/netiso/tp_iso.c
new file mode 100644
index 0000000..1cf67f8
--- /dev/null
+++ b/sys/netiso/tp_iso.c
@@ -0,0 +1,693 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tp_iso.c 8.1 (Berkeley) 6/10/93
+ */
+
+/***********************************************************
+ Copyright IBM Corporation 1987
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+ * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
+ */
+/*
+ * ARGO TP
+ * $Header: /var/src/sys/netiso/RCS/tp_iso.c,v 5.1 89/02/09 16:20:51 hagens Exp $
+ * $Source: /var/src/sys/netiso/RCS/tp_iso.c,v $
+ *
+ * Here is where you find the iso-dependent code. We've tried
+ * keep all net-level and (primarily) address-family-dependent stuff
+ * out of the tp source, and everthing here is reached indirectly
+ * through a switch table (struct nl_protosw *) tpcb->tp_nlproto
+ * (see tp_pcb.c).
+ * The routines here are:
+ * iso_getsufx: gets transport suffix out of an isopcb structure.
+ * iso_putsufx: put transport suffix into an isopcb structure.
+ * iso_putnetaddr: put a whole net addr into an isopcb.
+ * iso_getnetaddr: get a whole net addr from an isopcb.
+ * iso_cmpnetaddr: compare a whole net addr from an isopcb.
+ * iso_recycle_suffix: clear suffix for reuse in isopcb
+ * tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff
+ * tpclnp_mtu: figure out what size tpdu to use
+ * tpclnp_input: take a pkt from clnp, strip off its clnp header,
+ * give to tp
+ * tpclnp_output_dg: package a pkt for clnp given 2 addresses & some data
+ * tpclnp_output: package a pkt for clnp given an isopcb & some data
+ */
+
+#ifdef ISO
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/protosw.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netiso/argo_debug.h>
+#include <netiso/tp_param.h>
+#include <netiso/tp_stat.h>
+#include <netiso/tp_pcb.h>
+#include <netiso/tp_trace.h>
+#include <netiso/tp_stat.h>
+#include <netiso/tp_tpdu.h>
+#include <netiso/tp_clnp.h>
+#include <netiso/cltp_var.h>
+
+/*
+ * CALLED FROM:
+ * pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
+ * FUNCTION, ARGUMENTS:
+ * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
+ */
+
+iso_getsufx(isop, lenp, data_out, which)
+ struct isopcb *isop;
+ u_short *lenp;
+ caddr_t data_out;
+ int which;
+{
+ register struct sockaddr_iso *addr = 0;
+
+ switch (which) {
+ case TP_LOCAL:
+ addr = isop->isop_laddr;
+ break;
+
+ case TP_FOREIGN:
+ addr = isop->isop_faddr;
+ }
+ if (addr)
+ bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
+}
+
+/* CALLED FROM:
+ * tp_newsocket(); i.e., when a connection is being established by an
+ * incoming CR_TPDU.
+ *
+ * FUNCTION, ARGUMENTS:
+ * Put a transport suffix (found in name) into an isopcb structure (isop).
+ * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
+ */
+void
+iso_putsufx(isop, sufxloc, sufxlen, which)
+ struct isopcb *isop;
+ caddr_t sufxloc;
+ int sufxlen, which;
+{
+ struct sockaddr_iso **dst, *backup;
+ register struct sockaddr_iso *addr;
+ struct mbuf *m;
+ int len;
+
+ switch (which) {
+ default:
+ return;
+
+ case TP_LOCAL:
+ dst = &isop->isop_laddr;
+ backup = &isop->isop_sladdr;
+ break;
+
+ case TP_FOREIGN:
+ dst = &isop->isop_faddr;
+ backup = &isop->isop_sfaddr;
+ }
+ if ((addr = *dst) == 0) {
+ addr = *dst = backup;
+ addr->siso_nlen = 0;
+ addr->siso_slen = 0;
+ addr->siso_plen = 0;
+ printf("iso_putsufx on un-initialized isopcb\n");
+ }
+ len = sufxlen + addr->siso_nlen +
+ (sizeof(*addr) - sizeof(addr->siso_data));
+ if (addr == backup) {
+ if (len > sizeof(*addr)) {
+ m = m_getclr(M_DONTWAIT, MT_SONAME);
+ if (m == 0)
+ return;
+ addr = *dst = mtod(m, struct sockaddr_iso *);
+ *addr = *backup;
+ m->m_len = len;
+ }
+ }
+ bcopy(sufxloc, TSEL(addr), sufxlen);
+ addr->siso_tlen = sufxlen;
+ addr->siso_len = len;
+}
+
+/*
+ * CALLED FROM:
+ * tp.trans whenever we go into REFWAIT state.
+ * FUNCTION and ARGUMENT:
+ * Called when a ref is frozen, to allow the suffix to be reused.
+ * (isop) is the net level pcb. This really shouldn't have to be
+ * done in a NET level pcb but... for the internet world that just
+ * the way it is done in BSD...
+ * The alternative is to have the port unusable until the reference
+ * timer goes off.
+ */
+void
+iso_recycle_tsuffix(isop)
+ struct isopcb *isop;
+{
+ isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
+}
+
+/*
+ * CALLED FROM:
+ * tp_newsocket(); i.e., when a connection is being established by an
+ * incoming CR_TPDU.
+ *
+ * FUNCTION and ARGUMENTS:
+ * Copy a whole net addr from a struct sockaddr (name).
+ * into an isopcb (isop).
+ * The argument (which) takes values TP_LOCAL or TP_FOREIGN
+ */
+void
+iso_putnetaddr(isop, name, which)
+ register struct isopcb *isop;
+ struct sockaddr_iso *name;
+ int which;
+{
+ struct sockaddr_iso **sisop, *backup;
+ register struct sockaddr_iso *siso;
+
+ switch (which) {
+ default:
+ printf("iso_putnetaddr: should panic\n");
+ return;
+ case TP_LOCAL:
+ sisop = &isop->isop_laddr;
+ backup = &isop->isop_sladdr;
+ break;
+ case TP_FOREIGN:
+ sisop = &isop->isop_faddr;
+ backup = &isop->isop_sfaddr;
+ }
+ siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
+ IFDEBUG(D_TPISO)
+ printf("ISO_PUTNETADDR\n");
+ dump_isoaddr(isop->isop_faddr);
+ ENDDEBUG
+ siso->siso_addr = name->siso_addr;
+}
+
+/*
+ * CALLED FROM:
+ * tp_input() when a connection is being established by an
+ * incoming CR_TPDU, and considered for interception.
+ *
+ * FUNCTION and ARGUMENTS:
+ * compare a whole net addr from a struct sockaddr (name),
+ * with that implicitly stored in an isopcb (isop).
+ * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
+ */
+iso_cmpnetaddr(isop, name, which)
+ register struct isopcb *isop;
+ register struct sockaddr_iso *name;
+ int which;
+{
+ struct sockaddr_iso **sisop, *backup;
+ register struct sockaddr_iso *siso;
+
+ switch (which) {
+ default:
+ printf("iso_cmpnetaddr: should panic\n");
+ return 0;
+ case TP_LOCAL:
+ sisop = &isop->isop_laddr;
+ backup = &isop->isop_sladdr;
+ break;
+ case TP_FOREIGN:
+ sisop = &isop->isop_faddr;
+ backup = &isop->isop_sfaddr;
+ }
+ siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
+ IFDEBUG(D_TPISO)
+ printf("ISO_CMPNETADDR\n");
+ dump_isoaddr(siso);
+ ENDDEBUG
+ if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen))
+ return (0);
+ return (bcmp((caddr_t)name->siso_data,
+ (caddr_t)siso->siso_data, name->siso_nlen) == 0);
+}
+
+/*
+ * CALLED FROM:
+ * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
+ * FUNCTION and ARGUMENTS:
+ * Copy a whole net addr from an isopcb (isop) into
+ * a struct sockaddr (name).
+ * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
+ */
+
+void
+iso_getnetaddr( isop, name, which)
+ struct isopcb *isop;
+ struct mbuf *name;
+ int which;
+{
+ struct sockaddr_iso *siso =
+ (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
+ if (siso)
+ bcopy((caddr_t)siso, mtod(name, caddr_t),
+ (unsigned)(name->m_len = siso->siso_len));
+ else
+ name->m_len = 0;
+}
+/*
+ * NAME: tpclnp_mtu()
+ *
+ * CALLED FROM:
+ * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
+ *
+ * FUNCTION, ARGUMENTS, and RETURN VALUE:
+ *
+ * Perform subnetwork dependent part of determining MTU information.
+ * It appears that setting a double pointer to the rtentry associated with
+ * the destination, and returning the header size for the network protocol
+ * suffices.
+ *
+ * SIDE EFFECTS:
+ * Sets tp_routep pointer in pcb.
+ *
+ * NOTES:
+ */
+tpclnp_mtu(tpcb)
+register struct tp_pcb *tpcb;
+{
+ struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
+
+ IFDEBUG(D_CONN)
+ printf("tpclnp_mtu(tpcb)\n", tpcb);
+ ENDDEBUG
+ tpcb->tp_routep = &(isop->isop_route.ro_rt);
+ if (tpcb->tp_netservice == ISO_CONS)
+ return 0;
+ else
+ return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
+ 2 * sizeof(struct iso_addr));
+
+}
+
+/*
+ * CALLED FROM:
+ * tp_emit()
+ * FUNCTION and ARGUMENTS:
+ * Take a packet(m0) from tp and package it so that clnp will accept it.
+ * This means prepending space for the clnp header and filling in a few
+ * of the fields.
+ * isop is the isopcb structure; datalen is the length of the data in the
+ * mbuf string m0.
+ * RETURN VALUE:
+ * whatever (E*) is returned form the net layer output routine.
+ */
+
+int
+tpclnp_output(isop, m0, datalen, nochksum)
+ struct isopcb *isop;
+ struct mbuf *m0;
+ int datalen;
+ int nochksum;
+{
+ register struct mbuf *m = m0;
+ IncStat(ts_tpdu_sent);
+
+ IFDEBUG(D_TPISO)
+ struct tpdu *hdr = mtod(m0, struct tpdu *);
+
+ printf(
+"abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
+ datalen,
+ (int)hdr->tpdu_li, (int)hdr->tpdu_type, nochksum);
+ dump_isoaddr(isop->isop_faddr);
+ printf("\nsrc addr:\n");
+ dump_isoaddr(isop->isop_laddr);
+ dump_mbuf(m0, "at tpclnp_output");
+ ENDDEBUG
+
+ return
+ clnp_output(m0, isop, datalen, /* flags */nochksum ? CLNP_NO_CKSUM : 0);
+}
+
+/*
+ * CALLED FROM:
+ * tp_error_emit()
+ * FUNCTION and ARGUMENTS:
+ * This is a copy of tpclnp_output that takes the addresses
+ * instead of a pcb. It's used by the tp_error_emit, when we
+ * don't have an iso_pcb with which to call the normal output rtn.
+ * RETURN VALUE:
+ * ENOBUFS or
+ * whatever (E*) is returned form the net layer output routine.
+ */
+
+int
+tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
+ struct iso_addr *laddr, *faddr;
+ struct mbuf *m0;
+ int datalen;
+ struct route *ro;
+ int nochksum;
+{
+ struct isopcb tmppcb;
+ int err;
+ int flags;
+ register struct mbuf *m = m0;
+
+ IFDEBUG(D_TPISO)
+ printf("tpclnp_output_dg datalen 0x%x m0 0x%x\n", datalen, m0);
+ ENDDEBUG
+
+ /*
+ * Fill in minimal portion of isopcb so that clnp can send the
+ * packet.
+ */
+ bzero((caddr_t)&tmppcb, sizeof(tmppcb));
+ tmppcb.isop_laddr = &tmppcb.isop_sladdr;
+ tmppcb.isop_laddr->siso_addr = *laddr;
+ tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
+ tmppcb.isop_faddr->siso_addr = *faddr;
+
+ IFDEBUG(D_TPISO)
+ printf("tpclnp_output_dg faddr: \n");
+ dump_isoaddr(&tmppcb.isop_sfaddr);
+ printf("\ntpclnp_output_dg laddr: \n");
+ dump_isoaddr(&tmppcb.isop_sladdr);
+ printf("\n");
+ ENDDEBUG
+
+ /*
+ * Do not use packet cache since this is a one shot error packet
+ */
+ flags = (CLNP_NOCACHE|(nochksum?CLNP_NO_CKSUM:0));
+
+ IncStat(ts_tpdu_sent);
+
+ err = clnp_output(m0, &tmppcb, datalen, flags);
+
+ /*
+ * Free route allocated by clnp (if the route was indeed allocated)
+ */
+ if (tmppcb.isop_route.ro_rt)
+ RTFREE(tmppcb.isop_route.ro_rt);
+
+ return(err);
+}
+/*
+ * CALLED FROM:
+ * clnp's input routine, indirectly through the protosw.
+ * FUNCTION and ARGUMENTS:
+ * Take a packet (m) from clnp, strip off the clnp header and give it to tp
+ * No return value.
+ */
+ProtoHook
+tpclnp_input(m, src, dst, clnp_len, ce_bit)
+ register struct mbuf *m;
+ struct sockaddr_iso *src, *dst;
+ int clnp_len, ce_bit;
+{
+ struct mbuf *tp_inputprep();
+ int tp_input(), cltp_input(), (*input)() = tp_input;
+
+ IncStat(ts_pkt_rcvd);
+
+ IFDEBUG(D_TPINPUT)
+ printf("tpclnp_input: m 0x%x clnp_len 0x%x\n", m, clnp_len);
+ dump_mbuf(m, "at tpclnp_input");
+ ENDDEBUG
+ /*
+ * CLNP gives us an mbuf chain WITH the clnp header pulled up,
+ * and the length of the clnp header.
+ * First, strip off the Clnp header. leave the mbuf there for the
+ * pullup that follows.
+ */
+ m->m_len -= clnp_len;
+ m->m_data += clnp_len;
+ m->m_pkthdr.len -= clnp_len;
+ /* XXXX: should probably be in clnp_input */
+ switch (dst->siso_data[dst->siso_nlen - 1]) {
+#ifdef TUBA
+ case ISOPROTO_TCP:
+ return (tuba_tcpinput(m, src, dst));
+#endif
+ case 0:
+ if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)
+ return 0;
+ if (*(mtod(m, u_char *)) == ISO10747_IDRP)
+ return (idrp_input(m, src, dst));
+ }
+ m = tp_inputprep(m);
+ if (m == 0)
+ return 0;
+ if (mtod(m, u_char *)[1] == UD_TPDU_type)
+ input = cltp_input;
+
+ IFDEBUG(D_TPINPUT)
+ dump_mbuf(m, "after tpclnp_input both pullups");
+ ENDDEBUG
+
+ IFDEBUG(D_TPISO)
+ printf("calling %sinput : src 0x%x, dst 0x%x, src addr:\n",
+ (input == tp_input ? "tp_" : "clts_"), src, dst);
+ dump_isoaddr(src);
+ printf(" dst addr:\n");
+ dump_isoaddr(dst);
+ ENDDEBUG
+
+ (void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst,
+ 0, tpclnp_output_dg, ce_bit);
+
+ IFDEBUG(D_QUENCH)
+ {
+ if(time.tv_usec & 0x4 && time.tv_usec & 0x40) {
+ printf("tpclnp_input: FAKING %s\n",
+ tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2");
+ if(tp_stat.ts_pkt_rcvd & 0x1) {
+ tpclnp_ctlinput(PRC_QUENCH, &src);
+ } else {
+ tpclnp_ctlinput(PRC_QUENCH2, &src);
+ }
+ }
+ }
+ ENDDEBUG
+
+ return 0;
+}
+
+ProtoHook
+iso_rtchange()
+{
+ return 0;
+}
+
+/*
+ * CALLED FROM:
+ * tpclnp_ctlinput()
+ * FUNCTION and ARGUMENTS:
+ * find the tpcb pointer and pass it to tp_quench
+ */
+void
+tpiso_decbit(isop)
+ struct isopcb *isop;
+{
+ tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2);
+}
+/*
+ * CALLED FROM:
+ * tpclnp_ctlinput()
+ * FUNCTION and ARGUMENTS:
+ * find the tpcb pointer and pass it to tp_quench
+ */
+void
+tpiso_quench(isop)
+ struct isopcb *isop;
+{
+ tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH);
+}
+
+/*
+ * CALLED FROM:
+ * The network layer through the protosw table.
+ * FUNCTION and ARGUMENTS:
+ * When clnp an ICMP-like msg this gets called.
+ * It either returns an error status to the user or
+ * it causes all connections on this address to be aborted
+ * by calling the appropriate xx_notify() routine.
+ * (cmd) is the type of ICMP error.
+ * (siso) is the address of the guy who sent the ER CLNPDU
+ */
+ProtoHook
+tpclnp_ctlinput(cmd, siso)
+ int cmd;
+ struct sockaddr_iso *siso;
+{
+ extern u_char inetctlerrmap[];
+ extern ProtoHook tpiso_abort();
+ extern ProtoHook iso_rtchange();
+ extern ProtoHook tpiso_reset();
+ void iso_pcbnotify();
+
+ IFDEBUG(D_TPINPUT)
+ printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
+ dump_isoaddr(siso);
+ ENDDEBUG
+
+ if (cmd < 0 || cmd > PRC_NCMDS)
+ return 0;
+ if (siso->siso_family != AF_ISO)
+ return 0;
+ switch (cmd) {
+
+ case PRC_QUENCH2:
+ iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_decbit);
+ break;
+
+ case PRC_QUENCH:
+ iso_pcbnotify(&tp_isopcb, siso, 0, (int (*)())tpiso_quench);
+ break;
+
+ case PRC_TIMXCEED_REASS:
+ case PRC_ROUTEDEAD:
+ iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
+ break;
+
+ case PRC_HOSTUNREACH:
+ case PRC_UNREACH_NET:
+ case PRC_IFDOWN:
+ case PRC_HOSTDEAD:
+ iso_pcbnotify(&tp_isopcb, siso,
+ (int)inetctlerrmap[cmd], iso_rtchange);
+ break;
+
+ default:
+ /*
+ case PRC_MSGSIZE:
+ case PRC_UNREACH_HOST:
+ case PRC_UNREACH_PROTOCOL:
+ case PRC_UNREACH_PORT:
+ case PRC_UNREACH_NEEDFRAG:
+ case PRC_UNREACH_SRCFAIL:
+ case PRC_REDIRECT_NET:
+ case PRC_REDIRECT_HOST:
+ case PRC_REDIRECT_TOSNET:
+ case PRC_REDIRECT_TOSHOST:
+ case PRC_TIMXCEED_INTRANS:
+ case PRC_PARAMPROB:
+ */
+ iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort);
+ break;
+ }
+ return 0;
+}
+/*
+ * XXX - Variant which is called by clnp_er.c with an isoaddr rather
+ * than a sockaddr_iso.
+ */
+
+static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};
+tpclnp_ctlinput1(cmd, isoa)
+ int cmd;
+ struct iso_addr *isoa;
+{
+ bzero((caddr_t)&siso.siso_addr, sizeof(siso.siso_addr));
+ bcopy((caddr_t)isoa, (caddr_t)&siso.siso_addr, isoa->isoa_len);
+ tpclnp_ctlinput(cmd, &siso);
+}
+
+/*
+ * These next 2 routines are
+ * CALLED FROM:
+ * xxx_notify() from tp_ctlinput() when
+ * net level gets some ICMP-equiv. type event.
+ * FUNCTION and ARGUMENTS:
+ * Cause the connection to be aborted with some sort of error
+ * reason indicating that the network layer caused the abort.
+ * Fakes an ER TPDU so we can go through the driver.
+ * abort always aborts the TP connection.
+ * reset may or may not, depending on the TP class that's in use.
+ */
+ProtoHook
+tpiso_abort(isop)
+ struct isopcb *isop;
+{
+ struct tp_event e;
+
+ IFDEBUG(D_CONN)
+ printf("tpiso_abort 0x%x\n", isop);
+ ENDDEBUG
+ e.ev_number = ER_TPDU;
+ e.ATTR(ER_TPDU).e_reason = ECONNABORTED;
+ return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
+}
+
+ProtoHook
+tpiso_reset(isop)
+ struct isopcb *isop;
+{
+ struct tp_event e;
+
+ e.ev_number = T_NETRESET;
+ return tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
+
+}
+
+#endif /* ISO */
OpenPOWER on IntegriCloud