1*41587Ssklower /* Copyright (c) University of British Columbia, 1984 */ 2*41587Ssklower 3*41587Ssklower #include "../h/param.h" 4*41587Ssklower #include "../h/systm.h" 5*41587Ssklower #include "../h/mbuf.h" 6*41587Ssklower #include "../h/domain.h" 7*41587Ssklower #include "../h/socket.h" 8*41587Ssklower #include "../h/protosw.h" 9*41587Ssklower #include "../h/errno.h" 10*41587Ssklower #include "../h/time.h" 11*41587Ssklower #include "../h/kernel.h" 12*41587Ssklower 13*41587Ssklower #include "../net/if.h" 14*41587Ssklower 15*41587Ssklower #include "../netccitt/hdlc.h" 16*41587Ssklower #include "../netccitt/hd_var.h" 17*41587Ssklower #include "../netccitt/x25.h" 18*41587Ssklower 19*41587Ssklower hd_init () 20*41587Ssklower { 21*41587Ssklower 22*41587Ssklower hdintrq.ifq_maxlen = IFQ_MAXLEN; 23*41587Ssklower } 24*41587Ssklower 25*41587Ssklower hd_ctlinput (prc, addr) 26*41587Ssklower caddr_t addr; 27*41587Ssklower { 28*41587Ssklower register struct x25config *xcp = (struct x25config *)addr; 29*41587Ssklower register struct ifnet *ifp; 30*41587Ssklower register struct hdcb *hdp; 31*41587Ssklower register struct ifaddr *ifa; 32*41587Ssklower 33*41587Ssklower if (xcp->xc_family != AF_CCITT) 34*41587Ssklower return (EAFNOSUPPORT); 35*41587Ssklower if (xcp->xc_lptype != HDLCPROTO_LAPB) 36*41587Ssklower return (EPROTONOSUPPORT); 37*41587Ssklower for (ifa = ifa_ifwithaddr ((struct sockaddr *)xcp); ifa; ifa = ifa->ifa_next) 38*41587Ssklower if (ifa->ifa_addr.sa_family == AF_CCITT) 39*41587Ssklower break; 40*41587Ssklower if (ifa == 0 || (ifp = ifa->ifa_ifp) == 0) 41*41587Ssklower panic ("hd_ctlinput"); 42*41587Ssklower for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) 43*41587Ssklower if (hdp->hd_ifp == ifp) 44*41587Ssklower break; 45*41587Ssklower 46*41587Ssklower if (hdp == 0) { /* new interface */ 47*41587Ssklower register int error; 48*41587Ssklower register struct mbuf *m; 49*41587Ssklower 50*41587Ssklower m = m_getclr (M_DONTWAIT, MT_PCB); 51*41587Ssklower if (m == 0) 52*41587Ssklower return (ENOBUFS); 53*41587Ssklower if (error = pk_ctlinput (PRC_LINKDOWN, xcp)) { 54*41587Ssklower m_freem (m); 55*41587Ssklower return (error); 56*41587Ssklower } 57*41587Ssklower 58*41587Ssklower hdp = mtod (m, struct hdcb *); 59*41587Ssklower hdp->hd_ifp = ifp; 60*41587Ssklower hdp->hd_xcp = xcp; 61*41587Ssklower hdp->hd_next = hdcbhead; 62*41587Ssklower hdcbhead = hdp; 63*41587Ssklower hdp->hd_state = INIT; 64*41587Ssklower } 65*41587Ssklower 66*41587Ssklower switch (prc) { 67*41587Ssklower case PRC_IFUP: 68*41587Ssklower if (xcp->xc_lwsize == 0 || 69*41587Ssklower xcp->xc_lwsize > MAX_WINDOW_SIZE) 70*41587Ssklower xcp->xc_lwsize = MAX_WINDOW_SIZE; 71*41587Ssklower if (hdp->hd_state == INIT) 72*41587Ssklower SET_TIMER (hdp); 73*41587Ssklower break; 74*41587Ssklower 75*41587Ssklower case PRC_IFDOWN: 76*41587Ssklower if (hdp->hd_state == ABM) 77*41587Ssklower hd_message (hdp, "Operator shutdown: link closed"); 78*41587Ssklower (void) pk_ctlinput (PRC_LINKDOWN, xcp); 79*41587Ssklower hd_writeinternal (hdp, DISC, POLLON); 80*41587Ssklower hdp->hd_state = DISC_SENT; 81*41587Ssklower SET_TIMER (hdp); 82*41587Ssklower } 83*41587Ssklower return (0); 84*41587Ssklower } 85*41587Ssklower 86*41587Ssklower hd_initvars (hdp) 87*41587Ssklower register struct hdcb *hdp; 88*41587Ssklower { 89*41587Ssklower register struct mbuf *m; 90*41587Ssklower register int i; 91*41587Ssklower 92*41587Ssklower /* Clear Transmit queue. */ 93*41587Ssklower while ((m = hd_remove (&hdp->hd_txq)) != NULL) 94*41587Ssklower m_freem (m); 95*41587Ssklower 96*41587Ssklower /* Clear Retransmit queue. */ 97*41587Ssklower i = hdp->hd_lastrxnr; 98*41587Ssklower while (i != hdp->hd_retxqi) { 99*41587Ssklower m_freem (hdp->hd_retxq[i]); 100*41587Ssklower i = (i + 1) % MODULUS; 101*41587Ssklower } 102*41587Ssklower hdp->hd_retxqi = 0; 103*41587Ssklower 104*41587Ssklower hdp->hd_vs = hdp->hd_vr = 0; 105*41587Ssklower hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0; 106*41587Ssklower hdp->hd_rrtimer = 0; 107*41587Ssklower KILL_TIMER(hdp); 108*41587Ssklower hdp->hd_retxcnt = 0; 109*41587Ssklower hdp->hd_condition = 0; 110*41587Ssklower } 111*41587Ssklower 112*41587Ssklower hd_decode (hdp, frame) 113*41587Ssklower register struct hdcb *hdp; 114*41587Ssklower struct Hdlc_frame *frame; 115*41587Ssklower { 116*41587Ssklower register int frametype = ILLEGAL; 117*41587Ssklower register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame; 118*41587Ssklower register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame; 119*41587Ssklower register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame; 120*41587Ssklower 121*41587Ssklower if (iframe -> hdlc_0 == 0) { 122*41587Ssklower frametype = IFRAME; 123*41587Ssklower hdp->hd_iframes_in++; 124*41587Ssklower } 125*41587Ssklower 126*41587Ssklower else if (sframe -> hdlc_01 == 1) { 127*41587Ssklower /* Supervisory format. */ 128*41587Ssklower switch (sframe -> s2) { 129*41587Ssklower case 0: 130*41587Ssklower frametype = RR; 131*41587Ssklower hdp->hd_rrs_in++; 132*41587Ssklower break; 133*41587Ssklower 134*41587Ssklower case 1: 135*41587Ssklower frametype = RNR; 136*41587Ssklower hdp->hd_rnrs_in++; 137*41587Ssklower break; 138*41587Ssklower 139*41587Ssklower case 2: 140*41587Ssklower frametype = REJ; 141*41587Ssklower hdp->hd_rejs_in++; 142*41587Ssklower } 143*41587Ssklower } 144*41587Ssklower else if (uframe -> hdlc_11 == 3) { 145*41587Ssklower /* Unnumbered format. */ 146*41587Ssklower switch (uframe -> m3) { 147*41587Ssklower case 0: 148*41587Ssklower frametype = DM; 149*41587Ssklower break; 150*41587Ssklower 151*41587Ssklower case 1: 152*41587Ssklower frametype = SABM; 153*41587Ssklower break; 154*41587Ssklower 155*41587Ssklower case 2: 156*41587Ssklower frametype = DISC; 157*41587Ssklower break; 158*41587Ssklower 159*41587Ssklower case 3: 160*41587Ssklower frametype = UA; 161*41587Ssklower break; 162*41587Ssklower 163*41587Ssklower case 4: 164*41587Ssklower frametype = FRMR; 165*41587Ssklower hdp->hd_frmrs_in++; 166*41587Ssklower } 167*41587Ssklower } 168*41587Ssklower return (frametype); 169*41587Ssklower } 170*41587Ssklower 171*41587Ssklower /* 172*41587Ssklower * This routine is called when the HDLC layer internally generates a 173*41587Ssklower * command or response for the remote machine ( eg. RR, UA etc. ). 174*41587Ssklower * Only supervisory or unnumbered frames are processed. 175*41587Ssklower */ 176*41587Ssklower 177*41587Ssklower hd_writeinternal (hdp, frametype, pf) 178*41587Ssklower register struct hdcb *hdp; 179*41587Ssklower register int frametype, pf; 180*41587Ssklower { 181*41587Ssklower register struct mbuf *buf; 182*41587Ssklower struct Hdlc_frame *frame; 183*41587Ssklower register struct Hdlc_sframe *sframe; 184*41587Ssklower register struct Hdlc_uframe *uframe; 185*41587Ssklower 186*41587Ssklower MGET (buf, M_DONTWAIT, MT_HEADER); 187*41587Ssklower if (buf == 0) 188*41587Ssklower return; 189*41587Ssklower frame = mtod (buf, struct Hdlc_frame *); 190*41587Ssklower sframe = mtod (buf, struct Hdlc_sframe *); 191*41587Ssklower uframe = mtod (buf, struct Hdlc_uframe *); 192*41587Ssklower 193*41587Ssklower /* Assume a response - address structure for DTE */ 194*41587Ssklower frame -> address = ADDRESS_A; 195*41587Ssklower buf -> m_len = 2; 196*41587Ssklower buf -> m_act = buf -> m_next = NULL; 197*41587Ssklower 198*41587Ssklower switch (frametype) { 199*41587Ssklower case RR: 200*41587Ssklower frame -> control = RR_CONTROL; 201*41587Ssklower hdp->hd_rrs_out++; 202*41587Ssklower break; 203*41587Ssklower 204*41587Ssklower case RNR: 205*41587Ssklower frame -> control = RNR_CONTROL; 206*41587Ssklower hdp->hd_rnrs_out++; 207*41587Ssklower break; 208*41587Ssklower 209*41587Ssklower case REJ: 210*41587Ssklower frame -> control = REJ_CONTROL; 211*41587Ssklower hdp->hd_rejs_out++; 212*41587Ssklower break; 213*41587Ssklower 214*41587Ssklower case SABM: 215*41587Ssklower frame -> control = SABM_CONTROL; 216*41587Ssklower frame -> address = ADDRESS_B; 217*41587Ssklower break; 218*41587Ssklower 219*41587Ssklower case DISC: 220*41587Ssklower frame -> control = DISC_CONTROL; 221*41587Ssklower frame -> address = ADDRESS_B; 222*41587Ssklower break; 223*41587Ssklower 224*41587Ssklower case DM: 225*41587Ssklower frame -> control = DM_CONTROL; 226*41587Ssklower break; 227*41587Ssklower 228*41587Ssklower case UA: 229*41587Ssklower frame -> control = UA_CONTROL; 230*41587Ssklower break; 231*41587Ssklower 232*41587Ssklower case FRMR: 233*41587Ssklower frame -> control = FRMR_CONTROL; 234*41587Ssklower bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3); 235*41587Ssklower buf -> m_len = 5; 236*41587Ssklower hdp->hd_frmrs_out++; 237*41587Ssklower 238*41587Ssklower } 239*41587Ssklower 240*41587Ssklower if (sframe -> hdlc_01 == 1) { 241*41587Ssklower /* Supervisory format - RR, REJ, or RNR. */ 242*41587Ssklower sframe -> nr = hdp->hd_vr; 243*41587Ssklower sframe -> pf = pf; 244*41587Ssklower hdp->hd_lasttxnr = hdp->hd_vr; 245*41587Ssklower hdp->hd_rrtimer = 0; 246*41587Ssklower } 247*41587Ssklower else 248*41587Ssklower uframe -> pf = pf; 249*41587Ssklower 250*41587Ssklower hd_trace (hdp, TX, frame); 251*41587Ssklower (*hdp -> hd_ifp -> if_output) (hdp -> hd_ifp, buf, 252*41587Ssklower (struct sockaddr *)hdp->hd_xcp); 253*41587Ssklower 254*41587Ssklower } 255*41587Ssklower 256*41587Ssklower struct mbuf * 257*41587Ssklower hd_remove (q) 258*41587Ssklower struct hdtxq *q; 259*41587Ssklower { 260*41587Ssklower register struct mbuf *m; 261*41587Ssklower 262*41587Ssklower m = q -> head; 263*41587Ssklower if (m) { 264*41587Ssklower if ((q -> head = m -> m_act) == NULL) 265*41587Ssklower q -> tail = NULL; 266*41587Ssklower m -> m_act = 0; 267*41587Ssklower } 268*41587Ssklower return (m); 269*41587Ssklower } 270*41587Ssklower 271*41587Ssklower hd_append (q, m) 272*41587Ssklower register struct hdtxq *q; 273*41587Ssklower register struct mbuf *m; 274*41587Ssklower { 275*41587Ssklower 276*41587Ssklower m -> m_act = NULL; 277*41587Ssklower if (q -> tail == NULL) 278*41587Ssklower q -> head = m; 279*41587Ssklower else 280*41587Ssklower q -> tail -> m_act = m; 281*41587Ssklower q -> tail = m; 282*41587Ssklower } 283*41587Ssklower 284*41587Ssklower hd_flush (ifp) 285*41587Ssklower struct ifnet *ifp; 286*41587Ssklower { 287*41587Ssklower register struct mbuf *m; 288*41587Ssklower register int s; 289*41587Ssklower 290*41587Ssklower while (1) { 291*41587Ssklower s = spl6 (); /* XXX SHOULDN'T THIS BE splimp? */ 292*41587Ssklower IF_DEQUEUE (&ifp->if_snd, m); 293*41587Ssklower splx (s); 294*41587Ssklower if (m == 0) 295*41587Ssklower break; 296*41587Ssklower m_freem (m); 297*41587Ssklower } 298*41587Ssklower } 299*41587Ssklower 300*41587Ssklower hd_message (hdp, msg) 301*41587Ssklower struct hdcb *hdp; 302*41587Ssklower char *msg; 303*41587Ssklower { 304*41587Ssklower char *format_ntn (); 305*41587Ssklower 306*41587Ssklower if (hdcbhead -> hd_next) 307*41587Ssklower printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg); 308*41587Ssklower else 309*41587Ssklower printf ("HDLC: %s\n", msg); 310*41587Ssklower } 311*41587Ssklower 312*41587Ssklower #ifdef HDLCDEBUG 313*41587Ssklower hd_status (hdp) 314*41587Ssklower struct hdcb *hdp; 315*41587Ssklower { 316*41587Ssklower printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n", 317*41587Ssklower hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi); 318*41587Ssklower 319*41587Ssklower printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n", 320*41587Ssklower hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx); 321*41587Ssklower } 322*41587Ssklower #endif 323