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