check for duplicate CR's; allow intercepting all CR's to a given
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Fri, 29 Jun 1990 10:40:38 +0000 (02:40 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Fri, 29 Jun 1990 10:40:38 +0000 (02:40 -0800)
nsap; not yet tested, but check in for tape anyhow

SCCS-vsn: sys/netiso/tp_inet.c 7.6
SCCS-vsn: sys/netiso/tp_iso.c 7.8
SCCS-vsn: sys/netiso/tp_input.c 7.12
SCCS-vsn: sys/netiso/tp_pcb.c 7.6
SCCS-vsn: sys/netiso/tp_output.c 7.6
SCCS-vsn: sys/netiso/tp_pcb.h 7.7
SCCS-vsn: sys/netiso/tp_user.h 7.8
SCCS-vsn: sys/netiso/tp_usrreq.c 7.12
SCCS-vsn: sys/tests/netiso/tisink.c 7.2

usr/src/sys/netiso/tp_inet.c
usr/src/sys/netiso/tp_input.c
usr/src/sys/netiso/tp_iso.c
usr/src/sys/netiso/tp_output.c
usr/src/sys/netiso/tp_pcb.c
usr/src/sys/netiso/tp_pcb.h
usr/src/sys/netiso/tp_user.h
usr/src/sys/netiso/tp_usrreq.c
usr/src/sys/tests/netiso/tisink.c

index a4839cd..b2b3fb2 100644 (file)
@@ -28,7 +28,7 @@ SOFTWARE.
  * ARGO TP
  * $Header: tp_inet.c,v 5.3 88/11/18 17:27:29 nhall Exp $ 
  * $Source: /usr/argo/sys/netiso/RCS/tp_inet.c,v $
  * ARGO TP
  * $Header: tp_inet.c,v 5.3 88/11/18 17:27:29 nhall Exp $ 
  * $Source: /usr/argo/sys/netiso/RCS/tp_inet.c,v $
- *     @(#)tp_inet.c   7.5 (Berkeley) %G% *
+ *     @(#)tp_inet.c   7.6 (Berkeley) %G% *
  *
  * Here is where you find the inet-dependent code.  We've tried
  * keep all net-level and (primarily) address-family-dependent stuff
  *
  * Here is where you find the inet-dependent code.  We've tried
  * keep all net-level and (primarily) address-family-dependent stuff
@@ -40,6 +40,7 @@ SOFTWARE.
  *             in_putsufx: put transport suffix into an inpcb structure.
  *             in_putnetaddr: put a whole net addr into an inpcb.
  *             in_getnetaddr: get a whole net addr from an inpcb.
  *             in_putsufx: put transport suffix into an inpcb structure.
  *             in_putnetaddr: put a whole net addr into an inpcb.
  *             in_getnetaddr: get a whole net addr from an inpcb.
+ *             in_cmpnetaddr: compare a whole net addr from an isopcb.
  *             in_recycle_suffix: clear suffix for reuse in inpcb
  *             tpip_mtu: figure out what size tpdu to use
  *             tpip_input: take a pkt from ip, strip off its ip header, give to tp
  *             in_recycle_suffix: clear suffix for reuse in inpcb
  *             tpip_mtu: figure out what size tpdu to use
  *             tpip_input: take a pkt from ip, strip off its ip header, give to tp
@@ -201,6 +202,39 @@ in_putnetaddr(inp, name, which)
        }
 }
 
        }
 }
 
+/*
+ * NAME:       in_putnetaddr()
+ *
+ * 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 inpcb (inp).
+ *     The argument (which) takes values TP_LOCAL or TP_FOREIGN
+ *
+ * RETURNS:            Nada
+ *
+ * SIDE EFFECTS:       
+ *
+ * NOTES:                      
+ */ 
+in_cmpnetaddr(inp, name, which)
+       register struct inpcb   *inp;
+       register struct sockaddr_in     *name;
+       int which;
+{
+       if (which == TP_LOCAL) {
+               if (name->sin_port && name->sin_port != inp->inp_lport)
+                       return 0;
+               return (name->sin_addr.s_addr == inp->inp_laddr.s_addr);
+       }
+       if (name->sin_port && name->sin_port != inp->inp_fport)
+               return 0;
+       return (name->sin_addr.s_addr == inp->inp_faddr.s_addr);
+}
+
 /*
  * NAME:       in_getnetaddr()
  *
 /*
  * NAME:       in_getnetaddr()
  *
index 3c26d43..86296a7 100644 (file)
@@ -29,7 +29,7 @@ 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.11 (Berkeley) %G% *
+ *     @(#)tp_input.c  7.12 (Berkeley) %G% *
  *
  * 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
@@ -58,6 +58,7 @@ static char *rcsid = "$Header: tp_input.c,v 5.6 88/11/18 17:27:38 nhall Exp $";
 
 #include "argoxtwentyfive.h"
 #include "param.h"
 
 #include "argoxtwentyfive.h"
 #include "param.h"
+#include "systm.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "mbuf.h"
 #include "socket.h"
 #include "socketvar.h"
@@ -386,8 +387,7 @@ tp_input(m, faddr, laddr, cons_channel, dgout_routine, ce_bit)
 #ifdef TP_PERF_MEAS
        u_char                                  perf_meas;
 #endif TP_PERF_MEAS
 #ifdef TP_PERF_MEAS
        u_char                                  perf_meas;
 #endif TP_PERF_MEAS
-       u_char                                  fsufxlen = 0;
-       u_char                                  lsufxlen = 0;
+       u_char                                  fsufxlen = 0, lsufxlen = 0, intercepted = 0;
        caddr_t                                 fsufxloc = 0, lsufxloc = 0;
        int                                             tpdu_len = 0;
        u_int                                   takes_data = FALSE;
        caddr_t                                 fsufxloc = 0, lsufxloc = 0;
        int                                             tpdu_len = 0;
        u_int                                   takes_data = FALSE;
@@ -619,46 +619,51 @@ again:
 
                /* } */ END_WHILE_OPTIONS(P)
 
 
                /* } */ END_WHILE_OPTIONS(P)
 
-               iflsufxlen == 0) {
+               if (lsufxlen == 0) {
                        /* can't look for a tpcb w/o any called sufx */
                        error =  E_TP_LENGTH_INVAL;
                        IncStat(ts_inv_sufx);
                        goto respond;
                } else {
                        /* can't look for a tpcb w/o any called sufx */
                        error =  E_TP_LENGTH_INVAL;
                        IncStat(ts_inv_sufx);
                        goto respond;
                } else {
-                       register        struct tp_ref   *rp;
-                       register        int                     r;
-                       extern          int                     tp_maxrefopen;
+                       register struct tp_pcb *t;
 
 
-                       rp = &tp_ref[1]; /* zero-th one is never open */
-                       for(  r=1 ; (r <= tp_maxrefopen) ; r++,rp++ ) {
-                               if (rp->tpr_state!=REF_OPENING) 
+                       for (t = tp_intercepts; t ; t->tp_nextlisten) {
+                               if (laddr->sa_family != t->tp_nlproto->nlp_afamily)
                                        continue;
                                        continue;
-                               if ( bcmp(lsufxloc, rp->tpr_pcb->tp_lsuffix, lsufxlen)==0 ) {
-                                       tpcb =  rp->tpr_pcb;
-                                       if( laddr->sa_family !=
-                                                       tpcb->tp_sock->so_proto->pr_domain->dom_family ) {
-                                               IFDEBUG(D_CONN)
-                                                       printf(
-                                       "MISMATCHED AF on CR! laddr.family 0x%x expected 0x%x\n",
-                                                       laddr->sa_family, 
-                                                       tpcb->tp_sock->so_proto->pr_domain->dom_family );
-                                               ENDDEBUG
-                                               continue;
-                                       }
-                                       IFTRACE(D_TPINPUT)
-                                               tptrace(TPPTmisc, "tp_input: ref *lsufxloc refstate", 
-                                                       r, *lsufxloc, rp->tpr_state, 0);
-                                       ENDTRACE
-                                       /* found it */
-                                       break;
+                               if ((*tpcb->tp_nlproto->nlp_cmpnetaddr)(
+                                               t->tp_npcb, laddr, TP_LOCAL)) {
+                                                       intercepted = 1;
+                                                       goto check_duplicate_cr;
                                }
                        }
                                }
                        }
-
-                       CHECK( (r > tp_maxrefopen), E_TP_NO_SESSION, ts_inv_sufx, respond,
+                       for (t = tp_listeners; t ; t->tp_nextlisten) {
+                               if (bcmp(lsufxloc, t->tp_lsuffix, lsufxlen) != 0)
+                                       continue;
+                               if (laddr->sa_family != t->tp_nlproto->nlp_afamily)
+                                       continue;
+                       }
+                       CHECK(t == 0, E_TP_NO_SESSION, ts_inv_sufx, respond,
                                (1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
                                /* _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) 
                                 */
                                (1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
                                /* _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) 
                                 */
+               check_duplicate_cr:
+                       tpcb = t;
+                       for (t = tpcb->tp_next; t != tpcb; t = t->tp_next) {
+                               if (sref != t->tp_fref)
+                                       continue;
+                               if ((*tpcb->tp_nlproto->nlp_cmpnetaddr)(
+                                               t->tp_npcb, faddr, TP_FOREIGN)) {
+                                       IFDEBUG(D_TPINPUT)
+                                               printf("duplicate CR discarded\n");
+                                       ENDDEBUG
+                                       goto discard;
+                               }
+                       }
+                       IFTRACE(D_TPINPUT)
+                               tptrace(TPPTmisc, "tp_input: tpcb *lsufxloc tpstate", 
+                                       tpcb, *lsufxloc, tpcb->tp_state, 0);
+                       ENDTRACE
                }
 
                /* 
                }
 
                /* 
@@ -728,6 +733,7 @@ again:
 
                so = tpcb->tp_sock;
                if (so->so_options & SO_ACCEPTCONN) {
 
                so = tpcb->tp_sock;
                if (so->so_options & SO_ACCEPTCONN) {
+                       struct tp_pcb *parent_tpcb = tpcb;
                        /* 
                         * Create a socket, tpcb, ll pcb, etc. 
                         * for this newborn connection, and fill in all the values. 
                        /* 
                         * Create a socket, tpcb, ll pcb, etc. 
                         * for this newborn connection, and fill in all the values. 
@@ -752,6 +758,7 @@ again:
                                goto discard;
                        }
                        tpcb = sototpcb(so);
                                goto discard;
                        }
                        tpcb = sototpcb(so);
+                       insque(parent_tpcb, tpcb);
 
                        /*
                         * Stash the addresses in the net level pcb 
 
                        /*
                         * Stash the addresses in the net level pcb 
@@ -762,14 +769,14 @@ again:
                        (tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, laddr, TP_LOCAL);
 
                        /* stash the f suffix in the new tpcb */
                        (tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, laddr, TP_LOCAL);
 
                        /* stash the f suffix in the new tpcb */
-                       /* l suffix is already there */
                        bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen);
                        bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen);
-
+                       /* l suffix is already there, unless this is an intercept case */
+                       if (intercepted)
+                               bcopy(lsufxloc, tpcb->tp_lsuffix, lsufxlen);
                        (tpcb->tp_nlproto->nlp_putsufx)
                                        (so->so_pcb, fsufxloc, fsufxlen, TP_FOREIGN);
                        (tpcb->tp_nlproto->nlp_putsufx)
                                        (so->so_pcb, lsufxloc, lsufxlen, TP_LOCAL);
                        (tpcb->tp_nlproto->nlp_putsufx)
                                        (so->so_pcb, fsufxloc, fsufxlen, TP_FOREIGN);
                        (tpcb->tp_nlproto->nlp_putsufx)
                                        (so->so_pcb, lsufxloc, lsufxlen, TP_LOCAL);
-
 #ifdef TP_PERF_MEAS
                        if( tpcb->tp_perf_on = perf_meas ) { /* assignment */
                                /* ok, let's create an mbuf for stashing the
 #ifdef TP_PERF_MEAS
                        if( tpcb->tp_perf_on = perf_meas ) { /* assignment */
                                /* ok, let's create an mbuf for stashing the
index 494efaa..4a5ea5d 100644 (file)
@@ -28,7 +28,7 @@ SOFTWARE.
  * 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 $
  * 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 $
- *     @(#)tp_iso.c    7.7 (Berkeley) %G%
+ *     @(#)tp_iso.c    7.8 (Berkeley) %G%
  *
  * Here is where you find the iso-dependent code.  We've tried
  * keep all net-level and (primarily) address-family-dependent stuff
  *
  * Here is where you find the iso-dependent code.  We've tried
  * keep all net-level and (primarily) address-family-dependent stuff
@@ -40,6 +40,7 @@ SOFTWARE.
  *             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_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
  *             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
@@ -199,6 +200,9 @@ iso_putnetaddr(isop, name, which)
        register struct sockaddr_iso *siso;
 
        switch (which) {
        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;
        case TP_LOCAL:
                sisop = &isop->isop_laddr;
                backup = &isop->isop_sladdr;
@@ -215,6 +219,47 @@ iso_putnetaddr(isop, name, which)
        siso->siso_addr = name->siso_addr;
 }
 
        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
 /*
  * CALLED FROM:
  *  pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
index fcd299a..3de9b19 100644 (file)
@@ -29,7 +29,7 @@ SOFTWARE.
  *
  * $Header: tp_output.c,v 5.4 88/11/18 17:28:08 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_output.c,v $
  *
  * $Header: tp_output.c,v 5.4 88/11/18 17:28:08 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_output.c,v $
- *     @(#)tp_output.c 7.5 (Berkeley) %G% *
+ *     @(#)tp_output.c 7.6 (Berkeley) %G% *
  *
  * In here is tp_ctloutput(), the guy called by [sg]etsockopt(),
  */
  *
  * In here is tp_ctloutput(), the guy called by [sg]etsockopt(),
  */
@@ -39,18 +39,20 @@ static char *rcsid = "$Header: tp_output.c,v 5.4 88/11/18 17:28:08 nhall Exp $";
 #endif lint
 
 #include "param.h"
 #endif lint
 
 #include "param.h"
-#include "systm.h"
 #include "mbuf.h"
 #include "mbuf.h"
-#include "protosw.h"
+#include "systm.h"
 #include "socket.h"
 #include "socketvar.h"
 #include "socket.h"
 #include "socketvar.h"
+#include "protosw.h"
+#include "user.h"
+#include "kernel.h"
 #include "errno.h"
 #include "errno.h"
-#include "types.h"
 #include "time.h"
 #include "tp_param.h"
 #include "tp_user.h"
 #include "tp_stat.h"
 #include "tp_ip.h"
 #include "time.h"
 #include "tp_param.h"
 #include "tp_user.h"
 #include "tp_stat.h"
 #include "tp_ip.h"
+#include "tp_clnp.h"
 #include "tp_timer.h"
 #include "argo_debug.h"
 #include "tp_pcb.h"
 #include "tp_timer.h"
 #include "argo_debug.h"
 #include "tp_pcb.h"
@@ -420,6 +422,50 @@ tp_ctloutput(cmd, so, level, optname, mp)
 
        switch (optname) {
 
 
        switch (optname) {
 
+       case TPOPT_INTERCEPT:
+               if (error = suser(u.u_cred, &u.u_acflag))
+                       break;
+               else if (cmd != PRCO_SETOPT || tpcb->tp_state != TP_LISTENING)
+                       error = EINVAL;
+               else {
+                       register struct tp_pcb *t = 0;
+                       struct mbuf *m = m_getclr(M_WAIT, MT_SONAME);
+                       struct sockaddr *sa = mtod(m, struct sockaddr *);
+                       (*tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, m, TP_LOCAL);
+                       switch (sa->sa_family) {
+                       case AF_ISO:
+                               if (((struct sockaddr_iso *)sa)->siso_nlen == 0)
+                                       default: error = EINVAL;
+                               break;
+                       case AF_INET:
+                               if (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0)
+                                       error = EINVAL;
+                               break;
+                       }
+                       for (t = tp_intercepts; t; t = t->tp_nextlisten) {
+                               if (t->tp_nlproto->nlp_afamily != tpcb->tp_nlproto->nlp_afamily)
+                                       continue;
+                               if ((*t->tp_nlproto->nlp_cmpnetaddr)(t->tp_npcb, sa, TP_LOCAL))
+                                       error = EADDRINUSE;
+                       }
+                       m_freem(m);
+                       if (error)
+                               break;
+               }
+               {
+                       register struct tp_pcb **tt;
+                       for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
+                               if (*tt == tpcb)
+                                       break;
+                       if (*tt)
+                               *tt = tpcb->tp_nextlisten;
+                       else
+                               {error = EHOSTUNREACH; goto done; }
+               }
+               tp_intercepts = tpcb;
+               tpcb->tp_nextlisten = tp_intercepts;
+               break;
+
        case TPOPT_MY_TSEL:
                if ( cmd == PRCO_GETOPT ) {
                        ASSERT( tpcb->tp_lsuffixlen <= MAX_TSAP_SEL_LEN );
        case TPOPT_MY_TSEL:
                if ( cmd == PRCO_GETOPT ) {
                        ASSERT( tpcb->tp_lsuffixlen <= MAX_TSAP_SEL_LEN );
index 9cb53f6..40c58cd 100644 (file)
@@ -29,7 +29,7 @@ SOFTWARE.
  *
  * $Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.c,v $
  *
  * $Header: tp_pcb.c,v 5.4 88/11/18 17:28:24 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.c,v $
- *     @(#)tp_pcb.c    7.5 (Berkeley) %G% *
+ *     @(#)tp_pcb.c    7.6 (Berkeley) %G% *
  *
  *
  * This is the initialization and cleanup stuff - 
  *
  *
  * This is the initialization and cleanup stuff - 
@@ -230,6 +230,7 @@ struct tp_conn_param tp_conn_param[] = {
 #ifdef INET
 int            in_putnetaddr();
 int            in_getnetaddr();
 #ifdef INET
 int            in_putnetaddr();
 int            in_getnetaddr();
+int            in_cmpnetaddr();
 int    in_putsufx(); 
 int    in_getsufx(); 
 int    in_recycle_tsuffix(); 
 int    in_putsufx(); 
 int    in_getsufx(); 
 int    in_recycle_tsuffix(); 
@@ -246,6 +247,7 @@ struct inpcb        tp_inpcb;
 #ifdef ISO
 int            iso_putnetaddr();
 int            iso_getnetaddr();
 #ifdef ISO
 int            iso_putnetaddr();
 int            iso_getnetaddr();
+int            iso_cmpnetaddr();
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
@@ -263,6 +265,7 @@ struct isopcb       tp_isopcb;
 #if NARGOXTWENTYFIVE > 0
 int            iso_putnetaddr();
 int            iso_getnetaddr();
 #if NARGOXTWENTYFIVE > 0
 int            iso_putnetaddr();
 int            iso_getnetaddr();
+int            iso_cmpnetaddr();
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
 int    iso_putsufx(); 
 int    iso_getsufx(); 
 int    iso_recycle_tsuffix(); 
@@ -281,7 +284,7 @@ struct isopcb       tp_isopcb;
 struct nl_protosw nl_protosw[] = {
        /* ISO_CLNS */
 #ifdef ISO
 struct nl_protosw nl_protosw[] = {
        /* ISO_CLNS */
 #ifdef ISO
-       { AF_ISO, iso_putnetaddr, iso_getnetaddr,
+       { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpclnp_mtu, iso_pcbbind, iso_pcbconnect,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpclnp_mtu, iso_pcbbind, iso_pcbconnect,
@@ -295,7 +298,7 @@ struct nl_protosw nl_protosw[] = {
 #endif ISO
        /* IN_CLNS */
 #ifdef INET
 #endif ISO
        /* IN_CLNS */
 #ifdef INET
-       { AF_INET, in_putnetaddr, in_getnetaddr,
+       { AF_INET, in_putnetaddr, in_getnetaddr, in_cmpnetaddr,
                in_putsufx, in_getsufx,
                in_recycle_tsuffix,
                tpip_mtu, in_pcbbind, in_pcbconnect,
                in_putsufx, in_getsufx,
                in_recycle_tsuffix,
                tpip_mtu, in_pcbbind, in_pcbconnect,
@@ -309,7 +312,7 @@ struct nl_protosw nl_protosw[] = {
 #endif INET
        /* ISO_CONS */
 #if defined(ISO) && (NARGOXTWENTYFIVE > 0)
 #endif INET
        /* ISO_CONS */
 #if defined(ISO) && (NARGOXTWENTYFIVE > 0)
-       { AF_ISO, iso_putnetaddr, iso_getnetaddr,
+       { AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpcons_mtu, iso_pcbbind, iso_pcbconnect,
                iso_putsufx, iso_getsufx,
                iso_recycle_tsuffix,
                tpcons_mtu, iso_pcbbind, iso_pcbconnect,
index cdf11c2..f669bca 100644 (file)
@@ -29,7 +29,7 @@ SOFTWARE.
  *
  * $Header: tp_pcb.h,v 5.2 88/11/18 17:09:32 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.h,v $
  *
  * $Header: tp_pcb.h,v 5.2 88/11/18 17:09:32 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_pcb.h,v $
- *     @(#)tp_pcb.h    7.6 (Berkeley) %G% *
+ *     @(#)tp_pcb.h    7.7 (Berkeley) %G% *
  *
  * 
  * This file defines the transport protocol control block (tpcb).
  *
  * 
  * This file defines the transport protocol control block (tpcb).
@@ -102,11 +102,11 @@ struct tp_rtc {
        struct mbuf             *tprt_data; /* ptr to the octets of data */
 };
 
        struct mbuf             *tprt_data; /* ptr to the octets of data */
 };
 
-extern
 struct nl_protosw {
        int             nlp_afamily;                    /* address family */
        int             (*nlp_putnetaddr)();    /* puts addresses in nl pcb */
        int             (*nlp_getnetaddr)();    /* gets addresses from nl pcb */
 struct nl_protosw {
        int             nlp_afamily;                    /* address family */
        int             (*nlp_putnetaddr)();    /* puts addresses in nl pcb */
        int             (*nlp_getnetaddr)();    /* gets addresses from nl pcb */
+       int             (*nlp_cmpnetaddr)();    /* compares address in pcb with sockaddr */
        int             (*nlp_putsufx)();               /* puts transport suffixes in nl pcb */
        int             (*nlp_getsufx)();               /* gets transport suffixes from nl pcb */
        int             (*nlp_recycle_suffix)();/* clears suffix from nl pcb */
        int             (*nlp_putsufx)();               /* puts transport suffixes in nl pcb */
        int             (*nlp_getsufx)();               /* gets transport suffixes from nl pcb */
        int             (*nlp_recycle_suffix)();/* clears suffix from nl pcb */
@@ -120,10 +120,13 @@ struct nl_protosw {
        int             (*nlp_dgoutput)();              /* prepare a packet to give to nl */
        int             (*nlp_ctloutput)();             /* hook for network set/get options */
        caddr_t nlp_pcblist;                    /* list of xx_pcb's for connections */
        int             (*nlp_dgoutput)();              /* prepare a packet to give to nl */
        int             (*nlp_ctloutput)();             /* hook for network set/get options */
        caddr_t nlp_pcblist;                    /* list of xx_pcb's for connections */
-} nl_protosw[];
+};
 
 
 struct tp_pcb {
 
 
 struct tp_pcb {
+       struct tp_pcb           *tp_next;
+       struct tp_pcb           *tp_prev;
+       struct tp_pcb           *tp_nextlisten; /* chain all listeners */
        u_short                         tp_state;               /* state of fsm */
        short                           tp_retrans;             /* # times can still retrans */
        struct tp_ref           *tp_refp;               /* rest of pcb  */
        u_short                         tp_state;               /* state of fsm */
        short                           tp_retrans;             /* # times can still retrans */
        struct tp_ref           *tp_refp;               /* rest of pcb  */
@@ -320,9 +323,14 @@ u_int      tp_start_win;
        } \
 }
 
        } \
 }
 
+#ifdef KERNEL
 extern struct timeval  time;
 extern struct tp_ref   tp_ref[];
 extern struct tp_param tp_param;
 extern struct timeval  time;
 extern struct tp_ref   tp_ref[];
 extern struct tp_param tp_param;
+extern struct nl_protosw  nl_protosw[];
+extern struct tp_pcb   *tp_listeners;
+extern struct tp_pcb   *tp_intercepts;
+#endif
 
 #define        sototpcb(so)    ((struct tp_pcb *)(so->so_tpcb))
 #define        sototpref(so)   ((struct tp_ref *)((so)->so_tpcb->tp_ref))
 
 #define        sototpcb(so)    ((struct tp_pcb *)(so->so_tpcb))
 #define        sototpref(so)   ((struct tp_ref *)((so)->so_tpcb->tp_ref))
index 89111fb..77314e7 100644 (file)
@@ -29,7 +29,7 @@ SOFTWARE.
  *
  * $Header: tp_user.h,v 5.2 88/11/04 15:44:44 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_user.h,v $
  *
  * $Header: tp_user.h,v 5.2 88/11/04 15:44:44 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_user.h,v $
- *     @(#)tp_user.h   7.7 (Berkeley) %G%
+ *     @(#)tp_user.h   7.8 (Berkeley) %G%
  *
  * These are the values a real-live user ;-) needs. 
  */
  *
  * These are the values a real-live user ;-) needs. 
  */
@@ -96,6 +96,7 @@ struct tp_conn_param {
 #define                TPRX_EACH               0x4 /* retrans each packet of a set */
 #define                TPRX_FASTSTART  0x1 /* don't use slow start */
 
 #define                TPRX_EACH               0x4 /* retrans each packet of a set */
 #define                TPRX_FASTSTART  0x1 /* don't use slow start */
 
+#define TPOPT_INTERCEPT                0x200
 #define TPOPT_FLAGS                    0x300
 #define TPOPT_CONN_DATA                0x400 
 #define TPOPT_DISC_DATA                0x500 
 #define TPOPT_FLAGS                    0x300
 #define TPOPT_CONN_DATA                0x400 
 #define TPOPT_DISC_DATA                0x500 
index b30523c..06a92cc 100644 (file)
@@ -29,7 +29,7 @@ SOFTWARE.
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
  *
  * $Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $
  * $Source: /usr/argo/sys/netiso/RCS/tp_usrreq.c,v $
- *     @(#)tp_usrreq.c 7.11 (Berkeley) %G%
+ *     @(#)tp_usrreq.c 7.12 (Berkeley) %G%
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
  *
  * tp_usrreq(), the fellow that gets called from most of the socket code.
  * Pretty straighforward.
@@ -67,6 +67,7 @@ static char *rcsid = "$Header: tp_usrreq.c,v 5.4 88/11/18 17:29:18 nhall Exp $";
 int tp_attach(), tp_driver();
 int TNew;
 int TPNagle1, TPNagle2;
 int tp_attach(), tp_driver();
 int TNew;
 int TPNagle1, TPNagle2;
+struct tp_pcb *tp_listeners, *tp_intercepts;
 
 #ifdef ARGO_DEBUG
 /*
 
 #ifdef ARGO_DEBUG
 /*
@@ -397,6 +398,25 @@ tp_usrreq(so, req, m, nam, controlp)
 
        case PRU_DETACH:        /* called from close() */
                /* called only after disconnect was called */
 
        case PRU_DETACH:        /* called from close() */
                /* called only after disconnect was called */
+               if (tpcb->tp_state == TP_LISTENING) {
+                       register struct tp_pcb **tt;
+                       for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
+                               if (*tt == tpcb)
+                                       break;
+                       if (*tt)
+                               *tt = tpcb->tp_nextlisten;
+                       else {
+                               for (tt = &tp_intercepts; *tt; tt = &((*tt)->tp_nextlisten))
+                                       if (*tt == tpcb)
+                                               break;
+                               if (*tt)
+                                       *tt = tpcb->tp_nextlisten;
+                               else
+                                       printf("tp_usrreq - detach: should panic\n");
+                       }
+               }
+               if (tpcb->tp_next)
+                       remque(tpcb);
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
                error = DoEvent(T_DETACH);
                if (tpcb->tp_state == TP_CLOSED) {
                        free((caddr_t)tpcb, M_PCB);
@@ -426,6 +446,11 @@ tp_usrreq(so, req, m, nam, controlp)
                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
                                tpcb->tp_lsuffix, TP_LOCAL);
                }
                        (tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
                                tpcb->tp_lsuffix, TP_LOCAL);
                }
+               if (tpcb->tp_next == 0) {
+                       tpcb->tp_next = tpcb->tp_prev = tpcb;
+                       tpcb->tp_nextlisten = tp_listeners;
+                       tp_listeners = tpcb->tp_nextlisten;
+               }
                IFDEBUG(D_TPISO)
                        if (tpcb->tp_state != TP_CLOSED)
                                printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
                IFDEBUG(D_TPISO)
                        if (tpcb->tp_state != TP_CLOSED)
                                printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
index 0116172..2bd1124 100644 (file)
@@ -5,7 +5,7 @@
  * %sccs.include.redist.c%
  */
 #ifndef lint
  * %sccs.include.redist.c%
  */
 #ifndef lint
-static char sccsid[] = "@(#)tisink.c   7.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)tisink.c   7.2 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -39,7 +39,7 @@ struct  sockaddr_iso faddr, laddr = { sizeof(laddr), AF_ISO };
 struct  sockaddr_iso *siso = &laddr;
 
 long size, count = 10, forkp, confp, echop, mynamep, verbose = 1, playtag = 0;
 struct  sockaddr_iso *siso = &laddr;
 
 long size, count = 10, forkp, confp, echop, mynamep, verbose = 1, playtag = 0;
-long records;
+long records, intercept;
 
 char buf[2048];
 char your_it[] = "You're it!";
 
 char buf[2048];
 char your_it[] = "You're it!";
@@ -131,6 +131,10 @@ tisink()
        /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */
 
        try(listen, (s, 5), "");
        /*try(setsockopt, (s, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)), ""); */
 
        try(listen, (s, 5), "");
+       if (intercept) {
+           try(setsockopt,
+               (s, SOL_TRANSPORT, TPOPT_INTERCEPT, &on, sizeof(on)), "");
+       }
        for(;;) {
                int child, ns;
                int addrlen = sizeof(faddr);
        for(;;) {
                int child, ns;
                int addrlen = sizeof(faddr);