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*57031Ssklower * @(#)hd_subr.c 7.9 (Berkeley) 12/08/92 1341705Ssklower */ 1441587Ssklower 1556530Sbostic #include <sys/param.h> 1656530Sbostic #include <sys/systm.h> 1756530Sbostic #include <sys/mbuf.h> 1856530Sbostic #include <sys/domain.h> 1956530Sbostic #include <sys/socket.h> 20*57031Ssklower #include <sys/socketvar.h> 2156530Sbostic #include <sys/protosw.h> 2256530Sbostic #include <sys/errno.h> 2356530Sbostic #include <sys/time.h> 2456530Sbostic #include <sys/kernel.h> 2541587Ssklower 2656530Sbostic #include <net/if.h> 2741587Ssklower 2856530Sbostic #include <netccitt/hdlc.h> 2956530Sbostic #include <netccitt/hd_var.h> 3056530Sbostic #include <netccitt/x25.h> 31*57031Ssklower #include <netccitt/pk_var.h> 3241587Ssklower 3341587Ssklower hd_init () 3441587Ssklower { 3541587Ssklower 3641587Ssklower hdintrq.ifq_maxlen = IFQ_MAXLEN; 3741587Ssklower } 3841587Ssklower 3941587Ssklower hd_ctlinput (prc, addr) 4045296Ssklower struct sockaddr *addr; 4141587Ssklower { 4241587Ssklower register struct x25config *xcp = (struct x25config *)addr; 4341587Ssklower register struct hdcb *hdp; 4441587Ssklower register struct ifaddr *ifa; 4545296Ssklower struct ifnet *ifp; 4649927Ssklower caddr_t pk_newlink(); 4741587Ssklower 4845296Ssklower if (addr->sa_family != AF_CCITT) 4941587Ssklower return (EAFNOSUPPORT); 5041587Ssklower if (xcp->xc_lptype != HDLCPROTO_LAPB) 5141587Ssklower return (EPROTONOSUPPORT); 5245296Ssklower ifa = ifa_ifwithaddr(addr); 5345296Ssklower if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT || 5445296Ssklower (ifp = ifa->ifa_ifp) == 0) 5541587Ssklower panic ("hd_ctlinput"); 5641587Ssklower for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) 5741587Ssklower if (hdp->hd_ifp == ifp) 5841587Ssklower break; 5941587Ssklower 6041587Ssklower if (hdp == 0) { /* new interface */ 6145296Ssklower int error, hd_ifoutput(), hd_output(); 6241587Ssklower 6345296Ssklower /* an hdcb is now too big to fit in an mbuf */ 6445296Ssklower MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT); 6545296Ssklower if (hdp == 0) 6641587Ssklower return (ENOBUFS); 6745296Ssklower bzero((caddr_t)hdp, sizeof(*hdp)); 6849927Ssklower hdp->hd_pkp = 6957020Ssklower (caddr_t) pk_newlink ((struct x25_ifaddr *) ifa, 7057020Ssklower (caddr_t) hdp); 7157020Ssklower ((struct x25_ifaddr *)ifa)->ia_pkcb = 7257020Ssklower (struct pkcb *) hdp->hd_pkp; 7349927Ssklower if (hdp -> hd_pkp == 0) { 7449927Ssklower free(hdp, M_PCB); 7549927Ssklower return (ENOBUFS); 7641587Ssklower } 7741587Ssklower hdp->hd_ifp = ifp; 7845296Ssklower hdp->hd_ifa = ifa; 7941587Ssklower hdp->hd_xcp = xcp; 8041587Ssklower hdp->hd_state = INIT; 8145296Ssklower hdp->hd_output = hd_ifoutput; 8249927Ssklower hdp->hd_next = hdcbhead; 8349927Ssklower hdcbhead = hdp; 8457020Ssklower } else if (hdp->hd_pkp == 0) { /* interface got reconfigured */ 8557020Ssklower hdp->hd_pkp = 8657020Ssklower (caddr_t) pk_newlink ((struct x25_ifaddr *) ifa, 8757020Ssklower (caddr_t) hdp); 8857020Ssklower ((struct x25_ifaddr *)ifa)->ia_pkcb = 8957020Ssklower (struct pkcb *) hdp->hd_pkp; 9057020Ssklower if (hdp -> hd_pkp == 0) { 9157020Ssklower free(hdp, M_PCB); 9257020Ssklower return (ENOBUFS); 9357020Ssklower } 9441587Ssklower } 9541587Ssklower 9641587Ssklower switch (prc) { 9741587Ssklower case PRC_IFUP: 9841587Ssklower if (xcp->xc_lwsize == 0 || 9941587Ssklower xcp->xc_lwsize > MAX_WINDOW_SIZE) 10041587Ssklower xcp->xc_lwsize = MAX_WINDOW_SIZE; 10141587Ssklower if (hdp->hd_state == INIT) 10241587Ssklower SET_TIMER (hdp); 10341587Ssklower break; 10441587Ssklower 10541587Ssklower case PRC_IFDOWN: 10641587Ssklower if (hdp->hd_state == ABM) 10741587Ssklower hd_message (hdp, "Operator shutdown: link closed"); 10849927Ssklower (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); 10957020Ssklower 11057020Ssklower /* fall thru to ... */ 11157020Ssklower 11257020Ssklower case PRC_DISCONNECT_REQUEST: 11357020Ssklower /* drop reference to pkcb --- it's dead meat */ 11457020Ssklower hdp->hd_pkp = (caddr_t) 0; 11557020Ssklower ((struct x25_ifaddr *)ifa)->ia_pkcb = (struct pkcb *) 0; 11657020Ssklower 11741587Ssklower hd_writeinternal (hdp, DISC, POLLON); 11841587Ssklower hdp->hd_state = DISC_SENT; 11941587Ssklower SET_TIMER (hdp); 12041587Ssklower } 12141587Ssklower return (0); 12241587Ssklower } 12341587Ssklower 12441587Ssklower hd_initvars (hdp) 12541587Ssklower register struct hdcb *hdp; 12641587Ssklower { 12741587Ssklower register struct mbuf *m; 12841587Ssklower register int i; 12941587Ssklower 13041587Ssklower /* Clear Transmit queue. */ 13141587Ssklower while ((m = hd_remove (&hdp->hd_txq)) != NULL) 13241587Ssklower m_freem (m); 13341587Ssklower 13441587Ssklower /* Clear Retransmit queue. */ 13541587Ssklower i = hdp->hd_lastrxnr; 13641587Ssklower while (i != hdp->hd_retxqi) { 13741587Ssklower m_freem (hdp->hd_retxq[i]); 13841587Ssklower i = (i + 1) % MODULUS; 13941587Ssklower } 14041587Ssklower hdp->hd_retxqi = 0; 14141587Ssklower 14241587Ssklower hdp->hd_vs = hdp->hd_vr = 0; 14341587Ssklower hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0; 14441587Ssklower hdp->hd_rrtimer = 0; 14541587Ssklower KILL_TIMER(hdp); 14641587Ssklower hdp->hd_retxcnt = 0; 14741587Ssklower hdp->hd_condition = 0; 14841587Ssklower } 14941587Ssklower 15041587Ssklower hd_decode (hdp, frame) 15141587Ssklower register struct hdcb *hdp; 15241587Ssklower struct Hdlc_frame *frame; 15341587Ssklower { 15441587Ssklower register int frametype = ILLEGAL; 15541587Ssklower register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame; 15641587Ssklower register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame; 15741587Ssklower register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame; 15841587Ssklower 15941587Ssklower if (iframe -> hdlc_0 == 0) { 16041587Ssklower frametype = IFRAME; 16141587Ssklower hdp->hd_iframes_in++; 16241587Ssklower } 16341587Ssklower 16441587Ssklower else if (sframe -> hdlc_01 == 1) { 16541587Ssklower /* Supervisory format. */ 16641587Ssklower switch (sframe -> s2) { 16741587Ssklower case 0: 16841587Ssklower frametype = RR; 16941587Ssklower hdp->hd_rrs_in++; 17041587Ssklower break; 17141587Ssklower 17241587Ssklower case 1: 17341587Ssklower frametype = RNR; 17441587Ssklower hdp->hd_rnrs_in++; 17541587Ssklower break; 17641587Ssklower 17741587Ssklower case 2: 17841587Ssklower frametype = REJ; 17941587Ssklower hdp->hd_rejs_in++; 18041587Ssklower } 18141587Ssklower } 18241587Ssklower else if (uframe -> hdlc_11 == 3) { 18341587Ssklower /* Unnumbered format. */ 18441587Ssklower switch (uframe -> m3) { 18541587Ssklower case 0: 18641587Ssklower frametype = DM; 18741587Ssklower break; 18841587Ssklower 18941587Ssklower case 1: 19041587Ssklower frametype = SABM; 19141587Ssklower break; 19241587Ssklower 19341587Ssklower case 2: 19441587Ssklower frametype = DISC; 19541587Ssklower break; 19641587Ssklower 19741587Ssklower case 3: 19841587Ssklower frametype = UA; 19941587Ssklower break; 20041587Ssklower 20141587Ssklower case 4: 20241587Ssklower frametype = FRMR; 20341587Ssklower hdp->hd_frmrs_in++; 20441587Ssklower } 20541587Ssklower } 20641587Ssklower return (frametype); 20741587Ssklower } 20841587Ssklower 20941587Ssklower /* 21041587Ssklower * This routine is called when the HDLC layer internally generates a 21141587Ssklower * command or response for the remote machine ( eg. RR, UA etc. ). 21241587Ssklower * Only supervisory or unnumbered frames are processed. 21341587Ssklower */ 21441587Ssklower 21541587Ssklower hd_writeinternal (hdp, frametype, pf) 21641587Ssklower register struct hdcb *hdp; 21741587Ssklower register int frametype, pf; 21841587Ssklower { 21941587Ssklower register struct mbuf *buf; 22041587Ssklower struct Hdlc_frame *frame; 22141587Ssklower register struct Hdlc_sframe *sframe; 22241587Ssklower register struct Hdlc_uframe *uframe; 22341587Ssklower 22445296Ssklower MGETHDR (buf, M_DONTWAIT, MT_HEADER); 22541587Ssklower if (buf == 0) 22641587Ssklower return; 22741587Ssklower frame = mtod (buf, struct Hdlc_frame *); 22841587Ssklower sframe = mtod (buf, struct Hdlc_sframe *); 22941587Ssklower uframe = mtod (buf, struct Hdlc_uframe *); 23041587Ssklower 23141587Ssklower /* Assume a response - address structure for DTE */ 23241587Ssklower frame -> address = ADDRESS_A; 23341587Ssklower buf -> m_len = 2; 23441587Ssklower buf -> m_act = buf -> m_next = NULL; 23541587Ssklower 23641587Ssklower switch (frametype) { 23741587Ssklower case RR: 23841587Ssklower frame -> control = RR_CONTROL; 23941587Ssklower hdp->hd_rrs_out++; 24041587Ssklower break; 24141587Ssklower 24241587Ssklower case RNR: 24341587Ssklower frame -> control = RNR_CONTROL; 24441587Ssklower hdp->hd_rnrs_out++; 24541587Ssklower break; 24641587Ssklower 24741587Ssklower case REJ: 24841587Ssklower frame -> control = REJ_CONTROL; 24941587Ssklower hdp->hd_rejs_out++; 25041587Ssklower break; 25141587Ssklower 25241587Ssklower case SABM: 25341587Ssklower frame -> control = SABM_CONTROL; 25441587Ssklower frame -> address = ADDRESS_B; 25541587Ssklower break; 25641587Ssklower 25741587Ssklower case DISC: 25845296Ssklower if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) { 25945296Ssklower hdp->hd_state = DISCONNECTED; 26045296Ssklower (void) m_freem (buf); 26145296Ssklower hd_flush (hdp->hd_ifp); 26245296Ssklower return; 26345296Ssklower } 26441587Ssklower frame -> control = DISC_CONTROL; 26541587Ssklower frame -> address = ADDRESS_B; 26641587Ssklower break; 26741587Ssklower 26841587Ssklower case DM: 26941587Ssklower frame -> control = DM_CONTROL; 27041587Ssklower break; 27141587Ssklower 27241587Ssklower case UA: 27341587Ssklower frame -> control = UA_CONTROL; 27441587Ssklower break; 27541587Ssklower 27641587Ssklower case FRMR: 27741587Ssklower frame -> control = FRMR_CONTROL; 27841587Ssklower bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3); 27941587Ssklower buf -> m_len = 5; 28041587Ssklower hdp->hd_frmrs_out++; 28141587Ssklower 28241587Ssklower } 28341587Ssklower 28441587Ssklower if (sframe -> hdlc_01 == 1) { 28541587Ssklower /* Supervisory format - RR, REJ, or RNR. */ 28641587Ssklower sframe -> nr = hdp->hd_vr; 28741587Ssklower sframe -> pf = pf; 28841587Ssklower hdp->hd_lasttxnr = hdp->hd_vr; 28941587Ssklower hdp->hd_rrtimer = 0; 29041587Ssklower } 29141587Ssklower else 29241587Ssklower uframe -> pf = pf; 29341587Ssklower 29441587Ssklower hd_trace (hdp, TX, frame); 29545296Ssklower buf -> m_pkthdr.len = buf -> m_len; 29645296Ssklower (*hdp->hd_output) (hdp, buf); 29741587Ssklower } 29841587Ssklower 29941587Ssklower struct mbuf * 30041587Ssklower hd_remove (q) 30141587Ssklower struct hdtxq *q; 30241587Ssklower { 30341587Ssklower register struct mbuf *m; 30441587Ssklower 30541587Ssklower m = q -> head; 30641587Ssklower if (m) { 30741587Ssklower if ((q -> head = m -> m_act) == NULL) 30841587Ssklower q -> tail = NULL; 30941587Ssklower m -> m_act = 0; 31041587Ssklower } 31141587Ssklower return (m); 31241587Ssklower } 31341587Ssklower 31441587Ssklower hd_append (q, m) 31541587Ssklower register struct hdtxq *q; 31641587Ssklower register struct mbuf *m; 31741587Ssklower { 31841587Ssklower 31941587Ssklower m -> m_act = NULL; 32041587Ssklower if (q -> tail == NULL) 32141587Ssklower q -> head = m; 32241587Ssklower else 32341587Ssklower q -> tail -> m_act = m; 32441587Ssklower q -> tail = m; 32541587Ssklower } 32641587Ssklower 32741587Ssklower hd_flush (ifp) 32841587Ssklower struct ifnet *ifp; 32941587Ssklower { 33041587Ssklower register struct mbuf *m; 33141587Ssklower register int s; 33241587Ssklower 33341587Ssklower while (1) { 33445296Ssklower s = splimp (); 33541587Ssklower IF_DEQUEUE (&ifp->if_snd, m); 33641587Ssklower splx (s); 33741587Ssklower if (m == 0) 33841587Ssklower break; 33941587Ssklower m_freem (m); 34041587Ssklower } 34141587Ssklower } 34241587Ssklower 34341587Ssklower hd_message (hdp, msg) 34441587Ssklower struct hdcb *hdp; 34541587Ssklower char *msg; 34641587Ssklower { 34741587Ssklower char *format_ntn (); 34841587Ssklower 34941587Ssklower if (hdcbhead -> hd_next) 35041587Ssklower printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg); 35141587Ssklower else 35241587Ssklower printf ("HDLC: %s\n", msg); 35341587Ssklower } 35441587Ssklower 35541587Ssklower #ifdef HDLCDEBUG 35641587Ssklower hd_status (hdp) 35741587Ssklower struct hdcb *hdp; 35841587Ssklower { 35941587Ssklower printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n", 36041587Ssklower hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi); 36141587Ssklower 36241587Ssklower printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n", 36341587Ssklower hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx); 36441587Ssklower } 36541587Ssklower #endif 366