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