BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / netiso / tp_input.c
index e8b2e57..2321514 100644 (file)
@@ -1,3 +1,38 @@
+/*-
+ * Copyright (c) 1991 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_input.c  7.19 (Berkeley) 6/27/91
+ */
+
 /***********************************************************
                Copyright IBM Corporation 1987
 
 /***********************************************************
                Copyright IBM Corporation 1987
 
@@ -29,7 +64,6 @@ SOFTWARE.
  *
  * $Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_input.c,v $
  *
  * $Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_input.c,v $
- *     @(#)tp_input.c  7.14 (Berkeley) 7/24/90 *
  *
  * tp_input() gets an mbuf chain from ip.  Actually, not directly
  * from ip, because ip calls a net-level routine that strips off
  *
  * tp_input() gets an mbuf chain from ip.  Actually, not directly
  * from ip, because ip calls a net-level routine that strips off
@@ -52,11 +86,6 @@ SOFTWARE.
  * uses the static structure tpdu_info.
  */
 
  * uses the static structure tpdu_info.
  */
 
-#ifndef lint
-static char *rcsid = "$Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $";
-#endif lint
-
-#include "argoxtwentyfive.h"
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
 #include "param.h"
 #include "systm.h"
 #include "mbuf.h"
@@ -68,7 +97,9 @@ static char *rcsid = "$Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $";
 #include "time.h"
 #include "kernel.h"
 #include "types.h"
 #include "time.h"
 #include "kernel.h"
 #include "types.h"
+#include "iso.h"
 #include "iso_errno.h"
 #include "iso_errno.h"
+#include "iso_pcb.h"
 #include "tp_param.h"
 #include "tp_timer.h"
 #include "tp_stat.h"
 #include "tp_param.h"
 #include "tp_timer.h"
 #include "tp_stat.h"
@@ -76,8 +107,15 @@ static char *rcsid = "$Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $";
 #include "argo_debug.h"
 #include "tp_trace.h"
 #include "tp_tpdu.h"
 #include "argo_debug.h"
 #include "tp_trace.h"
 #include "tp_tpdu.h"
-#include "iso.h"
-#include "cons.h"
+
+#include "../net/if.h"
+#ifdef TRUE
+#undef FALSE
+#undef TRUE
+#endif
+#include "../netccitt/x25.h"
+#include "../netccitt/pk.h"
+#include "../netccitt/pk_var.h"
 
 int    iso_check_csum(), tp_driver(), tp_headersize(), tp_error_emit();
 
 
 int    iso_check_csum(), tp_driver(), tp_headersize(), tp_error_emit();
 
@@ -222,7 +260,7 @@ tp_newsocket(so, fname, cons_channel, class_to_use, netservice)
        u_int                                           netservice;
 {
        register struct tp_pcb  *tpcb = sototpcb(so); /* old tpcb, needed below */
        u_int                                           netservice;
 {
        register struct tp_pcb  *tpcb = sototpcb(so); /* old tpcb, needed below */
-       struct tp_pcb *                  newtpcb;
+       register struct tp_pcb  *newtpcb;
 
        /* 
         * sonewconn() gets a new socket structure,
 
        /* 
         * sonewconn() gets a new socket structure,
@@ -333,7 +371,7 @@ ok:
        return so;
 }
 
        return so;
 }
 
-#ifndef CONS
+#ifndef TPCONS
 tpcons_output()
 {
        return(0);
 tpcons_output()
 {
        return(0);
@@ -633,7 +671,8 @@ again:
                                }
                        }
                        for (t = tp_listeners; t ; t = t->tp_nextlisten)
                                }
                        }
                        for (t = tp_listeners; t ; t = t->tp_nextlisten)
-                               if (bcmp(lsufxloc, t->tp_lsuffix, lsufxlen) == 0 &&
+                               if (lsufxlen == t->tp_lsuffixlen &&
+                                       bcmp(lsufxloc, t->tp_lsuffix, lsufxlen) == 0 &&
                                        laddr->sa_family == t->tp_nlproto->nlp_afamily)
                                                break;
                        CHECK(t == 0, E_TP_NO_SESSION, ts_inv_sufx, respond,
                                        laddr->sa_family == t->tp_nlproto->nlp_afamily)
                                                break;
                        CHECK(t == 0, E_TP_NO_SESSION, ts_inv_sufx, respond,
@@ -838,7 +877,12 @@ again:
                IncStat(ts_ER_rcvd);
                e.ev_number = ER_TPDU;
                e.ATTR(ER_TPDU).e_reason =  (u_char)hdr->tpdu_ERreason;
                IncStat(ts_ER_rcvd);
                e.ev_number = ER_TPDU;
                e.ATTR(ER_TPDU).e_reason =  (u_char)hdr->tpdu_ERreason;
-               takes_data = 1;
+               CHECK (((int)dref <= 0 || dref >= N_TPREF || 
+                       (tpcb = tp_ref[dref].tpr_pcb ) == (struct tp_pcb *) 0 ||
+                       tpcb->tp_refp->tpr_state == REF_FREE ||
+                       tpcb->tp_refp->tpr_state == REF_FROZEN),
+                      E_TP_MISM_REFS, ts_inv_dref, discard, 0)
+
        } else {
                /* tpdu type is CC, XPD, XAK, GR, AK, DR, DC, or DT */
 
        } else {
                /* tpdu type is CC, XPD, XAK, GR, AK, DR, DC, or DT */
 
@@ -846,8 +890,9 @@ again:
                 * _tpduf is the fixed part; add 2 to get the dref bits of 
                 * the fixed part (can't take the address of a bit field) 
                 */
                 * _tpduf is the fixed part; add 2 to get the dref bits of 
                 * the fixed part (can't take the address of a bit field) 
                 */
+#ifdef old_history
                if(cons_channel) {
                if(cons_channel) {
-#if NARGOXTWENTYFIVE > 0
+#ifdef NARGOXTWENTYFIVE
                        extern struct tp_pcb *cons_chan_to_tpcb();
 
                        tpcb = cons_chan_to_tpcb( cons_channel );
                        extern struct tp_pcb *cons_chan_to_tpcb();
 
                        tpcb = cons_chan_to_tpcb( cons_channel );
@@ -868,9 +913,13 @@ again:
                                (1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
 #else
                        printf("tp_input(): X25 NOT CONFIGURED!!\n");
                                (1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
 #else
                        printf("tp_input(): X25 NOT CONFIGURED!!\n");
-#endif NARGOXTWENTYFIVE > 0
-                       
-               } else {
+#endif
+               } else
+                       /* we've now made the error reporting thing check for
+                       multiple channels and not close out if more than
+                       one in use */
+#endif old_history
+               {
 
                        CHECK( ((int)dref <= 0 || dref >= N_TPREF) ,
                                E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
 
                        CHECK( ((int)dref <= 0 || dref >= N_TPREF) ,
                                E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
@@ -1073,6 +1122,14 @@ again:
                                (1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr) 
                                        /* ^ more or less the location of class */
                                )
                                (1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr) 
                                        /* ^ more or less the location of class */
                                )
+#ifdef TPCONS
+                               if (tpcb->tp_netservice == ISO_CONS &&
+                                       class_to_use == TP_CLASS_0) {
+                                       struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
+                                       struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
+                                       lcp->lcd_flags &= ~X25_DG_CIRCUIT;
+                               }
+#endif
                        }
                        if( ! tpcb->tp_use_checksum)
                                IncStat(ts_csum_off);
                        }
                        if( ! tpcb->tp_use_checksum)
                                IncStat(ts_csum_off);
@@ -1096,16 +1153,6 @@ again:
                        (tpcb->tp_nlproto->nlp_mtu)(tpcb->tp_sock, tpcb->tp_sock->so_pcb,
                                                &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
 
                        (tpcb->tp_nlproto->nlp_mtu)(tpcb->tp_sock, tpcb->tp_sock->so_pcb,
                                                &tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
 
-#ifdef CONS
-                       /* Could be that this CC came in on a NEW vc, in which case
-                        * we have to confirm it.
-                        */
-                       if( cons_channel )
-                               cons_netcmd( CONN_CONFIRM, tpcb->tp_npcb, cons_channel, 
-                                               tpcb->tp_class == TP_CLASS_4);
-#endif CONS
-
-                       tpcb->tp_peer_acktime = acktime;
 
                        /* if called or calling suffices appeared on the CC, 
                         * they'd better jive with what's in the pcb
 
                        /* if called or calling suffices appeared on the CC, 
                         * they'd better jive with what's in the pcb
@@ -1306,8 +1353,12 @@ again:
        if (takes_data) {
                int max = tpdu_info[ hdr->tpdu_type ] [TP_MAX_DATA_INDEX];
                int datalen = tpdu_len - hdr->tpdu_li - 1, mbtype = MT_DATA;
        if (takes_data) {
                int max = tpdu_info[ hdr->tpdu_type ] [TP_MAX_DATA_INDEX];
                int datalen = tpdu_len - hdr->tpdu_li - 1, mbtype = MT_DATA;
-               struct cmsghdr c_hdr;
-               struct mbuf *n;
+               struct {
+                       struct tp_disc_reason dr;
+                       struct cmsghdr x_hdr;
+               } x;
+#define c_hdr x.x_hdr
+               register struct mbuf *n;
 
                CHECK( (max && datalen > max), E_TP_LENGTH_INVAL,
                        ts_inv_length, respond, (max + hdr->tpdu_li + 1) );
 
                CHECK( (max && datalen > max), E_TP_LENGTH_INVAL,
                        ts_inv_length, respond, (max + hdr->tpdu_li + 1) );
@@ -1322,19 +1373,27 @@ again:
                        goto make_control_msg;
 
                case DR_TPDU_type:
                        goto make_control_msg;
 
                case DR_TPDU_type:
+                       x.dr.dr_hdr.cmsg_len = sizeof(x) - sizeof(c_hdr);
+                       x.dr.dr_hdr.cmsg_type = TPOPT_DISC_REASON;
+                       x.dr.dr_hdr.cmsg_level = SOL_TRANSPORT;
+                       x.dr.dr_reason = hdr->tpdu_DRreason;
                        c_hdr.cmsg_type = TPOPT_DISC_DATA;
                make_control_msg:
                        c_hdr.cmsg_type = TPOPT_DISC_DATA;
                make_control_msg:
+                       datalen += sizeof(c_hdr);
+                       c_hdr.cmsg_len = datalen;
                        c_hdr.cmsg_level = SOL_TRANSPORT;
                        mbtype = MT_CONTROL;
                        MGET(n, M_DONTWAIT, MT_DATA);
                        c_hdr.cmsg_level = SOL_TRANSPORT;
                        mbtype = MT_CONTROL;
                        MGET(n, M_DONTWAIT, MT_DATA);
-                       if (n) {
-                               datalen += sizeof(c_hdr);
-                               n->m_len = sizeof(c_hdr);
-                               c_hdr.cmsg_len = datalen;
-                               *mtod(n, struct cmsghdr *) = c_hdr;
-                               n->m_next = m;
-                               m = n;
-                       } else {m_freem(m); m = 0; goto invoke;}
+                       if (n == 0)
+                               {m_freem(m); m = 0; datalen = 0; goto invoke; }
+                       if (hdr->tpdu_type == DR_TPDU_type) {
+                               datalen += sizeof(x) - sizeof(c_hdr);
+                               bcopy((caddr_t)&x, mtod(n, caddr_t), n->m_len = sizeof(x));
+                       } else
+                               bcopy((caddr_t)&c_hdr, mtod(n, caddr_t),
+                                         n->m_len = sizeof(c_hdr));
+                       n->m_next = m;
+                       m = n;
                        /* FALLTHROUGH */
 
                case XPD_TPDU_type:
                        /* FALLTHROUGH */
 
                case XPD_TPDU_type: