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