]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i4b/layer2/i4b_tei.c
* Use sys/sys/random.h rather than a i386 specific one.
[FreeBSD/FreeBSD.git] / sys / i4b / layer2 / i4b_tei.c
1 /*
2  * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b_tei.c - tei handling procedures
28  *      -----------------------------------
29  *
30  *      $Id: i4b_tei.c,v 1.17 1999/12/13 21:25:27 hm Exp $ 
31  *
32  * $FreeBSD$
33  *
34  *      last edit-date: [Mon Dec 13 22:04:24 1999]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #ifdef __FreeBSD__
39 #include "i4bq921.h"
40 #else
41 #define NI4BQ921        1
42 #endif
43 #if NI4BQ921 > 0
44
45 #include <sys/param.h>
46
47 #if defined(__FreeBSD__)
48 #include <sys/ioccom.h>
49 #include <sys/random.h>
50 #else
51 #include <sys/ioctl.h>
52 #endif
53
54 #include <sys/kernel.h>
55 #include <sys/systm.h>
56 #include <sys/syslog.h>
57 #include <sys/mbuf.h>
58 #include <sys/socket.h>
59 #include <net/if.h>
60
61 #ifdef __FreeBSD__
62 #include <machine/i4b_debug.h>
63 #include <machine/i4b_ioctl.h>
64 #else
65 #include <i4b/i4b_debug.h>
66 #include <i4b/i4b_ioctl.h>
67 #endif
68
69 #include <i4b/include/i4b_global.h>
70 #include <i4b/include/i4b_l1l2.h>
71 #include <i4b/include/i4b_l2l3.h>
72 #include <i4b/include/i4b_isdnq931.h>
73 #include <i4b/include/i4b_mbuf.h>
74
75 #include <i4b/layer2/i4b_l2.h>
76 #include <i4b/layer2/i4b_l2fsm.h>
77
78 /*---------------------------------------------------------------------------*
79  *      handle a received TEI management frame
80  *---------------------------------------------------------------------------*/
81 void
82 i4b_tei_rxframe(int unit, struct mbuf *m)
83 {
84         l2_softc_t *l2sc = &l2_softc[unit];
85         u_char *ptr = m->m_data;
86         
87         switch(*(ptr + OFF_MT))
88         {
89                 case MT_ID_ASSIGN:
90                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
91                             (*(ptr + OFF_RIH) == l2sc->last_rih))
92                         {
93                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
94                                 l2sc->tei_valid = TEI_VALID;
95
96                                 if(l2sc->T202 == TIMER_ACTIVE)
97                                         i4b_T202_stop(l2sc);
98
99                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, l2sc->tei);
100
101                                 log(LOG_INFO, "i4b: unit %d, assigned TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
102
103                                 DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Assign - TEI = %d\n", l2sc->tei));
104
105                                 i4b_next_l2state(l2sc, EV_MDASGRQ);
106                         }
107                         break;
108                         
109                 case MT_ID_DENY:
110                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
111                             (*(ptr + OFF_RIH) == l2sc->last_rih))
112                         {
113                                 l2sc->tei_valid = TEI_INVALID;
114                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
115
116                                 if(l2sc->tei == GROUP_TEI)
117                                 {
118                                         log(LOG_WARNING, "i4b: unit %d, denied TEI, no TEI values available from exchange!\n", l2sc->unit);
119                                         DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("TEI ID Denied, No TEI values available from exchange!\n"));
120                                 }
121                                 else
122                                 {
123                                         log(LOG_WARNING, "i4b: unit %d, denied TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
124                                         DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("TEI ID Denied - TEI = %d\n", l2sc->tei));
125                                 }                                       
126                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
127                                 i4b_next_l2state(l2sc, EV_MDERRRS);
128                         }
129                         break;
130                         
131                 case MT_ID_CHK_REQ:
132                         if( (l2sc->tei_valid == TEI_VALID) &&
133                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
134                               (GROUP_TEI == GET_TEIFROMAI(*(ptr+OFF_AI))) ))
135                         {
136                                 static int lasttei = -1;
137
138                                 if(l2sc->tei != lasttei)
139                                 {
140                                         DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Check Req - TEI = %d\n", l2sc->tei));
141                                         lasttei = l2sc->tei;
142                                 }
143                                 
144                                 if(l2sc->T202 == TIMER_ACTIVE)
145                                         i4b_T202_stop(l2sc);
146                                 i4b_tei_chkresp(l2sc);
147                         }
148                         break;
149                         
150                 case MT_ID_REMOVE:
151                         if( (l2sc->tei_valid == TEI_VALID) &&
152                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
153                               (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI)))))
154                         {
155                                 l2sc->tei_valid = TEI_INVALID;
156                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
157
158                                 log(LOG_INFO, "i4b: unit %d, removed TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
159                                 DBGL2(L2_TEI_MSG, "i4b_tei_rx_frame", ("TEI ID Remove - TEI = %d\n", l2sc->tei));
160                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
161                                 i4b_next_l2state(l2sc, EV_MDREMRQ);
162                         }
163                         break;
164                         
165                 default:
166                         DBGL2(L2_TEI_ERR, "i4b_tei_rx_frame", ("UNKNOWN TEI MGMT Frame, type = 0x%x\n", *(ptr + OFF_MT)));
167                         i4b_print_frame(m->m_len, m->m_data);
168                         break;
169         }
170         i4b_Dfreembuf(m);
171 }
172
173 /*---------------------------------------------------------------------------*
174  *      allocate and fill up a TEI management frame for sending
175  *---------------------------------------------------------------------------*/
176 static struct mbuf *
177 build_tei_mgmt_frame(l2_softc_t *l2sc, unsigned char type)
178 {
179         struct mbuf *m;
180         
181         if((m = i4b_Dgetmbuf(TEI_MGMT_FRM_LEN)) == NULL)
182                 return(NULL);
183
184         m->m_data[TEIM_SAPIO] = 0xfc;   /* SAPI = 63, CR = 0, EA = 0 */
185         m->m_data[TEIM_TEIO]  = 0xff;   /* TEI = 127, EA = 1 */
186         m->m_data[TEIM_UIO]   = UI;     /* UI */
187         m->m_data[TEIM_MEIO]  = MEI;    /* MEI */
188         m->m_data[TEIM_MTO]   = type;   /* message type */
189         
190         switch(type)
191         {
192                 case MT_ID_REQEST:
193                         i4b_make_rand_ri(l2sc);
194                         m->m_data[TEIM_RILO] = l2sc->last_ril;
195                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
196                         m->m_data[TEIM_AIO] = (GROUP_TEI << 1) | 0x01;
197                         break;
198
199                 case MT_ID_CHK_RSP:
200                         i4b_make_rand_ri(l2sc);
201                         m->m_data[TEIM_RILO] = l2sc->last_ril;
202                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
203                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
204                         break;
205                         
206                 case MT_ID_VERIFY:
207                         m->m_data[TEIM_RILO] = 0;
208                         m->m_data[TEIM_RIHO] = 0;
209                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
210                         break;
211
212                 default:
213                         i4b_Dfreembuf(m);
214                         panic("build_tei_mgmt_frame: invalid type");
215                         break;
216         }
217         l2sc->stat.tx_tei++;
218         return(m);
219 }
220
221 /*---------------------------------------------------------------------------*
222  *      i4b_tei_assign - TEI assignment procedure (Q.921, 5.3.2, pp 24)
223  *      T202func and N202 _MUST_ be set prior to calling this function !
224  *---------------------------------------------------------------------------*/
225 void
226 i4b_tei_assign(l2_softc_t *l2sc)
227 {
228         struct mbuf *m;
229
230         DBGL2(L2_TEI_MSG, "i4b_tei_assign", ("tx TEI ID_Request\n"));
231         
232         m = build_tei_mgmt_frame(l2sc, MT_ID_REQEST);
233
234         if(m == NULL)
235                 panic("i4b_tei_assign: no mbuf");               
236
237         i4b_T202_start(l2sc);
238         
239         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
240 }
241
242 /*---------------------------------------------------------------------------*
243  *      i4b_tei_assign - TEI verify procedure (Q.921, 5.3.5, pp 29)
244  *      T202func and N202 _MUST_ be set prior to calling this function !
245  *---------------------------------------------------------------------------*/
246 void
247 i4b_tei_verify(l2_softc_t *l2sc)
248 {
249         struct mbuf *m;
250
251         DBGL2(L2_TEI_MSG, "i4b_tei_verify", ("tx TEI ID_Verify\n"));
252
253         m = build_tei_mgmt_frame(l2sc, MT_ID_VERIFY);
254
255         if(m == NULL)
256                 panic("i4b_tei_verify: no mbuf");               
257
258         i4b_T202_start(l2sc);
259         
260         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
261 }
262
263 /*---------------------------------------------------------------------------*
264  *      i4b_tei_chkresp - TEI check response procedure (Q.921, 5.3.5, pp 29)
265  *---------------------------------------------------------------------------*/
266 void
267 i4b_tei_chkresp(l2_softc_t *l2sc)
268 {
269         struct mbuf *m;
270         static int lasttei = 0;
271
272         if(l2sc->tei != lasttei)
273         {
274                 lasttei = l2sc->tei;
275                 DBGL2(L2_TEI_MSG, "i4b_tei_chkresp", ("tx TEI ID_Check_Response\n"));
276         }
277
278         m = build_tei_mgmt_frame(l2sc, MT_ID_CHK_RSP);
279
280         if(m == NULL)
281                 panic("i4b_tei_chkresp: no mbuf");              
282
283         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
284 }
285
286 /*---------------------------------------------------------------------------*
287  *      generate some 16 bit "random" number used for TEI mgmt Ri field
288  *---------------------------------------------------------------------------*/
289 void
290 i4b_make_rand_ri(l2_softc_t *l2sc)
291 {
292
293 #if defined(__FreeBSD__)
294
295         u_short val;
296         read_random((char *)&val, sizeof(val));
297
298 #else
299
300         register u_short val;
301         register int i;
302         static int called = 42;
303         
304         val = (l2sc->last_rih << 8) | l2sc->last_ril;
305
306         val += ++called;
307         
308         for(i=0; i < 50 ; i++, val++)
309         {
310                 val |= l2sc->unit+i;
311                 val <<= i;
312                 val ^= (time.tv_sec >> 16) ^ time.tv_usec;
313                 val <<= i;
314                 val ^= time.tv_sec ^ (time.tv_usec >> 16);
315
316                 if(val != 0 && val != 0xffff)
317                         break;
318         }
319 #endif
320         l2sc->last_rih = (val >> 8) & 0x00ff;
321         l2sc->last_ril = val & 0x00ff;
322 }
323
324 #endif /* NI4BQ921 > 0 */