BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / netccitt / hd_subr.c
index a2a3cd0..bc881ec 100644 (file)
@@ -7,26 +7,52 @@
  * the Laboratory for Computation Vision and the Computer Science Department
  * of the University of British Columbia.
  *
  * the Laboratory for Computation Vision and the Computer Science Department
  * of the University of British Columbia.
  *
- * %sccs.include.redist.c%
+ * 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.
  *
  *
- *     @(#)hd_subr.c   7.2 (Berkeley) %G%
+ * 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.
+ *
+ *     @(#)hd_subr.c   7.6 (Berkeley) 5/29/91
  */
 
  */
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/mbuf.h"
-#include "../h/domain.h"
-#include "../h/socket.h"
-#include "../h/protosw.h"
-#include "../h/errno.h"
-#include "../h/time.h"
-#include "../h/kernel.h"
+#include "param.h"
+#include "systm.h"
+#include "mbuf.h"
+#include "domain.h"
+#include "socket.h"
+#include "protosw.h"
+#include "errno.h"
+#include "time.h"
+#include "kernel.h"
 
 #include "../net/if.h"
 
 
 #include "../net/if.h"
 
-#include "../netccitt/hdlc.h"
-#include "../netccitt/hd_var.h"
-#include "../netccitt/x25.h"
+#include "hdlc.h"
+#include "hd_var.h"
+#include "x25.h"
 
 hd_init ()
 {
 
 hd_init ()
 {
@@ -35,44 +61,47 @@ hd_init ()
 }
 
 hd_ctlinput (prc, addr)
 }
 
 hd_ctlinput (prc, addr)
-caddr_t addr;
+struct sockaddr *addr;
 {
        register struct x25config *xcp = (struct x25config *)addr;
 {
        register struct x25config *xcp = (struct x25config *)addr;
-       register struct ifnet *ifp;
        register struct hdcb *hdp;
        register struct ifaddr *ifa;
        register struct hdcb *hdp;
        register struct ifaddr *ifa;
+       struct ifnet *ifp;
+       caddr_t pk_newlink();
 
 
-       if (xcp->xc_family != AF_CCITT)
+       if (addr->sa_family != AF_CCITT)
                return (EAFNOSUPPORT);
        if (xcp->xc_lptype != HDLCPROTO_LAPB)
                return (EPROTONOSUPPORT);
                return (EAFNOSUPPORT);
        if (xcp->xc_lptype != HDLCPROTO_LAPB)
                return (EPROTONOSUPPORT);
-       for (ifa = ifa_ifwithaddr ((struct sockaddr *)xcp); ifa; ifa = ifa->ifa_next)
-               if (ifa->ifa_addr.sa_family == AF_CCITT)
-                       break;
-       if (ifa == 0 || (ifp = ifa->ifa_ifp) == 0)
+       ifa = ifa_ifwithaddr(addr);
+       if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT ||
+           (ifp = ifa->ifa_ifp) == 0)
                panic ("hd_ctlinput");
        for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
                if (hdp->hd_ifp == ifp)
                        break;
 
        if (hdp == 0) {         /* new interface */
                panic ("hd_ctlinput");
        for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
                if (hdp->hd_ifp == ifp)
                        break;
 
        if (hdp == 0) {         /* new interface */
-               register int error;
-               register struct mbuf *m;
+               int error, hd_ifoutput(), hd_output();
 
 
-               m = m_getclr (M_DONTWAIT, MT_PCB);
-               if (m == 0)
+               /* an hdcb is now too big to fit in an mbuf */
+               MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT);
+               if (hdp == 0)
+                       return (ENOBUFS);
+               bzero((caddr_t)hdp, sizeof(*hdp));
+               hdp->hd_pkp =
+                       pk_newlink ((struct x25_ifaddr *)ifa, (caddr_t)hdp);
+               if (hdp -> hd_pkp == 0) {
+                       free(hdp, M_PCB);
                        return (ENOBUFS);
                        return (ENOBUFS);
-               if (error = pk_ctlinput (PRC_LINKDOWN, xcp)) {
-                       m_freem (m);
-                       return (error);
                }
                }
-
-               hdp = mtod (m, struct hdcb *);
                hdp->hd_ifp = ifp;
                hdp->hd_ifp = ifp;
+               hdp->hd_ifa = ifa;
                hdp->hd_xcp = xcp;
                hdp->hd_xcp = xcp;
+               hdp->hd_state = INIT;
+               hdp->hd_output = hd_ifoutput;
                hdp->hd_next = hdcbhead;
                hdcbhead = hdp;
                hdp->hd_next = hdcbhead;
                hdcbhead = hdp;
-               hdp->hd_state = INIT;
        }
 
        switch (prc) {
        }
 
        switch (prc) {
@@ -87,7 +116,7 @@ caddr_t addr;
        case PRC_IFDOWN:
                if (hdp->hd_state == ABM)
                        hd_message (hdp, "Operator shutdown: link closed");
        case PRC_IFDOWN:
                if (hdp->hd_state == ABM)
                        hd_message (hdp, "Operator shutdown: link closed");
-               (void) pk_ctlinput (PRC_LINKDOWN, xcp);
+               (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
                hd_writeinternal (hdp, DISC, POLLON);
                hdp->hd_state = DISC_SENT;
                SET_TIMER (hdp);
                hd_writeinternal (hdp, DISC, POLLON);
                hdp->hd_state = DISC_SENT;
                SET_TIMER (hdp);
@@ -195,7 +224,7 @@ register int frametype, pf;
        register struct Hdlc_sframe *sframe;
        register struct Hdlc_uframe *uframe;
 
        register struct Hdlc_sframe *sframe;
        register struct Hdlc_uframe *uframe;
 
-       MGET (buf, M_DONTWAIT, MT_HEADER);
+       MGETHDR (buf, M_DONTWAIT, MT_HEADER);
        if (buf == 0)
                return;
        frame = mtod (buf, struct Hdlc_frame *);
        if (buf == 0)
                return;
        frame = mtod (buf, struct Hdlc_frame *);
@@ -229,6 +258,12 @@ register int frametype, pf;
                break;
 
        case DISC: 
                break;
 
        case DISC: 
+               if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) {
+                       hdp->hd_state = DISCONNECTED;
+                       (void) m_freem (buf);
+                       hd_flush (hdp->hd_ifp);
+                       return;
+               }
                frame -> control = DISC_CONTROL;
                frame -> address = ADDRESS_B;
                break;
                frame -> control = DISC_CONTROL;
                frame -> address = ADDRESS_B;
                break;
@@ -260,9 +295,8 @@ register int frametype, pf;
                uframe -> pf = pf;
 
        hd_trace (hdp, TX, frame);
                uframe -> pf = pf;
 
        hd_trace (hdp, TX, frame);
-       (*hdp -> hd_ifp -> if_output) (hdp -> hd_ifp, buf,
-               (struct sockaddr *)hdp->hd_xcp);
-
+       buf -> m_pkthdr.len = buf -> m_len;
+       (*hdp->hd_output) (hdp, buf);
 }
 
 struct mbuf *
 }
 
 struct mbuf *
@@ -300,7 +334,7 @@ struct ifnet *ifp;
        register int s;
 
        while (1) {
        register int s;
 
        while (1) {
-               s = spl6 ();            /* XXX SHOULDN'T THIS BE splimp? */
+               s = splimp ();
                IF_DEQUEUE (&ifp->if_snd, m);
                splx (s);
                if (m == 0)
                IF_DEQUEUE (&ifp->if_snd, m);
                splx (s);
                if (m == 0)