BSD 4_4 release
[unix-history] / usr / src / sys / netiso / iso_pcb.c
index f6c63b3..0b50c60 100644 (file)
@@ -1,3 +1,38 @@
+/*-
+ * 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.
+ *
+ *     @(#)iso_pcb.c   8.1 (Berkeley) 6/10/93
+ */
+
 /***********************************************************
                Copyright IBM Corporation 1987
 
 /***********************************************************
                Copyright IBM Corporation 1987
 
@@ -27,32 +62,34 @@ SOFTWARE.
 /*
  * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $
  * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $
 /*
  * $Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $
  * $Source: /usr/argo/sys/netiso/RCS/iso_pcb.c,v $
- *     @(#)iso_pcb.c   7.7 (Berkeley) 4/16/90
  *
  * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
  */
 
  *
  * Iso address family net-layer(s) pcb stuff. NEH 1/29/87
  */
 
-#ifndef lint
-static char *rcsid = "$Header: iso_pcb.c,v 4.5 88/06/29 14:59:56 hagens Exp $";
-#endif
-
 #ifdef ISO
 
 #ifdef ISO
 
-#include "param.h"
-#include "systm.h"
-#include "user.h"
-#include "mbuf.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "argo_debug.h"
-#include "iso.h"
-#include "clnp.h"
-#include "../netinet/in_systm.h"
-#include "../net/if.h"
-#include "../net/route.h"
-#include "iso_pcb.h"
-#include "iso_var.h"
-#include "protosw.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <netiso/argo_debug.h>
+#include <netiso/iso.h>
+#include <netiso/clnp.h>
+#include <netinet/in_systm.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netiso/iso_pcb.h>
+#include <netiso/iso_var.h>
+#include <sys/protosw.h>
+
+#ifdef TPCONS
+#include <netccitt/x25.h>
+#include <netccitt/pk.h>
+#include <netccitt/pk_var.h>
+#endif
 
 #define PCBNULL (struct isopcb *)0
 struct iso_addr zeroiso_addr = {
 
 #define PCBNULL (struct isopcb *)0
 struct iso_addr zeroiso_addr = {
@@ -86,7 +123,8 @@ iso_pcballoc(so, head)
        isop->isop_head = head;
        isop->isop_socket = so;
        insque(isop, head);
        isop->isop_head = head;
        isop->isop_socket = so;
        insque(isop, head);
-       so->so_pcb = (caddr_t)isop;
+       if (so)
+               so->so_pcb = (caddr_t)isop;
        return 0;
 }
        
        return 0;
 }
        
@@ -156,11 +194,6 @@ iso_pcbbind(isop, nam)
        if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
                        return ENAMETOOLONG;
        }
        if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
                        return ENAMETOOLONG;
        }
-       if (siso->siso_tlen) {
-                       register char *cp = TSEL(siso);
-                       suf.data[0] = cp[0];
-                       suf.data[1] = cp[1];
-       }
        if (siso->siso_nlen) {
                /* non-zero net addr- better match one of our interfaces */
                IFDEBUG(D_ISO)
        if (siso->siso_nlen) {
                /* non-zero net addr- better match one of our interfaces */
                IFDEBUG(D_ISO)
@@ -180,13 +213,17 @@ iso_pcbbind(isop, nam)
                isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
        }
        bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
                isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
        }
        bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
-       if (suf.s || siso->siso_tlen != 2) {
-               if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tlen <= 2) &&
-                  (u.u_uid != 0))
+       if (siso->siso_tlen == 0)
+               goto noname;
+       if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
+               iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
+               return EADDRINUSE;
+       if (siso->siso_tlen <= 2) {
+               bcopy(TSEL(siso), suf.data, sizeof(suf.data));
+               suf.s = ntohs(suf.s);
+               if((suf.s < ISO_PORT_RESERVED) &&
+                  (isop->isop_socket->so_state && SS_PRIV) == 0)
                        return EACCES;
                        return EACCES;
-               if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
-                       iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
-                       return EADDRINUSE;
        } else {
                register char *cp;
 noname:
        } else {
                register char *cp;
 noname:
@@ -198,7 +235,7 @@ noname:
                        if (head->isop_lport++ < ISO_PORT_RESERVED ||
                            head->isop_lport > ISO_PORT_USERRESERVED)
                                head->isop_lport = ISO_PORT_RESERVED;
                        if (head->isop_lport++ < ISO_PORT_RESERVED ||
                            head->isop_lport > ISO_PORT_USERRESERVED)
                                head->isop_lport = ISO_PORT_RESERVED;
-                       suf.s = head->isop_lport;
+                       suf.s = htons(head->isop_lport);
                        cp[0] = suf.data[0];
                        cp[1] = suf.data[1];
                } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
                        cp[0] = suf.data[0];
                        cp[1] = suf.data[1];
                } while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
@@ -418,7 +455,20 @@ iso_pcbdetach(isop)
                printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 
                        isop, isop->isop_socket, so);
        ENDDEBUG
                printf("iso_pcbdetach(isop 0x%x socket 0x%x so 0x%x)\n", 
                        isop, isop->isop_socket, so);
        ENDDEBUG
-       if (so ) { /* in the x.25 domain, we sometimes have no socket */
+#ifdef TPCONS
+       if (isop->isop_chan) {
+               register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
+               if (--isop->isop_refcnt > 0)
+                       return;
+               if (lcp && lcp->lcd_state == DATA_TRANSFER) {
+                       lcp->lcd_upper = 0;
+                       lcp->lcd_upnext = 0;
+                       pk_disconnect(lcp);
+               }
+               isop->isop_chan = 0;
+       }
+#endif
+       if (so) { /* in the x.25 domain, we sometimes have no socket */
                so->so_pcb = 0;
                sofree(so); 
        }
                so->so_pcb = 0;
                sofree(so); 
        }
@@ -564,4 +614,4 @@ iso_pcblookup(head, fportlen, fport, laddr)
        }
        return (struct isopcb *)0;
 }
        }
        return (struct isopcb *)0;
 }
-#endif ISO
+#endif /* ISO */