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*56530Sbostic * @(#)hd_subr.c 7.7 (Berkeley) 10/11/92 1341705Ssklower */ 1441587Ssklower 15*56530Sbostic #include <sys/param.h> 16*56530Sbostic #include <sys/systm.h> 17*56530Sbostic #include <sys/mbuf.h> 18*56530Sbostic #include <sys/domain.h> 19*56530Sbostic #include <sys/socket.h> 20*56530Sbostic #include <sys/protosw.h> 21*56530Sbostic #include <sys/errno.h> 22*56530Sbostic #include <sys/time.h> 23*56530Sbostic #include <sys/kernel.h> 2441587Ssklower 25*56530Sbostic #include <net/if.h> 2641587Ssklower 27*56530Sbostic #include <netccitt/hdlc.h> 28*56530Sbostic #include <netccitt/hd_var.h> 29*56530Sbostic #include <netccitt/x25.h> 3041587Ssklower 3141587Ssklower hd_init () 3241587Ssklower { 3341587Ssklower 3441587Ssklower hdintrq.ifq_maxlen = IFQ_MAXLEN; 3541587Ssklower } 3641587Ssklower 3741587Ssklower hd_ctlinput (prc, addr) 3845296Ssklower struct sockaddr *addr; 3941587Ssklower { 4041587Ssklower register struct x25config *xcp = (struct x25config *)addr; 4141587Ssklower register struct hdcb *hdp; 4241587Ssklower register struct ifaddr *ifa; 4345296Ssklower struct ifnet *ifp; 4449927Ssklower caddr_t pk_newlink(); 4541587Ssklower 4645296Ssklower if (addr->sa_family != AF_CCITT) 4741587Ssklower return (EAFNOSUPPORT); 4841587Ssklower if (xcp->xc_lptype != HDLCPROTO_LAPB) 4941587Ssklower return (EPROTONOSUPPORT); 5045296Ssklower ifa = ifa_ifwithaddr(addr); 5145296Ssklower if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT || 5245296Ssklower (ifp = ifa->ifa_ifp) == 0) 5341587Ssklower panic ("hd_ctlinput"); 5441587Ssklower for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) 5541587Ssklower if (hdp->hd_ifp == ifp) 5641587Ssklower break; 5741587Ssklower 5841587Ssklower if (hdp == 0) { /* new interface */ 5945296Ssklower int error, hd_ifoutput(), hd_output(); 6041587Ssklower 6145296Ssklower /* an hdcb is now too big to fit in an mbuf */ 6245296Ssklower MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT); 6345296Ssklower if (hdp == 0) 6441587Ssklower return (ENOBUFS); 6545296Ssklower bzero((caddr_t)hdp, sizeof(*hdp)); 6649927Ssklower hdp->hd_pkp = 6749927Ssklower pk_newlink ((struct x25_ifaddr *)ifa, (caddr_t)hdp); 6849927Ssklower if (hdp -> hd_pkp == 0) { 6949927Ssklower free(hdp, M_PCB); 7049927Ssklower return (ENOBUFS); 7141587Ssklower } 7241587Ssklower hdp->hd_ifp = ifp; 7345296Ssklower hdp->hd_ifa = ifa; 7441587Ssklower hdp->hd_xcp = xcp; 7541587Ssklower hdp->hd_state = INIT; 7645296Ssklower hdp->hd_output = hd_ifoutput; 7749927Ssklower hdp->hd_next = hdcbhead; 7849927Ssklower hdcbhead = hdp; 7941587Ssklower } 8041587Ssklower 8141587Ssklower switch (prc) { 8241587Ssklower case PRC_IFUP: 8341587Ssklower if (xcp->xc_lwsize == 0 || 8441587Ssklower xcp->xc_lwsize > MAX_WINDOW_SIZE) 8541587Ssklower xcp->xc_lwsize = MAX_WINDOW_SIZE; 8641587Ssklower if (hdp->hd_state == INIT) 8741587Ssklower SET_TIMER (hdp); 8841587Ssklower break; 8941587Ssklower 9041587Ssklower case PRC_IFDOWN: 9141587Ssklower if (hdp->hd_state == ABM) 9241587Ssklower hd_message (hdp, "Operator shutdown: link closed"); 9349927Ssklower (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); 9441587Ssklower hd_writeinternal (hdp, DISC, POLLON); 9541587Ssklower hdp->hd_state = DISC_SENT; 9641587Ssklower SET_TIMER (hdp); 9741587Ssklower } 9841587Ssklower return (0); 9941587Ssklower } 10041587Ssklower 10141587Ssklower hd_initvars (hdp) 10241587Ssklower register struct hdcb *hdp; 10341587Ssklower { 10441587Ssklower register struct mbuf *m; 10541587Ssklower register int i; 10641587Ssklower 10741587Ssklower /* Clear Transmit queue. */ 10841587Ssklower while ((m = hd_remove (&hdp->hd_txq)) != NULL) 10941587Ssklower m_freem (m); 11041587Ssklower 11141587Ssklower /* Clear Retransmit queue. */ 11241587Ssklower i = hdp->hd_lastrxnr; 11341587Ssklower while (i != hdp->hd_retxqi) { 11441587Ssklower m_freem (hdp->hd_retxq[i]); 11541587Ssklower i = (i + 1) % MODULUS; 11641587Ssklower } 11741587Ssklower hdp->hd_retxqi = 0; 11841587Ssklower 11941587Ssklower hdp->hd_vs = hdp->hd_vr = 0; 12041587Ssklower hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0; 12141587Ssklower hdp->hd_rrtimer = 0; 12241587Ssklower KILL_TIMER(hdp); 12341587Ssklower hdp->hd_retxcnt = 0; 12441587Ssklower hdp->hd_condition = 0; 12541587Ssklower } 12641587Ssklower 12741587Ssklower hd_decode (hdp, frame) 12841587Ssklower register struct hdcb *hdp; 12941587Ssklower struct Hdlc_frame *frame; 13041587Ssklower { 13141587Ssklower register int frametype = ILLEGAL; 13241587Ssklower register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame; 13341587Ssklower register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame; 13441587Ssklower register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame; 13541587Ssklower 13641587Ssklower if (iframe -> hdlc_0 == 0) { 13741587Ssklower frametype = IFRAME; 13841587Ssklower hdp->hd_iframes_in++; 13941587Ssklower } 14041587Ssklower 14141587Ssklower else if (sframe -> hdlc_01 == 1) { 14241587Ssklower /* Supervisory format. */ 14341587Ssklower switch (sframe -> s2) { 14441587Ssklower case 0: 14541587Ssklower frametype = RR; 14641587Ssklower hdp->hd_rrs_in++; 14741587Ssklower break; 14841587Ssklower 14941587Ssklower case 1: 15041587Ssklower frametype = RNR; 15141587Ssklower hdp->hd_rnrs_in++; 15241587Ssklower break; 15341587Ssklower 15441587Ssklower case 2: 15541587Ssklower frametype = REJ; 15641587Ssklower hdp->hd_rejs_in++; 15741587Ssklower } 15841587Ssklower } 15941587Ssklower else if (uframe -> hdlc_11 == 3) { 16041587Ssklower /* Unnumbered format. */ 16141587Ssklower switch (uframe -> m3) { 16241587Ssklower case 0: 16341587Ssklower frametype = DM; 16441587Ssklower break; 16541587Ssklower 16641587Ssklower case 1: 16741587Ssklower frametype = SABM; 16841587Ssklower break; 16941587Ssklower 17041587Ssklower case 2: 17141587Ssklower frametype = DISC; 17241587Ssklower break; 17341587Ssklower 17441587Ssklower case 3: 17541587Ssklower frametype = UA; 17641587Ssklower break; 17741587Ssklower 17841587Ssklower case 4: 17941587Ssklower frametype = FRMR; 18041587Ssklower hdp->hd_frmrs_in++; 18141587Ssklower } 18241587Ssklower } 18341587Ssklower return (frametype); 18441587Ssklower } 18541587Ssklower 18641587Ssklower /* 18741587Ssklower * This routine is called when the HDLC layer internally generates a 18841587Ssklower * command or response for the remote machine ( eg. RR, UA etc. ). 18941587Ssklower * Only supervisory or unnumbered frames are processed. 19041587Ssklower */ 19141587Ssklower 19241587Ssklower hd_writeinternal (hdp, frametype, pf) 19341587Ssklower register struct hdcb *hdp; 19441587Ssklower register int frametype, pf; 19541587Ssklower { 19641587Ssklower register struct mbuf *buf; 19741587Ssklower struct Hdlc_frame *frame; 19841587Ssklower register struct Hdlc_sframe *sframe; 19941587Ssklower register struct Hdlc_uframe *uframe; 20041587Ssklower 20145296Ssklower MGETHDR (buf, M_DONTWAIT, MT_HEADER); 20241587Ssklower if (buf == 0) 20341587Ssklower return; 20441587Ssklower frame = mtod (buf, struct Hdlc_frame *); 20541587Ssklower sframe = mtod (buf, struct Hdlc_sframe *); 20641587Ssklower uframe = mtod (buf, struct Hdlc_uframe *); 20741587Ssklower 20841587Ssklower /* Assume a response - address structure for DTE */ 20941587Ssklower frame -> address = ADDRESS_A; 21041587Ssklower buf -> m_len = 2; 21141587Ssklower buf -> m_act = buf -> m_next = NULL; 21241587Ssklower 21341587Ssklower switch (frametype) { 21441587Ssklower case RR: 21541587Ssklower frame -> control = RR_CONTROL; 21641587Ssklower hdp->hd_rrs_out++; 21741587Ssklower break; 21841587Ssklower 21941587Ssklower case RNR: 22041587Ssklower frame -> control = RNR_CONTROL; 22141587Ssklower hdp->hd_rnrs_out++; 22241587Ssklower break; 22341587Ssklower 22441587Ssklower case REJ: 22541587Ssklower frame -> control = REJ_CONTROL; 22641587Ssklower hdp->hd_rejs_out++; 22741587Ssklower break; 22841587Ssklower 22941587Ssklower case SABM: 23041587Ssklower frame -> control = SABM_CONTROL; 23141587Ssklower frame -> address = ADDRESS_B; 23241587Ssklower break; 23341587Ssklower 23441587Ssklower case DISC: 23545296Ssklower if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) { 23645296Ssklower hdp->hd_state = DISCONNECTED; 23745296Ssklower (void) m_freem (buf); 23845296Ssklower hd_flush (hdp->hd_ifp); 23945296Ssklower return; 24045296Ssklower } 24141587Ssklower frame -> control = DISC_CONTROL; 24241587Ssklower frame -> address = ADDRESS_B; 24341587Ssklower break; 24441587Ssklower 24541587Ssklower case DM: 24641587Ssklower frame -> control = DM_CONTROL; 24741587Ssklower break; 24841587Ssklower 24941587Ssklower case UA: 25041587Ssklower frame -> control = UA_CONTROL; 25141587Ssklower break; 25241587Ssklower 25341587Ssklower case FRMR: 25441587Ssklower frame -> control = FRMR_CONTROL; 25541587Ssklower bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3); 25641587Ssklower buf -> m_len = 5; 25741587Ssklower hdp->hd_frmrs_out++; 25841587Ssklower 25941587Ssklower } 26041587Ssklower 26141587Ssklower if (sframe -> hdlc_01 == 1) { 26241587Ssklower /* Supervisory format - RR, REJ, or RNR. */ 26341587Ssklower sframe -> nr = hdp->hd_vr; 26441587Ssklower sframe -> pf = pf; 26541587Ssklower hdp->hd_lasttxnr = hdp->hd_vr; 26641587Ssklower hdp->hd_rrtimer = 0; 26741587Ssklower } 26841587Ssklower else 26941587Ssklower uframe -> pf = pf; 27041587Ssklower 27141587Ssklower hd_trace (hdp, TX, frame); 27245296Ssklower buf -> m_pkthdr.len = buf -> m_len; 27345296Ssklower (*hdp->hd_output) (hdp, buf); 27441587Ssklower } 27541587Ssklower 27641587Ssklower struct mbuf * 27741587Ssklower hd_remove (q) 27841587Ssklower struct hdtxq *q; 27941587Ssklower { 28041587Ssklower register struct mbuf *m; 28141587Ssklower 28241587Ssklower m = q -> head; 28341587Ssklower if (m) { 28441587Ssklower if ((q -> head = m -> m_act) == NULL) 28541587Ssklower q -> tail = NULL; 28641587Ssklower m -> m_act = 0; 28741587Ssklower } 28841587Ssklower return (m); 28941587Ssklower } 29041587Ssklower 29141587Ssklower hd_append (q, m) 29241587Ssklower register struct hdtxq *q; 29341587Ssklower register struct mbuf *m; 29441587Ssklower { 29541587Ssklower 29641587Ssklower m -> m_act = NULL; 29741587Ssklower if (q -> tail == NULL) 29841587Ssklower q -> head = m; 29941587Ssklower else 30041587Ssklower q -> tail -> m_act = m; 30141587Ssklower q -> tail = m; 30241587Ssklower } 30341587Ssklower 30441587Ssklower hd_flush (ifp) 30541587Ssklower struct ifnet *ifp; 30641587Ssklower { 30741587Ssklower register struct mbuf *m; 30841587Ssklower register int s; 30941587Ssklower 31041587Ssklower while (1) { 31145296Ssklower s = splimp (); 31241587Ssklower IF_DEQUEUE (&ifp->if_snd, m); 31341587Ssklower splx (s); 31441587Ssklower if (m == 0) 31541587Ssklower break; 31641587Ssklower m_freem (m); 31741587Ssklower } 31841587Ssklower } 31941587Ssklower 32041587Ssklower hd_message (hdp, msg) 32141587Ssklower struct hdcb *hdp; 32241587Ssklower char *msg; 32341587Ssklower { 32441587Ssklower char *format_ntn (); 32541587Ssklower 32641587Ssklower if (hdcbhead -> hd_next) 32741587Ssklower printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg); 32841587Ssklower else 32941587Ssklower printf ("HDLC: %s\n", msg); 33041587Ssklower } 33141587Ssklower 33241587Ssklower #ifdef HDLCDEBUG 33341587Ssklower hd_status (hdp) 33441587Ssklower struct hdcb *hdp; 33541587Ssklower { 33641587Ssklower printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n", 33741587Ssklower hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi); 33841587Ssklower 33941587Ssklower printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n", 34041587Ssklower hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx); 34141587Ssklower } 34241587Ssklower #endif 343