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