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