|
|
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: *
1.1.1.2 ! root 38: * from: @(#)hd_subr.c 7.6 (Berkeley) 5/29/91
! 39: * hd_subr.c,v 1.2 1993/05/20 04:12:08 cgd Exp
1.1 root 40: */
41:
42: #include "param.h"
43: #include "systm.h"
44: #include "mbuf.h"
45: #include "domain.h"
46: #include "socket.h"
47: #include "protosw.h"
48: #include "errno.h"
49: #include "time.h"
50: #include "kernel.h"
51:
52: #include "../net/if.h"
53:
54: #include "hdlc.h"
55: #include "hd_var.h"
56: #include "x25.h"
57:
58: hd_init ()
59: {
60:
61: hdintrq.ifq_maxlen = IFQ_MAXLEN;
62: }
63:
64: hd_ctlinput (prc, addr)
65: struct sockaddr *addr;
66: {
67: register struct x25config *xcp = (struct x25config *)addr;
68: register struct hdcb *hdp;
69: register struct ifaddr *ifa;
70: struct ifnet *ifp;
71: caddr_t pk_newlink();
72:
73: if (addr->sa_family != AF_CCITT)
74: return (EAFNOSUPPORT);
75: if (xcp->xc_lptype != HDLCPROTO_LAPB)
76: return (EPROTONOSUPPORT);
77: ifa = ifa_ifwithaddr(addr);
78: if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT ||
79: (ifp = ifa->ifa_ifp) == 0)
80: panic ("hd_ctlinput");
81: for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
82: if (hdp->hd_ifp == ifp)
83: break;
84:
85: if (hdp == 0) { /* new interface */
86: int error, hd_ifoutput(), hd_output();
87:
88: /* an hdcb is now too big to fit in an mbuf */
89: MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT);
90: if (hdp == 0)
91: return (ENOBUFS);
92: bzero((caddr_t)hdp, sizeof(*hdp));
93: hdp->hd_pkp =
94: pk_newlink ((struct x25_ifaddr *)ifa, (caddr_t)hdp);
95: if (hdp -> hd_pkp == 0) {
96: free(hdp, M_PCB);
97: return (ENOBUFS);
98: }
99: hdp->hd_ifp = ifp;
100: hdp->hd_ifa = ifa;
101: hdp->hd_xcp = xcp;
102: hdp->hd_state = INIT;
103: hdp->hd_output = hd_ifoutput;
104: hdp->hd_next = hdcbhead;
105: hdcbhead = hdp;
106: }
107:
108: switch (prc) {
109: case PRC_IFUP:
110: if (xcp->xc_lwsize == 0 ||
111: xcp->xc_lwsize > MAX_WINDOW_SIZE)
112: xcp->xc_lwsize = MAX_WINDOW_SIZE;
113: if (hdp->hd_state == INIT)
114: SET_TIMER (hdp);
115: break;
116:
117: case PRC_IFDOWN:
118: if (hdp->hd_state == ABM)
119: hd_message (hdp, "Operator shutdown: link closed");
120: (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
121: hd_writeinternal (hdp, DISC, POLLON);
122: hdp->hd_state = DISC_SENT;
123: SET_TIMER (hdp);
124: }
125: return (0);
126: }
127:
128: hd_initvars (hdp)
129: register struct hdcb *hdp;
130: {
131: register struct mbuf *m;
132: register int i;
133:
134: /* Clear Transmit queue. */
135: while ((m = hd_remove (&hdp->hd_txq)) != NULL)
136: m_freem (m);
137:
138: /* Clear Retransmit queue. */
139: i = hdp->hd_lastrxnr;
140: while (i != hdp->hd_retxqi) {
141: m_freem (hdp->hd_retxq[i]);
142: i = (i + 1) % MODULUS;
143: }
144: hdp->hd_retxqi = 0;
145:
146: hdp->hd_vs = hdp->hd_vr = 0;
147: hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0;
148: hdp->hd_rrtimer = 0;
149: KILL_TIMER(hdp);
150: hdp->hd_retxcnt = 0;
151: hdp->hd_condition = 0;
152: }
153:
154: hd_decode (hdp, frame)
155: register struct hdcb *hdp;
156: struct Hdlc_frame *frame;
157: {
158: register int frametype = ILLEGAL;
159: register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
160: register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame;
161: register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame;
162:
163: if (iframe -> hdlc_0 == 0) {
164: frametype = IFRAME;
165: hdp->hd_iframes_in++;
166: }
167:
168: else if (sframe -> hdlc_01 == 1) {
169: /* Supervisory format. */
170: switch (sframe -> s2) {
171: case 0:
172: frametype = RR;
173: hdp->hd_rrs_in++;
174: break;
175:
176: case 1:
177: frametype = RNR;
178: hdp->hd_rnrs_in++;
179: break;
180:
181: case 2:
182: frametype = REJ;
183: hdp->hd_rejs_in++;
184: }
185: }
186: else if (uframe -> hdlc_11 == 3) {
187: /* Unnumbered format. */
188: switch (uframe -> m3) {
189: case 0:
190: frametype = DM;
191: break;
192:
193: case 1:
194: frametype = SABM;
195: break;
196:
197: case 2:
198: frametype = DISC;
199: break;
200:
201: case 3:
202: frametype = UA;
203: break;
204:
205: case 4:
206: frametype = FRMR;
207: hdp->hd_frmrs_in++;
208: }
209: }
210: return (frametype);
211: }
212:
213: /*
214: * This routine is called when the HDLC layer internally generates a
215: * command or response for the remote machine ( eg. RR, UA etc. ).
216: * Only supervisory or unnumbered frames are processed.
217: */
218:
219: hd_writeinternal (hdp, frametype, pf)
220: register struct hdcb *hdp;
221: register int frametype, pf;
222: {
223: register struct mbuf *buf;
224: struct Hdlc_frame *frame;
225: register struct Hdlc_sframe *sframe;
226: register struct Hdlc_uframe *uframe;
227:
228: MGETHDR (buf, M_DONTWAIT, MT_HEADER);
229: if (buf == 0)
230: return;
231: frame = mtod (buf, struct Hdlc_frame *);
232: sframe = mtod (buf, struct Hdlc_sframe *);
233: uframe = mtod (buf, struct Hdlc_uframe *);
234:
235: /* Assume a response - address structure for DTE */
236: frame -> address = ADDRESS_A;
237: buf -> m_len = 2;
238: buf -> m_act = buf -> m_next = NULL;
239:
240: switch (frametype) {
241: case RR:
242: frame -> control = RR_CONTROL;
243: hdp->hd_rrs_out++;
244: break;
245:
246: case RNR:
247: frame -> control = RNR_CONTROL;
248: hdp->hd_rnrs_out++;
249: break;
250:
251: case REJ:
252: frame -> control = REJ_CONTROL;
253: hdp->hd_rejs_out++;
254: break;
255:
256: case SABM:
257: frame -> control = SABM_CONTROL;
258: frame -> address = ADDRESS_B;
259: break;
260:
261: case DISC:
262: if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) {
263: hdp->hd_state = DISCONNECTED;
264: (void) m_freem (buf);
265: hd_flush (hdp->hd_ifp);
266: return;
267: }
268: frame -> control = DISC_CONTROL;
269: frame -> address = ADDRESS_B;
270: break;
271:
272: case DM:
273: frame -> control = DM_CONTROL;
274: break;
275:
276: case UA:
277: frame -> control = UA_CONTROL;
278: break;
279:
280: case FRMR:
281: frame -> control = FRMR_CONTROL;
282: bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3);
283: buf -> m_len = 5;
284: hdp->hd_frmrs_out++;
285:
286: }
287:
288: if (sframe -> hdlc_01 == 1) {
289: /* Supervisory format - RR, REJ, or RNR. */
290: sframe -> nr = hdp->hd_vr;
291: sframe -> pf = pf;
292: hdp->hd_lasttxnr = hdp->hd_vr;
293: hdp->hd_rrtimer = 0;
294: }
295: else
296: uframe -> pf = pf;
297:
298: hd_trace (hdp, TX, frame);
299: buf -> m_pkthdr.len = buf -> m_len;
300: (*hdp->hd_output) (hdp, buf);
301: }
302:
303: struct mbuf *
304: hd_remove (q)
305: struct hdtxq *q;
306: {
307: register struct mbuf *m;
308:
309: m = q -> head;
310: if (m) {
311: if ((q -> head = m -> m_act) == NULL)
312: q -> tail = NULL;
313: m -> m_act = 0;
314: }
315: return (m);
316: }
317:
318: hd_append (q, m)
319: register struct hdtxq *q;
320: register struct mbuf *m;
321: {
322:
323: m -> m_act = NULL;
324: if (q -> tail == NULL)
325: q -> head = m;
326: else
327: q -> tail -> m_act = m;
328: q -> tail = m;
329: }
330:
331: hd_flush (ifp)
332: struct ifnet *ifp;
333: {
334: register struct mbuf *m;
335: register int s;
336:
337: while (1) {
338: s = splimp ();
339: IF_DEQUEUE (&ifp->if_snd, m);
340: splx (s);
341: if (m == 0)
342: break;
343: m_freem (m);
344: }
345: }
346:
347: hd_message (hdp, msg)
348: struct hdcb *hdp;
349: char *msg;
350: {
351: char *format_ntn ();
352:
353: if (hdcbhead -> hd_next)
354: printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg);
355: else
356: printf ("HDLC: %s\n", msg);
357: }
358:
359: #ifdef HDLCDEBUG
360: hd_status (hdp)
361: struct hdcb *hdp;
362: {
363: printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n",
364: hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi);
365:
366: printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n",
367: hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx);
368: }
369: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.