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