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