141705Ssklower /* 241705Ssklower * Copyright (c) University of British Columbia, 1984 341705Ssklower * Copyright (c) 1990 The Regents of the University of California. 441705Ssklower * All rights reserved. 541705Ssklower * 641705Ssklower * This code is derived from software contributed to Berkeley by 741705Ssklower * the Laboratory for Computation Vision and the Computer Science Department 841705Ssklower * of the University of British Columbia. 941705Ssklower * 1041705Ssklower * %sccs.include.redist.c% 1141705Ssklower * 12*45296Ssklower * @(#)hd_subr.c 7.5 (Berkeley) 10/04/90 1341705Ssklower */ 1441587Ssklower 1545165Ssklower #include "param.h" 1645165Ssklower #include "systm.h" 1745165Ssklower #include "mbuf.h" 1845165Ssklower #include "domain.h" 1945165Ssklower #include "socket.h" 2045165Ssklower #include "protosw.h" 2145165Ssklower #include "errno.h" 2245165Ssklower #include "time.h" 2345165Ssklower #include "kernel.h" 2441587Ssklower 2541587Ssklower #include "../net/if.h" 2641587Ssklower 2745165Ssklower #include "hdlc.h" 2845165Ssklower #include "hd_var.h" 2945165Ssklower #include "x25.h" 3041587Ssklower 3141587Ssklower hd_init () 3241587Ssklower { 3341587Ssklower 3441587Ssklower hdintrq.ifq_maxlen = IFQ_MAXLEN; 3541587Ssklower } 3641587Ssklower 3741587Ssklower hd_ctlinput (prc, addr) 38*45296Ssklower struct sockaddr *addr; 3941587Ssklower { 4041587Ssklower register struct x25config *xcp = (struct x25config *)addr; 4141587Ssklower register struct hdcb *hdp; 4241587Ssklower register struct ifaddr *ifa; 43*45296Ssklower struct ifnet *ifp; 4441587Ssklower 45*45296Ssklower if (addr->sa_family != AF_CCITT) 4641587Ssklower return (EAFNOSUPPORT); 4741587Ssklower if (xcp->xc_lptype != HDLCPROTO_LAPB) 4841587Ssklower return (EPROTONOSUPPORT); 49*45296Ssklower ifa = ifa_ifwithaddr(addr); 50*45296Ssklower if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT || 51*45296Ssklower (ifp = ifa->ifa_ifp) == 0) 5241587Ssklower panic ("hd_ctlinput"); 5341587Ssklower for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) 5441587Ssklower if (hdp->hd_ifp == ifp) 5541587Ssklower break; 5641587Ssklower 5741587Ssklower if (hdp == 0) { /* new interface */ 58*45296Ssklower int error, hd_ifoutput(), hd_output(); 5941587Ssklower 60*45296Ssklower /* an hdcb is now too big to fit in an mbuf */ 61*45296Ssklower MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT); 62*45296Ssklower if (hdp == 0) 6341587Ssklower return (ENOBUFS); 64*45296Ssklower bzero((caddr_t)hdp, sizeof(*hdp)); 6541587Ssklower if (error = pk_ctlinput (PRC_LINKDOWN, xcp)) { 66*45296Ssklower free((caddr_t)hdp, M_PCB); 6741587Ssklower return (error); 6841587Ssklower } 69*45296Ssklower hdp->hd_next = hdcbhead; 70*45296Ssklower hdcbhead = hdp; 7141587Ssklower hdp->hd_ifp = ifp; 72*45296Ssklower hdp->hd_ifa = ifa; 7341587Ssklower hdp->hd_xcp = xcp; 7441587Ssklower hdp->hd_state = INIT; 75*45296Ssklower hdp->hd_output = hd_ifoutput; 76*45296Ssklower pk_ifattach((struct x25_ifaddr *)ifa, hd_output, (caddr_t)hdp); 7741587Ssklower } 7841587Ssklower 7941587Ssklower switch (prc) { 8041587Ssklower case PRC_IFUP: 8141587Ssklower if (xcp->xc_lwsize == 0 || 8241587Ssklower xcp->xc_lwsize > MAX_WINDOW_SIZE) 8341587Ssklower xcp->xc_lwsize = MAX_WINDOW_SIZE; 8441587Ssklower if (hdp->hd_state == INIT) 8541587Ssklower SET_TIMER (hdp); 8641587Ssklower break; 8741587Ssklower 8841587Ssklower case PRC_IFDOWN: 8941587Ssklower if (hdp->hd_state == ABM) 9041587Ssklower hd_message (hdp, "Operator shutdown: link closed"); 9141587Ssklower (void) pk_ctlinput (PRC_LINKDOWN, xcp); 9241587Ssklower hd_writeinternal (hdp, DISC, POLLON); 9341587Ssklower hdp->hd_state = DISC_SENT; 9441587Ssklower SET_TIMER (hdp); 9541587Ssklower } 9641587Ssklower return (0); 9741587Ssklower } 9841587Ssklower 9941587Ssklower hd_initvars (hdp) 10041587Ssklower register struct hdcb *hdp; 10141587Ssklower { 10241587Ssklower register struct mbuf *m; 10341587Ssklower register int i; 10441587Ssklower 10541587Ssklower /* Clear Transmit queue. */ 10641587Ssklower while ((m = hd_remove (&hdp->hd_txq)) != NULL) 10741587Ssklower m_freem (m); 10841587Ssklower 10941587Ssklower /* Clear Retransmit queue. */ 11041587Ssklower i = hdp->hd_lastrxnr; 11141587Ssklower while (i != hdp->hd_retxqi) { 11241587Ssklower m_freem (hdp->hd_retxq[i]); 11341587Ssklower i = (i + 1) % MODULUS; 11441587Ssklower } 11541587Ssklower hdp->hd_retxqi = 0; 11641587Ssklower 11741587Ssklower hdp->hd_vs = hdp->hd_vr = 0; 11841587Ssklower hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0; 11941587Ssklower hdp->hd_rrtimer = 0; 12041587Ssklower KILL_TIMER(hdp); 12141587Ssklower hdp->hd_retxcnt = 0; 12241587Ssklower hdp->hd_condition = 0; 12341587Ssklower } 12441587Ssklower 12541587Ssklower hd_decode (hdp, frame) 12641587Ssklower register struct hdcb *hdp; 12741587Ssklower struct Hdlc_frame *frame; 12841587Ssklower { 12941587Ssklower register int frametype = ILLEGAL; 13041587Ssklower register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame; 13141587Ssklower register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame; 13241587Ssklower register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame; 13341587Ssklower 13441587Ssklower if (iframe -> hdlc_0 == 0) { 13541587Ssklower frametype = IFRAME; 13641587Ssklower hdp->hd_iframes_in++; 13741587Ssklower } 13841587Ssklower 13941587Ssklower else if (sframe -> hdlc_01 == 1) { 14041587Ssklower /* Supervisory format. */ 14141587Ssklower switch (sframe -> s2) { 14241587Ssklower case 0: 14341587Ssklower frametype = RR; 14441587Ssklower hdp->hd_rrs_in++; 14541587Ssklower break; 14641587Ssklower 14741587Ssklower case 1: 14841587Ssklower frametype = RNR; 14941587Ssklower hdp->hd_rnrs_in++; 15041587Ssklower break; 15141587Ssklower 15241587Ssklower case 2: 15341587Ssklower frametype = REJ; 15441587Ssklower hdp->hd_rejs_in++; 15541587Ssklower } 15641587Ssklower } 15741587Ssklower else if (uframe -> hdlc_11 == 3) { 15841587Ssklower /* Unnumbered format. */ 15941587Ssklower switch (uframe -> m3) { 16041587Ssklower case 0: 16141587Ssklower frametype = DM; 16241587Ssklower break; 16341587Ssklower 16441587Ssklower case 1: 16541587Ssklower frametype = SABM; 16641587Ssklower break; 16741587Ssklower 16841587Ssklower case 2: 16941587Ssklower frametype = DISC; 17041587Ssklower break; 17141587Ssklower 17241587Ssklower case 3: 17341587Ssklower frametype = UA; 17441587Ssklower break; 17541587Ssklower 17641587Ssklower case 4: 17741587Ssklower frametype = FRMR; 17841587Ssklower hdp->hd_frmrs_in++; 17941587Ssklower } 18041587Ssklower } 18141587Ssklower return (frametype); 18241587Ssklower } 18341587Ssklower 18441587Ssklower /* 18541587Ssklower * This routine is called when the HDLC layer internally generates a 18641587Ssklower * command or response for the remote machine ( eg. RR, UA etc. ). 18741587Ssklower * Only supervisory or unnumbered frames are processed. 18841587Ssklower */ 18941587Ssklower 19041587Ssklower hd_writeinternal (hdp, frametype, pf) 19141587Ssklower register struct hdcb *hdp; 19241587Ssklower register int frametype, pf; 19341587Ssklower { 19441587Ssklower register struct mbuf *buf; 19541587Ssklower struct Hdlc_frame *frame; 19641587Ssklower register struct Hdlc_sframe *sframe; 19741587Ssklower register struct Hdlc_uframe *uframe; 19841587Ssklower 199*45296Ssklower MGETHDR (buf, M_DONTWAIT, MT_HEADER); 20041587Ssklower if (buf == 0) 20141587Ssklower return; 20241587Ssklower frame = mtod (buf, struct Hdlc_frame *); 20341587Ssklower sframe = mtod (buf, struct Hdlc_sframe *); 20441587Ssklower uframe = mtod (buf, struct Hdlc_uframe *); 20541587Ssklower 20641587Ssklower /* Assume a response - address structure for DTE */ 20741587Ssklower frame -> address = ADDRESS_A; 20841587Ssklower buf -> m_len = 2; 20941587Ssklower buf -> m_act = buf -> m_next = NULL; 21041587Ssklower 21141587Ssklower switch (frametype) { 21241587Ssklower case RR: 21341587Ssklower frame -> control = RR_CONTROL; 21441587Ssklower hdp->hd_rrs_out++; 21541587Ssklower break; 21641587Ssklower 21741587Ssklower case RNR: 21841587Ssklower frame -> control = RNR_CONTROL; 21941587Ssklower hdp->hd_rnrs_out++; 22041587Ssklower break; 22141587Ssklower 22241587Ssklower case REJ: 22341587Ssklower frame -> control = REJ_CONTROL; 22441587Ssklower hdp->hd_rejs_out++; 22541587Ssklower break; 22641587Ssklower 22741587Ssklower case SABM: 22841587Ssklower frame -> control = SABM_CONTROL; 22941587Ssklower frame -> address = ADDRESS_B; 23041587Ssklower break; 23141587Ssklower 23241587Ssklower case DISC: 233*45296Ssklower if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) { 234*45296Ssklower hdp->hd_state = DISCONNECTED; 235*45296Ssklower (void) m_freem (buf); 236*45296Ssklower hd_flush (hdp->hd_ifp); 237*45296Ssklower return; 238*45296Ssklower } 23941587Ssklower frame -> control = DISC_CONTROL; 24041587Ssklower frame -> address = ADDRESS_B; 24141587Ssklower break; 24241587Ssklower 24341587Ssklower case DM: 24441587Ssklower frame -> control = DM_CONTROL; 24541587Ssklower break; 24641587Ssklower 24741587Ssklower case UA: 24841587Ssklower frame -> control = UA_CONTROL; 24941587Ssklower break; 25041587Ssklower 25141587Ssklower case FRMR: 25241587Ssklower frame -> control = FRMR_CONTROL; 25341587Ssklower bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3); 25441587Ssklower buf -> m_len = 5; 25541587Ssklower hdp->hd_frmrs_out++; 25641587Ssklower 25741587Ssklower } 25841587Ssklower 25941587Ssklower if (sframe -> hdlc_01 == 1) { 26041587Ssklower /* Supervisory format - RR, REJ, or RNR. */ 26141587Ssklower sframe -> nr = hdp->hd_vr; 26241587Ssklower sframe -> pf = pf; 26341587Ssklower hdp->hd_lasttxnr = hdp->hd_vr; 26441587Ssklower hdp->hd_rrtimer = 0; 26541587Ssklower } 26641587Ssklower else 26741587Ssklower uframe -> pf = pf; 26841587Ssklower 26941587Ssklower hd_trace (hdp, TX, frame); 270*45296Ssklower buf -> m_pkthdr.len = buf -> m_len; 271*45296Ssklower (*hdp->hd_output) (hdp, buf); 27241587Ssklower } 27341587Ssklower 27441587Ssklower struct mbuf * 27541587Ssklower hd_remove (q) 27641587Ssklower struct hdtxq *q; 27741587Ssklower { 27841587Ssklower register struct mbuf *m; 27941587Ssklower 28041587Ssklower m = q -> head; 28141587Ssklower if (m) { 28241587Ssklower if ((q -> head = m -> m_act) == NULL) 28341587Ssklower q -> tail = NULL; 28441587Ssklower m -> m_act = 0; 28541587Ssklower } 28641587Ssklower return (m); 28741587Ssklower } 28841587Ssklower 28941587Ssklower hd_append (q, m) 29041587Ssklower register struct hdtxq *q; 29141587Ssklower register struct mbuf *m; 29241587Ssklower { 29341587Ssklower 29441587Ssklower m -> m_act = NULL; 29541587Ssklower if (q -> tail == NULL) 29641587Ssklower q -> head = m; 29741587Ssklower else 29841587Ssklower q -> tail -> m_act = m; 29941587Ssklower q -> tail = m; 30041587Ssklower } 30141587Ssklower 30241587Ssklower hd_flush (ifp) 30341587Ssklower struct ifnet *ifp; 30441587Ssklower { 30541587Ssklower register struct mbuf *m; 30641587Ssklower register int s; 30741587Ssklower 30841587Ssklower while (1) { 309*45296Ssklower s = splimp (); 31041587Ssklower IF_DEQUEUE (&ifp->if_snd, m); 31141587Ssklower splx (s); 31241587Ssklower if (m == 0) 31341587Ssklower break; 31441587Ssklower m_freem (m); 31541587Ssklower } 31641587Ssklower } 31741587Ssklower 31841587Ssklower hd_message (hdp, msg) 31941587Ssklower struct hdcb *hdp; 32041587Ssklower char *msg; 32141587Ssklower { 32241587Ssklower char *format_ntn (); 32341587Ssklower 32441587Ssklower if (hdcbhead -> hd_next) 32541587Ssklower printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg); 32641587Ssklower else 32741587Ssklower printf ("HDLC: %s\n", msg); 32841587Ssklower } 32941587Ssklower 33041587Ssklower #ifdef HDLCDEBUG 33141587Ssklower hd_status (hdp) 33241587Ssklower struct hdcb *hdp; 33341587Ssklower { 33441587Ssklower printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n", 33541587Ssklower hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi); 33641587Ssklower 33741587Ssklower printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n", 33841587Ssklower hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx); 33941587Ssklower } 34041587Ssklower #endif 341