|
|
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.