|
|
1.1 ! root 1: /* ! 2: * Copyright (c) University of British Columbia, 1984 ! 3: * Copyright (c) 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Laboratory for Computation Vision and the Computer Science Department ! 8: * of the University of British Columbia. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by the University of ! 21: * California, Berkeley and its contributors. ! 22: * 4. Neither the name of the University nor the names of its contributors ! 23: * may be used to endorse or promote products derived from this software ! 24: * without specific prior written permission. ! 25: * ! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 36: * SUCH DAMAGE. ! 37: * ! 38: * @(#)hd_subr.c 7.6 (Berkeley) 5/29/91 ! 39: */ ! 40: ! 41: #include "param.h" ! 42: #include "systm.h" ! 43: #include "mbuf.h" ! 44: #include "domain.h" ! 45: #include "socket.h" ! 46: #include "protosw.h" ! 47: #include "errno.h" ! 48: #include "time.h" ! 49: #include "kernel.h" ! 50: ! 51: #include "../net/if.h" ! 52: ! 53: #include "hdlc.h" ! 54: #include "hd_var.h" ! 55: #include "x25.h" ! 56: ! 57: hd_init () ! 58: { ! 59: ! 60: hdintrq.ifq_maxlen = IFQ_MAXLEN; ! 61: } ! 62: ! 63: hd_ctlinput (prc, addr) ! 64: struct sockaddr *addr; ! 65: { ! 66: register struct x25config *xcp = (struct x25config *)addr; ! 67: register struct hdcb *hdp; ! 68: register struct ifaddr *ifa; ! 69: struct ifnet *ifp; ! 70: caddr_t pk_newlink(); ! 71: ! 72: if (addr->sa_family != AF_CCITT) ! 73: return (EAFNOSUPPORT); ! 74: if (xcp->xc_lptype != HDLCPROTO_LAPB) ! 75: return (EPROTONOSUPPORT); ! 76: ifa = ifa_ifwithaddr(addr); ! 77: if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT || ! 78: (ifp = ifa->ifa_ifp) == 0) ! 79: panic ("hd_ctlinput"); ! 80: for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) ! 81: if (hdp->hd_ifp == ifp) ! 82: break; ! 83: ! 84: if (hdp == 0) { /* new interface */ ! 85: int error, hd_ifoutput(), hd_output(); ! 86: ! 87: /* an hdcb is now too big to fit in an mbuf */ ! 88: MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT); ! 89: if (hdp == 0) ! 90: return (ENOBUFS); ! 91: bzero((caddr_t)hdp, sizeof(*hdp)); ! 92: hdp->hd_pkp = ! 93: pk_newlink ((struct x25_ifaddr *)ifa, (caddr_t)hdp); ! 94: if (hdp -> hd_pkp == 0) { ! 95: free(hdp, M_PCB); ! 96: return (ENOBUFS); ! 97: } ! 98: hdp->hd_ifp = ifp; ! 99: hdp->hd_ifa = ifa; ! 100: hdp->hd_xcp = xcp; ! 101: hdp->hd_state = INIT; ! 102: hdp->hd_output = hd_ifoutput; ! 103: hdp->hd_next = hdcbhead; ! 104: hdcbhead = hdp; ! 105: } ! 106: ! 107: switch (prc) { ! 108: case PRC_IFUP: ! 109: if (xcp->xc_lwsize == 0 || ! 110: xcp->xc_lwsize > MAX_WINDOW_SIZE) ! 111: xcp->xc_lwsize = MAX_WINDOW_SIZE; ! 112: if (hdp->hd_state == INIT) ! 113: SET_TIMER (hdp); ! 114: break; ! 115: ! 116: case PRC_IFDOWN: ! 117: if (hdp->hd_state == ABM) ! 118: hd_message (hdp, "Operator shutdown: link closed"); ! 119: (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp); ! 120: hd_writeinternal (hdp, DISC, POLLON); ! 121: hdp->hd_state = DISC_SENT; ! 122: SET_TIMER (hdp); ! 123: } ! 124: return (0); ! 125: } ! 126: ! 127: hd_initvars (hdp) ! 128: register struct hdcb *hdp; ! 129: { ! 130: register struct mbuf *m; ! 131: register int i; ! 132: ! 133: /* Clear Transmit queue. */ ! 134: while ((m = hd_remove (&hdp->hd_txq)) != NULL) ! 135: m_freem (m); ! 136: ! 137: /* Clear Retransmit queue. */ ! 138: i = hdp->hd_lastrxnr; ! 139: while (i != hdp->hd_retxqi) { ! 140: m_freem (hdp->hd_retxq[i]); ! 141: i = (i + 1) % MODULUS; ! 142: } ! 143: hdp->hd_retxqi = 0; ! 144: ! 145: hdp->hd_vs = hdp->hd_vr = 0; ! 146: hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0; ! 147: hdp->hd_rrtimer = 0; ! 148: KILL_TIMER(hdp); ! 149: hdp->hd_retxcnt = 0; ! 150: hdp->hd_condition = 0; ! 151: } ! 152: ! 153: hd_decode (hdp, frame) ! 154: register struct hdcb *hdp; ! 155: struct Hdlc_frame *frame; ! 156: { ! 157: register int frametype = ILLEGAL; ! 158: register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame; ! 159: register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame; ! 160: register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame; ! 161: ! 162: if (iframe -> hdlc_0 == 0) { ! 163: frametype = IFRAME; ! 164: hdp->hd_iframes_in++; ! 165: } ! 166: ! 167: else if (sframe -> hdlc_01 == 1) { ! 168: /* Supervisory format. */ ! 169: switch (sframe -> s2) { ! 170: case 0: ! 171: frametype = RR; ! 172: hdp->hd_rrs_in++; ! 173: break; ! 174: ! 175: case 1: ! 176: frametype = RNR; ! 177: hdp->hd_rnrs_in++; ! 178: break; ! 179: ! 180: case 2: ! 181: frametype = REJ; ! 182: hdp->hd_rejs_in++; ! 183: } ! 184: } ! 185: else if (uframe -> hdlc_11 == 3) { ! 186: /* Unnumbered format. */ ! 187: switch (uframe -> m3) { ! 188: case 0: ! 189: frametype = DM; ! 190: break; ! 191: ! 192: case 1: ! 193: frametype = SABM; ! 194: break; ! 195: ! 196: case 2: ! 197: frametype = DISC; ! 198: break; ! 199: ! 200: case 3: ! 201: frametype = UA; ! 202: break; ! 203: ! 204: case 4: ! 205: frametype = FRMR; ! 206: hdp->hd_frmrs_in++; ! 207: } ! 208: } ! 209: return (frametype); ! 210: } ! 211: ! 212: /* ! 213: * This routine is called when the HDLC layer internally generates a ! 214: * command or response for the remote machine ( eg. RR, UA etc. ). ! 215: * Only supervisory or unnumbered frames are processed. ! 216: */ ! 217: ! 218: hd_writeinternal (hdp, frametype, pf) ! 219: register struct hdcb *hdp; ! 220: register int frametype, pf; ! 221: { ! 222: register struct mbuf *buf; ! 223: struct Hdlc_frame *frame; ! 224: register struct Hdlc_sframe *sframe; ! 225: register struct Hdlc_uframe *uframe; ! 226: ! 227: MGETHDR (buf, M_DONTWAIT, MT_HEADER); ! 228: if (buf == 0) ! 229: return; ! 230: frame = mtod (buf, struct Hdlc_frame *); ! 231: sframe = mtod (buf, struct Hdlc_sframe *); ! 232: uframe = mtod (buf, struct Hdlc_uframe *); ! 233: ! 234: /* Assume a response - address structure for DTE */ ! 235: frame -> address = ADDRESS_A; ! 236: buf -> m_len = 2; ! 237: buf -> m_act = buf -> m_next = NULL; ! 238: ! 239: switch (frametype) { ! 240: case RR: ! 241: frame -> control = RR_CONTROL; ! 242: hdp->hd_rrs_out++; ! 243: break; ! 244: ! 245: case RNR: ! 246: frame -> control = RNR_CONTROL; ! 247: hdp->hd_rnrs_out++; ! 248: break; ! 249: ! 250: case REJ: ! 251: frame -> control = REJ_CONTROL; ! 252: hdp->hd_rejs_out++; ! 253: break; ! 254: ! 255: case SABM: ! 256: frame -> control = SABM_CONTROL; ! 257: frame -> address = ADDRESS_B; ! 258: break; ! 259: ! 260: case DISC: ! 261: if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) { ! 262: hdp->hd_state = DISCONNECTED; ! 263: (void) m_freem (buf); ! 264: hd_flush (hdp->hd_ifp); ! 265: return; ! 266: } ! 267: frame -> control = DISC_CONTROL; ! 268: frame -> address = ADDRESS_B; ! 269: break; ! 270: ! 271: case DM: ! 272: frame -> control = DM_CONTROL; ! 273: break; ! 274: ! 275: case UA: ! 276: frame -> control = UA_CONTROL; ! 277: break; ! 278: ! 279: case FRMR: ! 280: frame -> control = FRMR_CONTROL; ! 281: bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3); ! 282: buf -> m_len = 5; ! 283: hdp->hd_frmrs_out++; ! 284: ! 285: } ! 286: ! 287: if (sframe -> hdlc_01 == 1) { ! 288: /* Supervisory format - RR, REJ, or RNR. */ ! 289: sframe -> nr = hdp->hd_vr; ! 290: sframe -> pf = pf; ! 291: hdp->hd_lasttxnr = hdp->hd_vr; ! 292: hdp->hd_rrtimer = 0; ! 293: } ! 294: else ! 295: uframe -> pf = pf; ! 296: ! 297: hd_trace (hdp, TX, frame); ! 298: buf -> m_pkthdr.len = buf -> m_len; ! 299: (*hdp->hd_output) (hdp, buf); ! 300: } ! 301: ! 302: struct mbuf * ! 303: hd_remove (q) ! 304: struct hdtxq *q; ! 305: { ! 306: register struct mbuf *m; ! 307: ! 308: m = q -> head; ! 309: if (m) { ! 310: if ((q -> head = m -> m_act) == NULL) ! 311: q -> tail = NULL; ! 312: m -> m_act = 0; ! 313: } ! 314: return (m); ! 315: } ! 316: ! 317: hd_append (q, m) ! 318: register struct hdtxq *q; ! 319: register struct mbuf *m; ! 320: { ! 321: ! 322: m -> m_act = NULL; ! 323: if (q -> tail == NULL) ! 324: q -> head = m; ! 325: else ! 326: q -> tail -> m_act = m; ! 327: q -> tail = m; ! 328: } ! 329: ! 330: hd_flush (ifp) ! 331: struct ifnet *ifp; ! 332: { ! 333: register struct mbuf *m; ! 334: register int s; ! 335: ! 336: while (1) { ! 337: s = splimp (); ! 338: IF_DEQUEUE (&ifp->if_snd, m); ! 339: splx (s); ! 340: if (m == 0) ! 341: break; ! 342: m_freem (m); ! 343: } ! 344: } ! 345: ! 346: hd_message (hdp, msg) ! 347: struct hdcb *hdp; ! 348: char *msg; ! 349: { ! 350: char *format_ntn (); ! 351: ! 352: if (hdcbhead -> hd_next) ! 353: printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg); ! 354: else ! 355: printf ("HDLC: %s\n", msg); ! 356: } ! 357: ! 358: #ifdef HDLCDEBUG ! 359: hd_status (hdp) ! 360: struct hdcb *hdp; ! 361: { ! 362: printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n", ! 363: hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi); ! 364: ! 365: printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n", ! 366: hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx); ! 367: } ! 368: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.