checkpoint further progress, still doesn't connect tho.
[unix-history] / usr / src / sys / netiso / if_cons.c
index 87a9e03..ff8fe27 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)if_cons.c   7.9 (Berkeley) %G%
+ *     @(#)if_cons.c   7.12 (Berkeley) %G%
  */
 
 /***********************************************************
  */
 
 /***********************************************************
@@ -51,33 +51,31 @@ unsigned LAST_CALL_PCB;
 #define Static static
 #endif ARGO_DEBUG
 
 #define Static static
 #endif ARGO_DEBUG
 
-
-
 #ifndef SOCK_STREAM
 #ifndef SOCK_STREAM
-#include "param.h"
-#include "systm.h"
-#include "mbuf.h"
-#include "protosw.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "errno.h"
-#include "ioctl.h"
-#include "tsleep.h"
-
-#include "../net/if.h"
-#include "../net/netisr.h"
-#include "../net/route.h"
-
-#include "iso_errno.h"
-#include "argo_debug.h"
-#include "tp_trace.h"
-#include "iso.h"
-#include "cons.h"
-#include "iso_pcb.h"
-
-#include "../netccitt/x25.h"
-#include "../netccitt/pk.h"
-#include "../netccitt/pk_var.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/tsleep.h>
+
+#include <net/if.h>
+#include <net/netisr.h>
+#include <net/route.h>
+
+#include <netiso/iso_errno.h>
+#include <netiso/argo_debug.h>
+#include <netiso/tp_trace.h>
+#include <netiso/iso.h>
+#include <netiso/cons.h>
+#include <netiso/iso_pcb.h>
+
+#include <netccitt/x25.h>
+#include <netccitt/pk.h>
+#include <netccitt/pk_var.h>
 #endif
 
 #ifdef ARGO_DEBUG
 #endif
 
 #ifdef ARGO_DEBUG
@@ -147,17 +145,8 @@ extern     struct ifaddr   *ifa_ifwithnet();
 
 extern struct ifaddr   *ifa_ifwithaddr();
 
 
 extern struct ifaddr   *ifa_ifwithaddr();
 
-Static  struct socket  dummysocket; /* for use by cosns */
-
 extern struct  isopcb  tp_isopcb; /* chain of all TP pcbs */
 extern struct  isopcb  tp_isopcb; /* chain of all TP pcbs */
-struct isopcb                  tp_incoming_pending;  /* incoming connections
-                                                                               for TP, pending */
 
 
-struct isopcb  *Xpcblist[] =  {
-       &tp_incoming_pending,
-       &tp_isopcb,
-       (struct isopcb *)0
-};
 
 Static         int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
 Static int FACILtoNSAP(), DTEtoNSAP();
 
 Static         int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
 Static int FACILtoNSAP(), DTEtoNSAP();
@@ -293,32 +282,28 @@ cons_init()
 #endif
 }
 
 #endif
 }
 
-tp_incoming(lcp, m0)
+tp_incoming(lcp, m)
 struct pklcd *lcp;
 struct pklcd *lcp;
-struct mbuf *m0;
+register struct mbuf *m;
 {
 {
-       register struct mbuf *m = m0->m_next; /* m0 has calling sockaddr_x25 */
        register struct isopcb *isop;
        register struct isopcb *isop;
-       extern struct isopcb tp_isopcb;
        int cons_tpinput();
 
        int cons_tpinput();
 
-       if (iso_pcballoc((struct socket *)0, &tp_incoming_pending)) {
-               m_freem(m);
-               pk_clear(lcp);
+       if (iso_pcballoc((struct socket *)0, &tp_isopcb)) {
+               pk_close(lcp);
                return;
        }
                return;
        }
-       isop = tp_incoming_pending.isop_next;
-       pk_output(lcp); /* Confirms call */
+       isop = tp_isopcb.isop_next;
        lcp->lcd_upper = cons_tpinput;
        lcp->lcd_upnext = (caddr_t)isop;
        lcp->lcd_upper = cons_tpinput;
        lcp->lcd_upnext = (caddr_t)isop;
+       lcp->lcd_send(lcp); /* Confirms call */
        isop->isop_chan = (caddr_t)lcp;
        isop->isop_laddr = &isop->isop_sladdr;
        isop->isop_faddr = &isop->isop_sfaddr;
        DTEtoNSAP(isop->isop_laddr, &lcp->lcd_laddr);
        DTEtoNSAP(isop->isop_faddr, &lcp->lcd_faddr);
        isop->isop_chan = (caddr_t)lcp;
        isop->isop_laddr = &isop->isop_sladdr;
        isop->isop_faddr = &isop->isop_sfaddr;
        DTEtoNSAP(isop->isop_laddr, &lcp->lcd_laddr);
        DTEtoNSAP(isop->isop_faddr, &lcp->lcd_faddr);
-       parse_facil(isop, lcp, &(mtod(m, struct x25_packet *)->packet_data),
+       parse_facil(lcp, isop, &(mtod(m, struct x25_packet *)->packet_data),
                m->m_pkthdr.len - PKHEADERLN);
                m->m_pkthdr.len - PKHEADERLN);
-       m_freem(m);
 }
 
 cons_tpinput(lcp, m0)
 }
 
 cons_tpinput(lcp, m0)
@@ -327,26 +312,20 @@ struct pklcd *lcp;
 {
        register struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
        register struct x25_packet *xp;
 {
        register struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
        register struct x25_packet *xp;
-       int cmd;
+       int cmd, ptype = CLEAR;
 
        if (isop == 0)
                return;
 
        if (isop == 0)
                return;
-       if (m0 == 0) {
-               isop->isop_chan = 0;
-               isop->isop_refcnt = 0;
-               lcp->lcd_upnext = 0;
-               lcp->lcd_upper = 0;
+       if (m0 == 0)
                goto dead;
                goto dead;
-       }
        switch(m0->m_type) {
        case MT_DATA:
        case MT_OOBDATA:
        switch(m0->m_type) {
        case MT_DATA:
        case MT_OOBDATA:
-               tpcons_input(m0, isop->isop_faddr, isop->isop_laddr,
-                       (struct socket *)0, (caddr_t)lcp);
+               tpcons_input(m0, isop->isop_faddr, isop->isop_laddr, (caddr_t)lcp);
                return;
 
        case MT_CONTROL:
                return;
 
        case MT_CONTROL:
-               switch (pk_decode(mtod(m0, struct x25_packet *))) {
+               switch (ptype = pk_decode(mtod(m0, struct x25_packet *))) {
 
                case RR:
                        cmd = PRC_CONS_SEND_DONE;
 
                case RR:
                        cmd = PRC_CONS_SEND_DONE;
@@ -360,12 +339,17 @@ struct pklcd *lcp;
                        return;
 
                dead:
                        return;
 
                dead:
-               case RESET:
                case CLEAR:
                case CLEAR_CONF:
                case CLEAR:
                case CLEAR_CONF:
+                       lcp->lcd_upper = 0;
+                       lcp->lcd_upnext = 0;
+                       isop->isop_chan = 0;
+               case RESET:
                        cmd = PRC_ROUTEDEAD;
                }
                tpcons_ctlinput(cmd, isop->isop_faddr, isop);
                        cmd = PRC_ROUTEDEAD;
                }
                tpcons_ctlinput(cmd, isop->isop_faddr, isop);
+               if (cmd = PRC_ROUTEDEAD && isop->isop_refcnt == 0) 
+                       iso_pcbdetach(isop);
        }
 }
 
        }
 }
 
@@ -385,6 +369,7 @@ cons_connect(isop)
        register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
        register struct mbuf    *m;
        struct ifaddr                   *ifa;
        register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
        register struct mbuf    *m;
        struct ifaddr                   *ifa;
+       int error;
 
        IFDEBUG(D_CCONN)
                printf("cons_connect(0x%x): ", isop);
 
        IFDEBUG(D_CCONN)
                printf("cons_connect(0x%x): ", isop);
@@ -402,8 +387,9 @@ cons_connect(isop)
                        &lcp->lcd_faddr, &lcp->lcd_laddr, 
                        isop->isop_socket->so_proto->pr_protocol); 
        ENDDEBUG
                        &lcp->lcd_faddr, &lcp->lcd_laddr, 
                        isop->isop_socket->so_proto->pr_protocol); 
        ENDDEBUG
-       return (make_partial_x25_packet(isop, lcp, m) ||
-                pk_connect(lcp, &lcp->lcd_faddr));
+       if ((error = make_partial_x25_packet(isop, lcp, m)) == 0)
+               error = pk_connect(lcp, &lcp->lcd_faddr);
+       return error;
 }
 
 /*
 }
 
 /*
@@ -571,7 +557,7 @@ make_partial_x25_packet(isop, lcp)
                lcp->lcd_facilities = 0;
                return 0;
        }
                lcp->lcd_facilities = 0;
                return 0;
        }
-       MGET(m, MT_DATA, M_WAITOK);
+       MGETHDR(m, MT_DATA, M_WAITOK);
        if (m == 0)
                return ENOBUFS;
        buf = mtod(m, caddr_t);
        if (m == 0)
                return ENOBUFS;
        buf = mtod(m, caddr_t);
@@ -579,18 +565,22 @@ make_partial_x25_packet(isop, lcp)
        
        /* ptr now points to facil length (len of whole facil field in OCTETS */
        facil_len = ptr ++;
        
        /* ptr now points to facil length (len of whole facil field in OCTETS */
        facil_len = ptr ++;
+       m->m_len = 0;
+       pk_build_facilities(m, &lcp->lcd_faddr, 0);
 
        IFDEBUG(D_CADDR)
                printf("make_partial  calling: ptr 0x%x, len 0x%x\n", ptr, 
                                isop->isop_laddr->siso_addr.isoa_len);
        ENDDEBUG
        if (cons_use_facils) {
 
        IFDEBUG(D_CADDR)
                printf("make_partial  calling: ptr 0x%x, len 0x%x\n", ptr, 
                                isop->isop_laddr->siso_addr.isoa_len);
        ENDDEBUG
        if (cons_use_facils) {
+               *ptr++ = 0;      /* Marker to separate X.25 facitilies from CCITT ones */
+               *ptr++ = 0x0f;
                *ptr = 0xcb; /* calling facility code */
                ptr ++;
                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
                ptr ++; /* leave room for the facil param len (in nibbles),
                *ptr = 0xcb; /* calling facility code */
                ptr ++;
                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
                ptr ++; /* leave room for the facil param len (in nibbles),
-                               * high two bits of which indicate full/partial NSAP
-                               */
+                                * high two bits of which indicate full/partial NSAP
+                                */
                len = isop->isop_laddr->siso_addr.isoa_len;
                bcopy( isop->isop_laddr->siso_data, ptr, len);
                *(ptr-2) = len+1; /* facil param len in octets */
                len = isop->isop_laddr->siso_addr.isoa_len;
                bcopy( isop->isop_laddr->siso_data, ptr, len);
                *(ptr-2) = len+1; /* facil param len in octets */
@@ -605,8 +595,8 @@ make_partial_x25_packet(isop, lcp)
                ptr ++;
                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
                ptr ++; /* leave room for the facil param len (in nibbles),
                ptr ++;
                ptr ++; /* leave room for facil param len (in OCTETS + 1) */
                ptr ++; /* leave room for the facil param len (in nibbles),
-                               * high two bits of which indicate full/partial NSAP
-                               */
+                                * high two bits of which indicate full/partial NSAP
+                                */
                len = isop->isop_faddr->siso_nlen;
                bcopy(isop->isop_faddr->siso_data, ptr, len);
                *(ptr-2) = len+1; /* facil param len = addr len + 1 for each of these
                len = isop->isop_faddr->siso_nlen;
                bcopy(isop->isop_faddr->siso_data, ptr, len);
                *(ptr-2) = len+1; /* facil param len = addr len + 1 for each of these
@@ -642,7 +632,7 @@ make_partial_x25_packet(isop, lcp)
        if (buflen > MHLEN)
                return E_CO_PNA_LONG;
 
        if (buflen > MHLEN)
                return E_CO_PNA_LONG;
 
-       m->m_len = buflen;
+       m->m_pkthdr.len = m->m_len = buflen;
        lcp->lcd_facilities = m;
        return  0;
 }
        lcp->lcd_facilities = m;
        return  0;
 }
@@ -700,10 +690,15 @@ NSAPtoDTE(siso, sx25)
                dtelen = out - sx25->x25_addr;
                *out++ = 0;
        } else {
                dtelen = out - sx25->x25_addr;
                *out++ = 0;
        } else {
-               register struct rtentry *rt = rtalloc1(siso, 1);
                /* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
                /* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
-
-               if (rt) {
+               register struct rtentry *rt;
+               extern struct sockaddr_iso blank_siso;
+               struct sockaddr_iso nsiso;
+
+               nsiso = blank_siso;
+               bcopy(nsiso.siso_data, siso->siso_data,
+                               nsiso.siso_nlen = siso->siso_nlen);
+               if (rt = rtalloc1(&nsiso, 1)) {
                        register struct sockaddr_x25 *sxx =
                                                        (struct sockaddr_x25 *)rt->rt_gateway;
                        register char *in = sxx->x25_addr;
                        register struct sockaddr_x25 *sxx =
                                                        (struct sockaddr_x25 *)rt->rt_gateway;
                        register char *in = sxx->x25_addr;
@@ -727,16 +722,16 @@ NSAPtoDTE(siso, sx25)
  *     Creates and NSAP in the sockaddr_iso (addr) from the
  *  x.25 facility found at buf - 1.
  * RETURNS:
  *     Creates and NSAP in the sockaddr_iso (addr) from the
  *  x.25 facility found at buf - 1.
  * RETURNS:
- *  length of parameter if ok, -1 if error.
+ *  0 if ok, -1 if error.
  */
 
 Static int
 FACILtoNSAP(addr, buf)
  */
 
 Static int
 FACILtoNSAP(addr, buf)
-       u_char          *buf;
+       register u_char                 *buf;
        register struct sockaddr_iso *addr;
 {
        register struct sockaddr_iso *addr;
 {
-       int len_in_nibbles, param_len = *buf++;
-       u_char                  buf_len; /* in bytes */
+       int                     len_in_nibbles = *++buf & 0x3f;
+       u_char          buf_len = (len_in_nibbles + 1) >> 1;; /* in bytes */
 
        IFDEBUG(D_CADDR)
                printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n", 
 
        IFDEBUG(D_CADDR)
                printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n", 
@@ -744,7 +739,6 @@ FACILtoNSAP(addr, buf)
        ENDDEBUG
 
        len_in_nibbles = *buf & 0x3f;
        ENDDEBUG
 
        len_in_nibbles = *buf & 0x3f;
-       buf_len = (len_in_nibbles + 1) >> 1;
        /* despite the fact that X.25 makes us put a length in nibbles
         * here, the NSAP-addrs are always in full octets
         */
        /* despite the fact that X.25 makes us put a length in nibbles
         * here, the NSAP-addrs are always in full octets
         */
@@ -766,10 +760,10 @@ FACILtoNSAP(addr, buf)
                /* Rather than blow away the connection, just ignore and use
                   NSAP from DTE */;
        }
                /* Rather than blow away the connection, just ignore and use
                   NSAP from DTE */;
        }
-       return param_len;
+       return 0;
 }
 
 }
 
-static
+Static
 init_siso(siso)
 register struct sockaddr_iso *siso;
 {
 init_siso(siso)
 register struct sockaddr_iso *siso;
 {
@@ -803,15 +797,17 @@ DTEtoNSAP(addr, sx)
 
 
        init_siso(addr);
 
 
        init_siso(addr);
-       src_len = strlen(sx->x25_addr);
        in = sx->x25_addr;
        in = sx->x25_addr;
-       out = addr->siso_data + 1;
-       if (*in == '0' && (src_len & 1 == 0)) {
+       src_len = strlen(in);
+       addr->siso_nlen = (src_len + 3) / 2;
+       out = addr->siso_data;
+       *out++ = 0x37;
+       if (src_len & 1) {
                pad_tail = 0xf;
                src_len++;
        }
                pad_tail = 0xf;
                src_len++;
        }
-       for (first = 0; src_len > 0; src_len --) {
-               first |= *in++;
+       for (first = 0; src_len > 0; src_len--) {
+               first |= 0xf & *in++;
                if (src_len & 1) {
                        *out++ = first;
                        first = 0;
                if (src_len & 1) {
                        *out++ = first;
                        first = 0;
@@ -831,15 +827,13 @@ DTEtoNSAP(addr, sx)
  *  0 if ok, E* otherwise.
  */
 
  *  0 if ok, E* otherwise.
  */
 
-static int
+Static int
 parse_facil(lcp, isop, buf, buf_len)
        caddr_t                 buf;
        u_char                  buf_len; /* in bytes */
        struct                  isopcb *isop;
        struct                  pklcd *lcp;
 {
 parse_facil(lcp, isop, buf, buf_len)
        caddr_t                 buf;
        u_char                  buf_len; /* in bytes */
        struct                  isopcb *isop;
        struct                  pklcd *lcp;
 {
-       register struct sockaddr_iso *called = isop->isop_laddr;
-       register struct sockaddr_iso *calling = isop->isop_faddr;
        register int    i;
        register u_char         *ptr = (u_char *)buf;
        u_char                  *ptr_lim, *facil_lim;
        register int    i;
        register u_char         *ptr = (u_char *)buf;
        u_char                  *ptr_lim, *facil_lim;
@@ -847,7 +841,7 @@ parse_facil(lcp, isop, buf, buf_len)
 
        IFDEBUG(D_CADDR)
                printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n", 
 
        IFDEBUG(D_CADDR)
                printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n", 
-                       buf, buf_len, called, calling);
+                       lcp, isop, buf, buf_len);
                dump_buf(buf, buf_len);
        ENDDEBUG
 
                dump_buf(buf, buf_len);
        ENDDEBUG
 
@@ -869,7 +863,7 @@ parse_facil(lcp, isop, buf, buf_len)
                printf("parse_facils: facil length is  0x%x\n", (int) facil_len);
        ENDDEBUG
 
                printf("parse_facils: facil length is  0x%x\n", (int) facil_len);
        ENDDEBUG
 
-       while (ptr <= facil_lim) {
+       while (ptr < facil_lim) {
                /* get NSAP addresses from facilities */
                switch (*ptr++) {
                        case 0xcb:
                /* get NSAP addresses from facilities */
                switch (*ptr++) {
                        case 0xcb:
@@ -902,6 +896,7 @@ parse_facil(lcp, isop, buf, buf_len)
                                                (example of intelligent protocol design) */
                        case 0x04:      /* charging info : requesting service */
                        case 0x08:      /* called line addr modified notification */
                                                (example of intelligent protocol design) */
                        case 0x04:      /* charging info : requesting service */
                        case 0x08:      /* called line addr modified notification */
+                       case 0x00:  /* marker to indicate beginning of CCITT facils */
                                facil_param_len = 1;
                                break;
 
                                facil_param_len = 1;
                                break;
 
@@ -914,21 +909,23 @@ parse_facil(lcp, isop, buf, buf_len)
                                facil_param_len = 2;
                                break;
 
                                facil_param_len = 2;
                                break;
 
-                               /* don't have any 3 octets */
-                               /*
-                               facil_param_len = 3;
-                               */
                        default:
                                printf(
                        default:
                                printf(
-"BOGUS FACILITY CODE facil_len 0x%x *facil_len 0x%x, ptr 0x%x *ptr 0x%x\n",
-                                       ptr, facil_len, ptr - 1, ptr[-1]);
-                               /* facil that we don't handle */
-                               return E_CO_HLI_REJI;
+"BOGUS FACILITY CODE facil_lim 0x%x facil_len %d, ptr 0x%x *ptr 0x%x\n",
+                                       facil_lim, facil_len, ptr - 1, ptr[-1]);
+                               /* facil that we don't handle
+                               return E_CO_HLI_REJI; */
+                               switch (ptr[-1] & 0xc0) {
+                               case 0x00:      facil_param_len = 1; break;
+                               case 0x40:      facil_param_len = 2; break;
+                               case 0x80:      facil_param_len = 3; break;
+                               case 0xc0:      facil_param_len = 0; break;
+                               }
                }
                if (facil_param_len == -1)
                        return E_CO_REG_ICDA;
                if (facil_param_len == 0) /* variable length */ 
                }
                if (facil_param_len == -1)
                        return E_CO_REG_ICDA;
                if (facil_param_len == 0) /* variable length */ 
-                       facil_param_len = (int)*ptr; /* 1 + the real facil param */
+                       facil_param_len = (int)*ptr++; /* 1 + the real facil param */
                ptr += facil_param_len;
        }
        return 0;
                ptr += facil_param_len;
        }
        return 0;