OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [isdn_net.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* $Id: isdn_net.c,v 1.1.1.1 2001-09-10 07:44:18 simons Exp $
2
 
3
 * Linux ISDN subsystem, network interfaces and related functions (linklevel).
4
 *
5
 * Copyright 1994-1998  by Fritz Elfert (fritz@isdn4linux.de)
6
 * Copyright 1995,96    by Thinking Objects Software GmbH Wuerzburg
7
 * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2, or (at your option)
12
 * any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
 *
23
 * $Log: not supported by cvs2svn $
24
 * Revision 1.1.1.1  2001/07/02 17:58:31  simons
25
 * Initial revision
26
 *
27
 * Revision 1.48.2.28  1998/11/27 15:38:12  paul
28
 * Also huptimeout with dialmode == manual
29
 *
30
 * Revision 1.48.2.27  1998/11/05 22:11:53  fritz
31
 * Changed mail-address.
32
 *
33
 * Revision 1.48.2.26  1998/11/03 14:54:39  fritz
34
 * Applied callback-patch fur bundled RAW-IP by gvz@popocate.hamburg.pop.de
35
 *
36
 * Revision 1.48.2.25  1998/11/03 14:31:05  fritz
37
 * Reduced stack usage in various functions.
38
 * Adapted statemachine to work with certified HiSax.
39
 * Some fixes in callback handling.
40
 *
41
 * Revision 1.48.2.24  1998/10/25 22:08:22  fritz
42
 * Bugfix: Only first number was dialed.
43
 *
44
 * Revision 1.48.2.23  1998/10/25 17:42:18  fritz
45
 * Bugfix: added missing reset of connect-flag.
46
 *
47
 * Revision 1.48.2.22  1998/10/25 15:48:13  fritz
48
 * Misc bugfixes and adaptions to new HiSax
49
 *
50
 * Revision 1.48.2.21  1998/10/23 10:14:02  paul
51
 * Implementation of "dialmode" (successor of "status")
52
 * You also need current isdnctrl for this!
53
 *
54
 * Revision 1.48.2.20  1998/08/03 15:52:00  paul
55
 * various changes from 2.0.3[45] kernel sources, as suggested by
56
 * Oliver.Lauer@coburg.baynet.de
57
 *
58
 * Revision 1.48.2.19  1998/07/30 11:29:32  paul
59
 * printk message only appeared when status is off and interface is rawIP,
60
 * which is confusing for people who don't know about "isdnctrl status <if> on".
61
 *
62
 * Revision 1.48.2.18  1998/06/29 17:08:20  cal
63
 * applied small TimRu-patch by Oliver Lauer
64
 *
65
 * Revision 1.48.2.17  1998/06/26 22:00:47  keil
66
 * tx_queue_len = 5 was too small
67
 *
68
 * Revision 1.48.2.16  1998/06/09 12:24:40  cal
69
 * Changed default of local netdev flags: ISDN_NET_STOPPED is default now,
70
 * so autodial is suppressed for that device until it is switched on using
71
 * 'isdnctrl status dev-name on'.
72
 *
73
 * Revision 1.48.2.15  1998/06/07 13:47:51  fritz
74
 * ABC cleanup
75
 *
76
 * Revision 1.48.2.13  1998/05/22 10:13:07  detabc
77
 * in case of a icmp-unreach condition the tcp-keepalive-entrys
78
 * will be dropped from the internal double-link-list (only abc-extension).
79
 * send icmp unreach only if the skb->protocol == ETH_P_IP
80
 *
81
 * Revision 1.48.2.12  1998/05/21 09:23:56  detabc
82
 * speedup abc-no-dchannel-redial
83
 *
84
 * Revision 1.48.2.11  1998/05/07 19:54:53  detabc
85
 * bugfix in abc_delayed_hangup
86
 * optimize keepalive-tests for abc_rawip
87
 *
88
 * Revision 1.48.2.10  1998/05/06 08:34:04  detabc
89
 * change ICMP_HOST_UNREACH to ICMP_NET_UNREACH (only abc-ext.)
90
 * set dev->tbusy to zero in isdn_net_unreachable() (only abc-ext.)
91
 * drop all new packets and send ICMP_NET_UNREACH for
92
 * min. dialwait to max. dialwait * 6 time. (only abc-ext.)
93
 * change random-deliver of packets (small first) from all emcapsulation
94
 * to only rawip with ABC-Router-Flag enabled.
95
 *
96
 * Revision 1.48.2.9  1998/05/03 17:48:22  detabc
97
 * remove unused dev->tbusy = 1 line (only abc-extension)
98
 *
99
 * Revision 1.48.2.8  1998/04/28 15:11:55  detabc
100
 * fixed the wrong #ifndef CONFIG_ISDN_WITH_ABC define
101
 *
102
 * Revision 1.48.2.7  1998/04/26 11:24:08  detabc
103
 * add abc_delayed_hangup (only with a spezial udp-packet)
104
 * move abc-compress and -crypt from start of transmit to the
105
 * isdn_net_send_skb() function (better for TIMRU and the work is much easyer).
106
 *
107
 * added the abc_tx_queue's in the isdn_net_send_skb().
108
 * give small-packets a high priority.
109
 * transmit small packest first.
110
 * NOTE: NOTE: NOTE:
111
 * At now with the ABC-EXTENSION will be deliver the pakets in RANDOM-ORDER.
112
 * Please let me know if this a problem.
113
 *
114
 * Revision 1.48.2.6  1998/04/18 17:55:09  detabc
115
 * dropp packets if call's are disabled (only abc-extension)
116
 * add secure callback (only abc-extension)
117
 * this means: if you are the callback-out-side and the remote
118
 * dont reject the call ?????
119
 * in this case the connection is ok !!! but you pay the connection !!!!
120
 * now this will be a configerror and the connection will be dropped .
121
 * also a new call will be disabled for 4 hours.
122
 * incouming-calls are still possible.
123
 *
124
 * Revision 1.48.2.5  1998/04/16 19:24:51  keil
125
 * Fix from vger (tx max qlength)
126
 *
127
 * Revision 1.48.2.4  1998/03/20 12:17:27  detabc
128
 * merge abc-extension with timru-time-rules
129
 * christian please check my changes in the CONFIG_ISDN_TIMEOUT_RULES sources
130
 * please ! think about:
131
 * behind the function isdn_abc_net_start_xmit(), is the first one behind
132
 * the kernel-driver, the paket will be compressed an/or crypted. In this
133
 * case no information availible in the skb->data area.
134
 *
135
 * Fritz !! Please read my remarks in the funktion isdn_net_unreachable() !
136
 *
137
 * Revision 1.48.2.3  1998/03/16 09:55:51  cal
138
 * Merged in TimRu-patches. Still needs validation in conjunction with ABC-patches.
139
 *
140
 * Revision 1.48.2.2  1998/03/07 23:35:09  detabc
141
 * added the abc-extension to the linux isdn-kernel
142
 * for kernel-version 2.0.xx
143
 * DO NOT USE FOR HIGHER KERNELS-VERSIONS
144
 * all source-lines are switched with the define  CONFIG_ISDN_WITH_ABC
145
 * (make config and answer ABC-Ext. Support (Compress,TCP-Keepalive ...) with yes
146
 *
147
 * you need also a modified isdnctrl-source the switch on the
148
 * features of the abc-extension
149
 *
150
 * please use carefully. more detail will be follow.
151
 * thanks
152
 *
153
 * Revision 1.48.2.1  1997/08/21 15:56:07  fritz
154
 * Synchronized 2.0.X branch with 2.0.31-pre7
155
 *
156
 * Revision 1.48  1997/06/22 11:57:15  fritz
157
 * Added ability to adjust slave triggerlevel.
158
 *
159
 * Revision 1.47  1997/06/21 10:52:05  fritz
160
 * Removed wrong SET_SKB_FREE in isdn_net_send_skb()
161
 *
162
 * Revision 1.46  1997/06/17 13:05:24  hipp
163
 * Applied Eric's underflow-patches (slightly modified)
164
 *
165
 * Revision 1.45  1997/06/10 16:24:22  hipp
166
 * hard_header changes for syncPPP (now behaves like RAWIP)
167
 *
168
 
169
 * Revision 1.44  1997/05/27 15:17:26  fritz
170
 * Added changes for recent 2.1.x kernels:
171
 *   changed return type of isdn_close
172
 *   queue_task_* -> queue_task
173
 *   clear/set_bit -> test_and_... where apropriate.
174
 *   changed type of hard_header_cache parameter.
175
 *
176
 * Revision 1.43  1997/03/30 16:51:13  calle
177
 * changed calls to copy_from_user/copy_to_user and removed verify_area
178
 * were possible.
179
 *
180
 * Revision 1.42  1997/03/11 08:43:51  fritz
181
 * Perform a hangup if number is deleted while dialing.
182
 *
183
 * Revision 1.41  1997/03/08 08:16:31  fritz
184
 * Bugfix: Deleting a phone number during dial gave unpredictable results.
185
 *
186
 * Revision 1.40  1997/03/05 21:16:08  fritz
187
 * Fix: did not compile with 2.1.27
188
 *
189
 * Revision 1.39  1997/03/04 21:36:52  fritz
190
 * Added sending ICMP messages when no connetion is possible.
191
 *
192
 * Revision 1.38  1997/02/23 23:41:14  fritz
193
 * Bugfix: Slave interfaces have to be hung up before master.
194
 *
195
 * Revision 1.37  1997/02/11 18:32:51  fritz
196
 * Bugfix in isdn_ppp_free_mpqueue().
197
 *
198
 * Revision 1.36  1997/02/10 21:31:11  fritz
199
 * Changed setup-interface (incoming and outgoing).
200
 *
201
 * Revision 1.35  1997/02/10 20:12:45  fritz
202
 * Changed interface for reporting incoming calls.
203
 *
204
 * Revision 1.34  1997/02/03 23:15:07  fritz
205
 * Reformatted according CodingStyle.
206
 * replaced arp_find prototype by proper include.
207
 * made dev_purge_queues static.
208
 * Bugfix in bogocps calculation.
209
 * removed isdn_net_receive_callback - was never used ;-)
210
 * Misc. fixes for Kernel 2.1.X comaptibility.
211
 *
212
 * Revision 1.33  1997/01/17 01:19:25  fritz
213
 * Applied chargeint patch.
214
 *
215
 * Revision 1.32  1997/01/14 01:29:31  fritz
216
 * Bugfix: isdn_net_hangup() did not reset ISDN_NET_CONNECTED.
217
 *
218
 * Revision 1.31  1997/01/11 23:30:42  fritz
219
 * Speed up dial statemachine.
220
 *
221
 * Revision 1.30  1996/11/25 17:20:50  hipp
222
 * fixed pppbind bug in isdn_net_find_icall()
223
 *
224
 * Revision 1.29  1996/11/13 02:31:38  fritz
225
 * Minor cleanup.
226
 *
227
 * Revision 1.28  1996/10/27 20:49:06  keil
228
 * bugfix to compile without MPP
229
 *
230
 * Revision 1.27  1996/10/25 18:46:01  fritz
231
 * Another bugfix in isdn_net_autohup()
232
 *
233
 * Revision 1.26  1996/10/23 23:05:36  fritz
234
 * Bugfix: Divide by zero in isdn_net_autohup()
235
 *
236
 * Revision 1.25  1996/10/22 23:13:58  fritz
237
 * Changes for compatibility to 2.0.X and 2.1.X kernels.
238
 *
239
 * Revision 1.24  1996/10/11 13:57:40  fritz
240
 * Bugfix: Error in BogoCPS calculation.
241
 *
242
 * Revision 1.23  1996/09/23 01:58:08  fritz
243
 * Fix: With syncPPP encapsulation, discard LCP packets
244
 *      when calculating hangup timeout.
245
 *
246
 * Revision 1.22  1996/09/23 00:03:37  fritz
247
 * Fix: did not compile without CONFIG_ISDN_PPP
248
 *
249
 * Revision 1.21  1996/09/07 12:44:50  hipp
250
 * (hopefully) fixed callback problem with syncPPP
251
 * syncPPP network devices now show PPP link encap
252
 *
253
 * Revision 1.20  1996/08/29 20:06:03  fritz
254
 * Bugfix: Transmission timeout had been much to low.
255
 *
256
 * Revision 1.19  1996/08/12 16:24:32  hipp
257
 * removed some (now) obsolete functions for syncPPP in rebuild_header etc.
258
 *
259
 * Revision 1.18  1996/07/03 13:48:51  hipp
260
 * bugfix: Call dev_purge_queues() only for master device
261
 *
262
 * Revision 1.17  1996/06/25 18:37:37  fritz
263
 * Fixed return count for empty return string in isdn_net_getphones().
264
 *
265
 * Revision 1.16  1996/06/24 17:48:08  fritz
266
 * Bugfixes:
267
 *   - Did not free channel on unbinding.
268
 *   - ioctl returned wrong callback settings.
269
 *
270
 * Revision 1.15  1996/06/16 17:42:54  tsbogend
271
 * fixed problem with IP addresses on Linux/Alpha (long is 8 byte there)
272
 *
273
 * Revision 1.14  1996/06/11 14:54:08  hipp
274
 * minor bugfix in isdn_net_send_skb
275
 * changes in BSENT callback handler for syncPPP
276
 * added lp->sav_skb stuff
277
 *
278
 * Revision 1.13  1996/06/06 14:25:44  fritz
279
 * Changed loglevel of "incoming ... without OAD" message, since
280
 * with audio support this is quite normal.
281
 *
282
 * Revision 1.12  1996/06/05 02:36:45  fritz
283
 * Minor bugfixes by M. Hipp.
284
 *
285
 * Revision 1.11  1996/05/18 01:36:59  fritz
286
 * Added spelling corrections and some minor changes
287
 * to stay in sync with kernel.
288
 *
289
 * Revision 1.10  1996/05/17 03:49:01  fritz
290
 * Some cleanup.
291
 *
292
 * Revision 1.9  1996/05/06 11:34:57  hipp
293
 * fixed a few bugs
294
 *
295
 * Revision 1.8  1996/04/30 21:04:40  fritz
296
 * Test commit
297
 *
298
 * Revision 1.7  1996/04/30 11:10:42  fritz
299
 * Added Michael's ippp-bind patch.
300
 *
301
 * Revision 1.6  1996/04/30 09:34:35  fritz
302
 * Removed compatibility-macros.
303
 *
304
 * Revision 1.5  1996/04/20 16:28:38  fritz
305
 * Made more parameters of the dial statemachine user-configurable and
306
 * added hangup after dial for more reliability using callback.
307
 * Changed all io going through generic routines in isdn_common.c
308
 * Added missing call to dev_free_skb on failed dialing.
309
 * Added uihdlc encapsulation.
310
 * Fixed isdn_net_setcfg not to destroy interface-flags anymore.
311
 * Misc. typos.
312
 *
313
 * Revision 1.4  1996/02/19 15:23:38  fritz
314
 * Bugfix: Sync-PPP packets got compressed twice, when resent due to
315
 *         send-queue-full reject.
316
 *
317
 * Revision 1.3  1996/02/11 02:22:28  fritz
318
 * Changed status- receive-callbacks to use pointer-arrays for finding
319
 * a corresponding interface instead of looping over all interfaces.
320
 * Activate Auto-hangup-timer only when interface is online.
321
 * Some bugfixes in the dialing-statemachine.
322
 * Lot of bugfixes in sk_buff'ized encapsulation handling.
323
 * For speedup connection-setup after dialing, remember sk_buf that triggered
324
 * dialing.
325
 * Fixed isdn_net_log_packet according to different encapsulations.
326
 * Correct ARP-handling for ETHERNET-encapsulation.
327
 *
328
 * Revision 1.2  1996/01/22 05:05:12  fritz
329
 * Changed returncode-logic for isdn_net_start_xmit() and its
330
 * helper-functions.
331
 * Changed handling of buildheader for RAWIP and ETHERNET-encapsulation.
332
 *
333
 * Revision 1.1  1996/01/09 04:12:34  fritz
334
 * Initial revision
335
 *
336
 */
337
 
338
#include <linux/config.h>
339
#define __NO_VERSION__
340
#include <linux/module.h>
341
#include <linux/isdn.h>
342
#include <linux/if_arp.h>
343
#include <net/arp.h>
344
#include <net/icmp.h>
345
#include "isdn_common.h"
346
#include "isdn_net.h"
347
#ifdef CONFIG_ISDN_PPP
348
#include "isdn_ppp.h"
349
#endif
350
 
351
/* Prototypes */
352
 
353
int isdn_net_force_dial_lp(isdn_net_local *);
354
static int isdn_net_wildmat(char *s, char *p);
355
static int isdn_net_start_xmit(struct sk_buff *, struct device *);
356
static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
357
static void dev_purge_queues(struct device *dev);       /* move this to net/core/dev.c */
358
 
359
char *isdn_net_revision = "$Revision: 1.1.1.1 $";
360
 
361
/*
362
 * Code for raw-networking over ISDN
363
 */
364
 
365
static void
366
isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
367
{
368
        int i;
369
 
370
        if(skb != NULL) {
371
                u_short proto = ntohs(skb->protocol);
372
 
373
                printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP %s\n",
374
                           dev->name,
375
                           (reason != NULL) ? reason : "reason unknown",
376
                           (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "" );
377
 
378
                if(proto == ETH_P_IP) {
379
 
380
                        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN, 0
381
#if (LINUX_VERSION_CODE < 0x02010f)     /* 2.1.15 */
382
                                ,dev
383
#endif
384
                                );
385
                }
386
        }
387
        else {  /* dial not triggered by rawIP packet */
388
                printk(KERN_DEBUG "isdn_net: %s: %s\n",
389
                           dev->name,
390
                           (reason != NULL) ? reason : "reason unknown");
391
        }
392
 
393
        for(i = 0; i < DEV_NUMBUFFS; i++) {
394
                struct sk_buff *skb;
395
 
396
                while((skb = skb_dequeue(&dev->buffs[i]))) {
397
                                if(ntohs(skb->protocol) == ETH_P_IP) {
398
                                        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0
399
#if (LINUX_VERSION_CODE < 0x02010f)     /* 2.1.15 */
400
                                        , dev
401
#endif
402
                                        );
403
                                }
404
                                dev_kfree_skb(skb, FREE_WRITE);
405
                }
406
        }
407
}
408
 
409
static void
410
isdn_net_reset(struct device *dev)
411
{
412
        ulong flags;
413
 
414
        save_flags(flags);
415
        cli();                  /* Avoid glitch on writes to CMD regs */
416
        dev->interrupt = 0;
417
        dev->tbusy = 0;
418
        restore_flags(flags);
419
}
420
 
421
/* Open/initialize the board. */
422
static int
423
isdn_net_open(struct device *dev)
424
{
425
        int i;
426
        struct device *p;
427
 
428
        isdn_net_reset(dev);
429
        dev->start = 1;
430
        /* Fill in the MAC-level header. */
431
        for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
432
                dev->dev_addr[i] = 0xfc;
433
        memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(u32));
434
 
435
        /* If this interface has slaves, start them also */
436
 
437
        if ((p = (((isdn_net_local *) dev->priv)->slave))) {
438
                while (p) {
439
                        isdn_net_reset(p);
440
                        p->start = 1;
441
                        p = (((isdn_net_local *) p->priv)->slave);
442
                }
443
        }
444
        isdn_MOD_INC_USE_COUNT();
445
        return 0;
446
}
447
 
448
/*
449
 * Assign an ISDN-channel to a net-interface
450
 */
451
static void
452
isdn_net_bind_channel(isdn_net_local * lp, int idx)
453
{
454
        ulong flags;
455
 
456
        save_flags(flags);
457
        cli();
458
        lp->isdn_device = dev->drvmap[idx];
459
        lp->isdn_channel = dev->chanmap[idx];
460
        dev->rx_netdev[idx] = lp->netdev;
461
        dev->st_netdev[idx] = lp->netdev;
462
        restore_flags(flags);
463
}
464
 
465
static inline void
466
isdn_net_unbind_ptr_idx(int idx)
467
{
468
        if (idx != -1) {
469
                dev->rx_netdev[idx] = NULL;
470
                dev->st_netdev[idx] = NULL;
471
        }
472
}
473
 
474
static inline void
475
isdn_net_unbind_ptr(int drv, int ch)
476
{
477
        isdn_net_unbind_ptr_idx(isdn_dc2minor(drv, ch));
478
}
479
 
480
/*
481
 * unbind a net-interface (resets interface after an error)
482
 */
483
static void
484
isdn_net_unbind_channel(isdn_net_local * lp)
485
{
486
        ulong flags;
487
 
488
        save_flags(flags);
489
        cli();
490
        if (lp->first_skb) {
491
                dev_kfree_skb(lp->first_skb, FREE_WRITE);
492
                lp->first_skb = NULL;
493
        }
494
        if (lp->sav_skb) {
495
                dev_kfree_skb(lp->sav_skb, FREE_WRITE);
496
                lp->sav_skb = NULL;
497
        }
498
        if (!lp->master)        /* purge only for master device */
499
                dev_purge_queues(&lp->netdev->dev);
500
        lp->dialstate = 0;
501
        if (lp->isdn_device != -1 && lp->isdn_device != -1) {
502
                isdn_net_unbind_ptr(lp->isdn_device, lp->isdn_channel);
503
                isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
504
        }
505
        lp->flags &= ~ISDN_NET_CONNECTED;
506
        lp->isdn_device = -1;
507
        lp->isdn_channel = -1;
508
 
509
        restore_flags(flags);
510
}
511
 
512
/*
513
 * Perform auto-hangup and cps-calculation for net-interfaces.
514
 *
515
 * auto-hangup:
516
 * Increment idle-counter (this counter is reset on any incoming or
517
 * outgoing packet), if counter exceeds configured limit either do a
518
 * hangup immediately or - if configured - wait until just before the next
519
 * charge-info.
520
 *
521
 * cps-calculation (needed for dynamic channel-bundling):
522
 * Since this function is called every second, simply reset the
523
 * byte-counter of the interface after copying it to the cps-variable.
524
 */
525
unsigned long last_jiffies = -HZ;
526
 
527
void
528
isdn_net_autohup()
529
{
530
        isdn_net_dev *p = dev->netdev;
531
        int anymore;
532
 
533
        anymore = 0;
534
        while (p) {
535
                isdn_net_local *l = (isdn_net_local *) & (p->local);
536
                if ((jiffies - last_jiffies) == 0)
537
                        l->cps = l->transcount;
538
                else
539
                        l->cps = (l->transcount * HZ) / (jiffies - last_jiffies);
540
                l->transcount = 0;
541
                if (dev->net_verbose > 3)
542
                        printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
543
                if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
544
                        anymore = 1;
545
                        l->huptimer++;
546
                        /*
547
                         * if there is some dialmode where timeout-hangup
548
                         * should _not_ be done, check for that here and
549
                         * 35 lines below (ifdef CONFIG_ISDN_BUDGET)
550
                         * eg: (ISDN_NET_DIALMODE(*l) != ISDN_NET_DM_NOTIMEOUT)
551
                         */
552
                        if ((l->onhtime) &&
553
                            (l->huptimer > l->onhtime))
554
                                if (l->hupflags & ISDN_MANCHARGE &&
555
                                    l->hupflags & ISDN_CHARGEHUP) {
556
                                        while (jiffies - l->chargetime > l->chargeint)
557
                                                l->chargetime += l->chargeint;
558
                                        if (jiffies - l->chargetime >= l->chargeint - 2 * HZ)
559
                                                if (l->outgoing || l->hupflags & ISDN_INHUP)
560
                                                        isdn_net_hangup(&p->dev);
561
                                } else if (l->outgoing) {
562
                                        if (l->hupflags & ISDN_CHARGEHUP) {
563
                                                if (l->hupflags & ISDN_WAITCHARGE) {
564
                                                        printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n",
565
                                                               l->name, l->hupflags);
566
                                                        isdn_net_hangup(&p->dev);
567
                                                } else if (jiffies - l->chargetime > l->chargeint) {
568
                                                        printk(KERN_DEBUG
569
                                                               "isdn_net: %s: chtime = %d, chint = %d\n",
570
                                                               l->name, l->chargetime, l->chargeint);
571
                                                        isdn_net_hangup(&p->dev);
572
                                                }
573
                                        } else
574
                                                isdn_net_hangup(&p->dev);
575
                                } else if (l->hupflags & ISDN_INHUP)
576
                                        isdn_net_hangup(&p->dev);
577
 
578
 
579
                        if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(p->local) == ISDN_NET_DM_OFF)) {
580
                                isdn_net_hangup(&p->dev);
581
                                break;
582
                        }
583
                }
584
                p = (isdn_net_dev *) p->next;
585
        }
586
        last_jiffies = jiffies;
587
        isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
588
}
589
 
590
/*
591
 * Handle status-messages from ISDN-interfacecard.
592
 * This function is called from within the main-status-dispatcher
593
 * isdn_status_callback, which itself is called from the low-level driver.
594
 * Return: 1 = Event handled, 0 = not for us or unknown Event.
595
 */
596
int
597
isdn_net_stat_callback(int idx, isdn_ctrl *c)
598
{
599
        isdn_net_dev *p = dev->st_netdev[idx];
600
 
601
        if (p) {
602
                isdn_net_local *lp = &(p->local);
603
                int cmd = c->command;
604
 
605
                switch (cmd) {
606
                        case ISDN_STAT_BSENT:
607
                                /* A packet has successfully been sent out */
608
                                if ((lp->flags & ISDN_NET_CONNECTED) &&
609
                                    (!lp->dialstate)) {
610
                                        lp->stats.tx_packets++;
611
                                        if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->sav_skb) {
612
                                                struct device *mdev;
613
                                                if (lp->master)
614
                                                        mdev = lp->master;
615
                                                else
616
                                                        mdev = &lp->netdev->dev;
617
                                                if (!isdn_net_send_skb(mdev, lp, lp->sav_skb)) {
618
                                                        lp->sav_skb = NULL;
619
                                                        mark_bh(NET_BH);
620
                                                } else {
621
                                                        return 1;
622
                                                }
623
                                        }
624
                                        if (test_and_clear_bit(0, (void *) &(p->dev.tbusy)))
625
                                                mark_bh(NET_BH);
626
                                }
627
                                return 1;
628
                        case ISDN_STAT_DCONN:
629
                                /* D-Channel is up */
630
                                switch (lp->dialstate) {
631
                                        case 4:
632
                                        case 7:
633
                                        case 8:
634
                                                lp->dialstate++;
635
                                                return 1;
636
                                        case 12:
637
                                        case 13:
638
                                                lp->dialstate = 5;
639
                                                return 1;
640
                                }
641
                                break;
642
                        case ISDN_STAT_DHUP:
643
                                /* Either D-Channel-hangup or error during dialout */
644
                                if (lp->flags & ISDN_NET_CONNECTED) {
645
                                        printk(KERN_INFO "%s: remote %s (%d)\n", lp->name,
646
                                                lp->dialstate?"abort":"hangup", lp->dialstate);
647
                                        printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
648
                                                lp->charge);
649
printk(KERN_DEBUG "idx=%d drv=%d ch=%d\n",idx, lp->isdn_device, lp->isdn_channel);
650
                                        if (!lp->dialstate) {
651
                                                isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
652
#ifdef CONFIG_ISDN_PPP
653
                                                isdn_ppp_free(lp);
654
#endif
655
                                                isdn_net_unbind_channel(lp);
656
                                        } else {
657
                                                switch (lp->dialstate) {
658
                                                        case 4:
659
                                                        case 5:
660
                                                        case 6:
661
                                                        case 7:
662
                                                        case 8:
663
                                                        case 9:
664
                                                                lp->dialstate = 3;
665
                                                                break;
666
                                                        case 11:
667
                                                                break;
668
                                                        case 12:
669
                                                                {
670
                                                                        isdn_ctrl cmd;
671
                                                                        printk(KERN_INFO "%s: got reject, waiting for callback ...\n", p->local.name);
672
 
673
                                                                        p->local.dtimer = 0;
674
                                                                        p->local.dialstate = 13;
675
                                                                        cmd.driver = p->local.isdn_device;
676
                                                                        cmd.command = ISDN_CMD_HANGUP;
677
                                                                        cmd.arg = p->local.isdn_channel;
678
                                                                        isdn_command(&cmd);
679
                                                                        isdn_all_eaz(p->local.isdn_device, p->local.isdn_channel);
680
                                                                }
681
                                                                /* Fall through */
682
                                                        case 13:
683
                                                                break;
684
                                                }
685
                                        }
686
                                        return 1;
687
                                }
688
                                break;
689
                        case ISDN_STAT_BCONN:
690
                                /* B-Channel is up */
691
                                switch (lp->dialstate) {
692
                                        case 5:
693
                                        case 6:
694
                                        case 7:
695
                                        case 8:
696
                                        case 9:
697
                                        case 10:
698
                                        case 12:
699
                                                if (lp->dialstate <= 6) {
700
                                                        dev->usage[idx] |= ISDN_USAGE_OUTGOING;
701
                                                        isdn_info_update();
702
                                                } else
703
                                                        dev->rx_netdev[idx] = p;
704
                                                lp->dialstate = 0;
705
                                                isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
706
                                                printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
707
                                                /* If first Chargeinfo comes before B-Channel connect,
708
                                                 * we correct the timestamp here.
709
                                                 */
710
                                                lp->chargetime = jiffies;
711
                                                printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
712
                                                lp->name, lp->chargetime);
713
                                                /* Immediately send first skb to speed up arp */
714
#ifdef CONFIG_ISDN_PPP
715
                                                if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
716
                                                        isdn_ppp_wakeup_daemon(lp);
717
#endif
718
                                                if (lp->first_skb) {
719
                                                        if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
720
                                                                lp->first_skb = NULL;
721
                                                }
722
                                                return 1;
723
                                }
724
                                break;
725
                        case ISDN_STAT_NODCH:
726
                                /* No D-Channel avail. */
727
                                if (lp->dialstate == 4) {
728
                                        lp->dialstate--;
729
                                        return 1;
730
                                }
731
                                break;
732
                        case ISDN_STAT_CINF:
733
                                /* Charge-info from TelCo. Calculate interval between
734
                                 * charge-infos and set timestamp for last info for
735
                                 * usage by isdn_net_autohup()
736
                                 */
737
                                lp->charge++;
738
                                if (lp->hupflags & ISDN_HAVECHARGE) {
739
                                        lp->hupflags &= ~ISDN_WAITCHARGE;
740
                                        lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
741
                                }
742
                                if (lp->hupflags & ISDN_WAITCHARGE)
743
                                        lp->hupflags |= ISDN_HAVECHARGE;
744
                                lp->chargetime = jiffies;
745
                                printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
746
                                       lp->name, lp->chargetime);
747
                                return 1;
748
                }
749
        }
750
        return 0;
751
}
752
 
753
/*
754
 * Check, if a number contains wildcard-characters, in which case it
755
 * is for incoming purposes only.
756
 */
757
static int
758
isdn_net_checkwild(char *num)
759
{
760
        return ((strchr(num, '?')) ||
761
                (strchr(num, '*')) ||
762
                (strchr(num, '[')) ||
763
                (strchr(num, ']')) ||
764
                (strchr(num, '^')));
765
}
766
 
767
/*
768
 * Perform dialout for net-interfaces and timeout-handling for
769
 * D-Channel-up and B-Channel-up Messages.
770
 * This function is initially called from within isdn_net_start_xmit() or
771
 * or isdn_net_find_icall() after initializing the dialstate for an
772
 * interface. If further calls are needed, the function schedules itself
773
 * for a timer-callback via isdn_timer_function().
774
 * The dialstate is also affected by incoming status-messages from
775
 * the ISDN-Channel which are handled in isdn_net_stat_callback() above.
776
 */
777
void
778
isdn_net_dial(void)
779
{
780
        isdn_net_dev *p = dev->netdev;
781
        int anymore = 0;
782
        int i;
783
        int flags;
784
        isdn_ctrl cmd;
785
 
786
        while (p) {
787
#ifdef ISDN_DEBUG_NET_DIAL
788
                if (p->local.dialstate)
789
                        printk(KERN_DEBUG "%s: dialstate=%d\n", p->local.name, p->local.dialstate);
790
#endif
791
 
792
                switch (p->local.dialstate) {
793
                        case 0:
794
                                /* Nothing to do for this interface */
795
                                break;
796
                        case 1:
797
                                /* Initiate dialout. Set phone-number-pointer to first number
798
                                 * of interface.
799
                                 */
800
                                save_flags(flags);
801
                                cli();
802
                                p->local.dial = p->local.phone[1];
803
                                restore_flags(flags);
804
                                if (!p->local.dial) {
805
                                        printk(KERN_WARNING "%s: phone number deleted?\n",
806
                                               p->local.name);
807
                                        isdn_net_hangup(&p->dev);
808
                                        break;
809
                                }
810
                                anymore = 1;
811
 
812
                                if(p->local.dialtimeout > 0)
813
                                        if(p->local.dialstarted == 0 || jiffies > (p->local.dialstarted + p->local.dialtimeout + p->local.dialwait)) {
814
                                                p->local.dialstarted = jiffies;
815
                                                p->local.dialwait_timer = 0;
816
                                        }
817
 
818
                                p->local.dialstate++;
819
                                /* Fall through */
820
                        case 2:
821
                                /* Prepare dialing. Clear EAZ, then set EAZ. */
822
                                cmd.driver = p->local.isdn_device;
823
                                cmd.arg = p->local.isdn_channel;
824
                                cmd.command = ISDN_CMD_CLREAZ;
825
                                isdn_command(&cmd);
826
                                sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(p->local.msn, cmd.driver));
827
                                cmd.command = ISDN_CMD_SETEAZ;
828
                                isdn_command(&cmd);
829
                                p->local.dialretry = 0;
830
                                anymore = 1;
831
                                p->local.dialstate++;
832
                                /* Fall through */
833
                        case 3:
834
                                /* Setup interface, dial current phone-number, switch to next number.
835
                                 * If list of phone-numbers is exhausted, increment
836
                                 * retry-counter.
837
                                 */
838
                                if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(p->local) == ISDN_NET_DM_OFF)) {
839
                                        char *s;
840
                                        if (dev->global_flags & ISDN_GLOBAL_STOPPED)
841
                                                s = "dial suppressed: isdn system stopped";
842
                                        else
843
                                                s = "dial suppressed: dialmode `off'";
844
                                        isdn_net_unreachable(&p->dev, p->local.first_skb, s);
845
                                        isdn_net_hangup(&p->dev);
846
                                        break;
847
                                }
848
                                cmd.driver = p->local.isdn_device;
849
                                cmd.command = ISDN_CMD_SETL2;
850
                                cmd.arg = p->local.isdn_channel + (p->local.l2_proto << 8);
851
                                isdn_command(&cmd);
852
                                cmd.driver = p->local.isdn_device;
853
                                cmd.command = ISDN_CMD_SETL3;
854
                                cmd.arg = p->local.isdn_channel + (p->local.l3_proto << 8);
855
                                isdn_command(&cmd);
856
                                cmd.driver = p->local.isdn_device;
857
                                cmd.arg = p->local.isdn_channel;
858
                                save_flags(flags);
859
                                cli();
860
                                if (!p->local.dial) {
861
                                        restore_flags(flags);
862
                                        printk(KERN_WARNING "%s: phone number deleted?\n",
863
                                               p->local.name);
864
                                        isdn_net_hangup(&p->dev);
865
                                        break;
866
                                }
867
                                if (!strcmp(p->local.dial->num, "LEASED")) {
868
                                        restore_flags(flags);
869
                                        p->local.dialstate = 4;
870
                                        printk(KERN_INFO "%s: Open leased line ...\n", p->local.name);
871
                                } else {
872
                                        if(p->local.dialtimeout > 0)
873
                                                if(jiffies > (p->local.dialstarted + p->local.dialtimeout)) {
874
                                                        restore_flags(flags);
875
                                                        p->local.dialwait_timer = jiffies + p->local.dialwait;
876
                                                        p->local.dialstarted = 0;
877
                                                        isdn_net_unreachable(&p->dev, p->local.first_skb, "dial: timed out");
878
                                                        isdn_net_hangup(&p->dev);
879
                                                        break;
880
                                                }
881
 
882
                                        sprintf(cmd.parm.setup.phone, "%s", p->local.dial->num);
883
                                        /*
884
                                         * Switch to next number or back to start if at end of list.
885
                                         */
886
                                        if (!(p->local.dial = (isdn_net_phone *) p->local.dial->next)) {
887
                                                p->local.dial = p->local.phone[1];
888
                                                p->local.dialretry++;
889
 
890
                                                if (p->local.dialretry > p->local.dialmax) {
891
                                                        restore_flags(flags);
892
                                                        if (p->local.dialtimeout == 0) {
893
                                                                p->local.dialwait_timer = jiffies + p->local.dialwait;
894
                                                                p->local.dialstarted = 0;
895
                                                                isdn_net_unreachable(&p->dev, p->local.first_skb, "dial: tried all numbers dialmax times");
896
                                                        }
897
                                                        isdn_net_hangup(&p->dev);
898
                                                        break;
899
                                                }
900
                                        }
901
                                        restore_flags(flags);
902
                                        cmd.command = ISDN_CMD_DIAL;
903
                                        cmd.parm.setup.si1 = 7;
904
                                        cmd.parm.setup.si2 = 0;
905
                                        sprintf(cmd.parm.setup.eazmsn, "%s",
906
                                                isdn_map_eaz2msn(p->local.msn, cmd.driver));
907
                                        i = isdn_dc2minor(p->local.isdn_device, p->local.isdn_channel);
908
                                        if (i >= 0) {
909
                                                strcpy(dev->num[i], cmd.parm.setup.phone);
910
                                                isdn_info_update();
911
                                        }
912
                                        printk(KERN_INFO "%s: dialing %d %s...\n", p->local.name,
913
                                               p->local.dialretry, cmd.parm.setup.phone);
914
                                        p->local.dtimer = 0;
915
#ifdef ISDN_DEBUG_NET_DIAL
916
                                        printk(KERN_DEBUG "dial: d=%d c=%d\n", p->local.isdn_device,
917
                                               p->local.isdn_channel);
918
#endif
919
                                        cmd.driver = p->local.isdn_device;
920
                                        isdn_command(&cmd);
921
                                }
922
                                p->local.huptimer = 0;
923
                                p->local.outgoing = 1;
924
                                if (p->local.chargeint) {
925
                                        p->local.hupflags |= ISDN_HAVECHARGE;
926
                                        p->local.hupflags &= ~ISDN_WAITCHARGE;
927
                                } else {
928
                                        p->local.hupflags |= ISDN_WAITCHARGE;
929
                                        p->local.hupflags &= ~ISDN_HAVECHARGE;
930
                                }
931
                                anymore = 1;
932
                                if (p->local.flags & ISDN_NET_CBOUT) {
933
                                        p->local.dialstate = (p->local.cbdelay) ? 12 : 13;
934
                                } else
935
                                        p->local.dialstate = 4;
936
                                break;
937
                        case 4:
938
                        case 13:
939
                                /* Wait for D-Channel-connect.
940
                                 * If timeout, switch back to state 3.
941
                                 * Dialmax-handling moved to state 3.
942
                                 */
943
                                if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT10)
944
                                        p->local.dialstate = 3;
945
                                anymore = 1;
946
                                break;
947
                        case 5:
948
                                /* Got D-Channel-Connect, send B-Channel-request */
949
                                cmd.driver = p->local.isdn_device;
950
                                cmd.arg = p->local.isdn_channel;
951
                                cmd.command = ISDN_CMD_ACCEPTB;
952
                                anymore = 1;
953
                                p->local.dtimer = 0;
954
                                p->local.dialstate++;
955
                                isdn_command(&cmd);
956
                                break;
957
                        case 6:
958
                                /* Wait for B- or D-Channel-connect. If timeout,
959
                                 * switch back to state 3.
960
                                 * Dialmax-handling moved to state 3.
961
                                 */
962
#ifdef ISDN_DEBUG_NET_DIAL
963
                                printk(KERN_DEBUG "dialtimer2: %d\n", p->local.dtimer);
964
#endif
965
                                if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT10)
966
                                        p->local.dialstate = 3;
967
                                anymore = 1;
968
                                break;
969
                        case 7:
970
                                /* Got incoming Call, setup L2 and L3 protocols,
971
                                 * then wait for D-Channel-connect
972
                                 */
973
#ifdef ISDN_DEBUG_NET_DIAL
974
                                printk(KERN_DEBUG "dialtimer4: %d\n", p->local.dtimer);
975
#endif
976
                                cmd.driver = p->local.isdn_device;
977
                                cmd.command = ISDN_CMD_SETL2;
978
                                cmd.arg = p->local.isdn_channel + (p->local.l2_proto << 8);
979
                                isdn_command(&cmd);
980
                                cmd.driver = p->local.isdn_device;
981
                                cmd.command = ISDN_CMD_SETL3;
982
                                cmd.arg = p->local.isdn_channel + (p->local.l3_proto << 8);
983
                                isdn_command(&cmd);
984
 
985
                                if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT15)
986
                                        isdn_net_hangup(&p->dev);
987
                                else {
988
                                        anymore = 1;
989
                                        p->local.dialstate++;
990
                                }
991
                                break;
992
                        case 9:
993
                                /* Got incoming D-Channel-Connect, send B-Channel-request */
994
                                cmd.driver = p->local.isdn_device;
995
                                cmd.arg = p->local.isdn_channel;
996
                                cmd.command = ISDN_CMD_ACCEPTB;
997
                                isdn_command(&cmd);
998
                                anymore = 1;
999
                                p->local.dtimer = 0;
1000
                                p->local.dialstate++;
1001
                                break;
1002
                        case 8:
1003
                        case 10:
1004
                                /*  Wait for B- or D-channel-connect */
1005
#ifdef ISDN_DEBUG_NET_DIAL
1006
                                printk(KERN_DEBUG "dialtimer4: %d\n", p->local.dtimer);
1007
#endif
1008
                                if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT60)
1009
                                        isdn_net_hangup(&p->dev);
1010
                                else
1011
                                        anymore = 1;
1012
                                break;
1013
                        case 11:
1014
                                /* Callback Delay */
1015
                                if (p->local.dtimer++ > p->local.cbdelay)
1016
                                        p->local.dialstate = 1;
1017
                                anymore = 1;
1018
                                break;
1019
                        case 12:
1020
                                /* Remote does callback. Hangup after cbdelay, then wait for incoming
1021
                                 * call (in state 13).
1022
                                 */
1023
                                if (p->local.dtimer++ > p->local.cbdelay)
1024
                                {
1025
                                        printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->local.name);
1026
                                        p->local.dtimer = 0;
1027
                                        p->local.dialstate = 13;
1028
                                        cmd.driver = p->local.isdn_device;
1029
                                        cmd.command = ISDN_CMD_HANGUP;
1030
                                        cmd.arg = p->local.isdn_channel;
1031
                                        isdn_command(&cmd);
1032
                                        isdn_all_eaz(p->local.isdn_device, p->local.isdn_channel);
1033
                                }
1034
                                anymore = 1;
1035
                                break;
1036
                        default:
1037
                                printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
1038
                                       p->local.dialstate, p->local.name);
1039
                }
1040
                p = (isdn_net_dev *) p->next;
1041
        }
1042
        isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);
1043
}
1044
 
1045
/*
1046
 * Perform hangup for a net-interface.
1047
 */
1048
void
1049
isdn_net_hangup(struct device *d)
1050
{
1051
        isdn_net_local *lp = (isdn_net_local *) d->priv;
1052
        isdn_ctrl cmd;
1053
 
1054
        if (lp->flags & ISDN_NET_CONNECTED) {
1055
                lp->flags &= ~ISDN_NET_CONNECTED;
1056
                printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
1057
#ifdef CONFIG_ISDN_PPP
1058
                isdn_ppp_free(lp);
1059
#endif
1060
                if ((lp->isdn_device != -1) && (lp->isdn_channel != -1)) {
1061
                        cmd.driver = lp->isdn_device;
1062
                        cmd.command = ISDN_CMD_HANGUP;
1063
                        cmd.arg = lp->isdn_channel;
1064
                        isdn_command(&cmd);
1065
                        isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
1066
                }
1067
                printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
1068
        }
1069
        isdn_net_unbind_channel(lp);
1070
}
1071
 
1072
typedef struct {
1073
        unsigned short source;
1074
        unsigned short dest;
1075
} ip_ports;
1076
 
1077
static void
1078
isdn_net_log_packet(u_char * buf, isdn_net_local * lp)
1079
{
1080
        u_char *p = buf;
1081
        unsigned short proto = ETH_P_IP;
1082
        int data_ofs;
1083
        ip_ports *ipp;
1084
        char addinfo[100];
1085
 
1086
        addinfo[0] = '\0';
1087
        switch (lp->p_encap) {
1088
                case ISDN_NET_ENCAP_IPTYP:
1089
                        proto = ntohs(*(unsigned short *) &buf[0]);
1090
                        p = &buf[2];
1091
                        break;
1092
                case ISDN_NET_ENCAP_ETHER:
1093
                        proto = ntohs(*(unsigned short *) &buf[12]);
1094
                        p = &buf[14];
1095
                        break;
1096
                case ISDN_NET_ENCAP_CISCOHDLC:
1097
                        proto = ntohs(*(unsigned short *) &buf[2]);
1098
                        p = &buf[4];
1099
                        break;
1100
#ifdef CONFIG_ISDN_PPP
1101
                case ISDN_NET_ENCAP_SYNCPPP:
1102
                        /* jump over fake header. */
1103
                        p = &buf[IPPP_MAX_HEADER];
1104
                        break;
1105
#endif
1106
        }
1107
        data_ofs = ((p[0] & 15) * 4);
1108
        switch (proto) {
1109
                case ETH_P_IP:
1110
                        switch (p[9]) {
1111
                                case 1:
1112
                                        strcpy(addinfo, " ICMP");
1113
                                        break;
1114
                                case 2:
1115
                                        strcpy(addinfo, " IGMP");
1116
                                        break;
1117
                                case 4:
1118
                                        strcpy(addinfo, " IPIP");
1119
                                        break;
1120
                                case 6:
1121
                                        ipp = (ip_ports *) (&p[data_ofs]);
1122
                                        sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
1123
                                                ntohs(ipp->dest));
1124
                                        break;
1125
                                case 8:
1126
                                        strcpy(addinfo, " EGP");
1127
                                        break;
1128
                                case 12:
1129
                                        strcpy(addinfo, " PUP");
1130
                                        break;
1131
                                case 17:
1132
                                        ipp = (ip_ports *) (&p[data_ofs]);
1133
                                        sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
1134
                                                ntohs(ipp->dest));
1135
                                        break;
1136
                                case 22:
1137
                                        strcpy(addinfo, " IDP");
1138
                                        break;
1139
                        }
1140
                        printk(KERN_INFO "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
1141
                               p[12], p[13], p[14], p[15],
1142
                               p[16], p[17], p[18], p[19],
1143
                               addinfo);
1144
                        break;
1145
                case ETH_P_ARP:
1146
                        printk(KERN_INFO "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
1147
                               p[14], p[15], p[16], p[17],
1148
                               p[24], p[25], p[26], p[27]);
1149
                        break;
1150
        }
1151
}
1152
 
1153
/*
1154
 * Generic routine to send out an skbuf.
1155
 * If lowlevel-device does not support supports skbufs, use
1156
 * standard send-routine, else send directly.
1157
 *
1158
 * Return: 0 on success, !0 on failure.
1159
 * Side-effects: ndev->tbusy is cleared on success.
1160
 */
1161
int
1162
isdn_net_send_skb(struct device *ndev, isdn_net_local * lp,
1163
                  struct sk_buff *skb)
1164
{
1165
        int ret;
1166
        int len = skb->len;     /* save len */
1167
 
1168
        ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, skb);
1169
        if (ret == len) {
1170
                lp->transcount += len;
1171
                clear_bit(0, (void *) &(ndev->tbusy));
1172
                return 0;
1173
        }
1174
        if (ret < 0) {
1175
                dev_kfree_skb(skb, FREE_WRITE);
1176
                lp->stats.tx_errors++;
1177
                clear_bit(0, (void *) &(ndev->tbusy));
1178
                return 0;
1179
        }
1180
        return 1;
1181
}
1182
 
1183
/*
1184
 *  Helper function for isdn_net_start_xmit.
1185
 *  When called, the connection is already established.
1186
 *  Based on cps-calculation, check if device is overloaded.
1187
 *  If so, and if a slave exists, trigger dialing for it.
1188
 *  If any slave is online, deliver packets using a simple round robin
1189
 *  scheme.
1190
 *
1191
 *  Return: 0 on success, !0 on failure.
1192
 */
1193
 
1194
static int
1195
isdn_net_xmit(struct device *ndev, isdn_net_local * lp, struct sk_buff *skb)
1196
{
1197
        int ret;
1198
 
1199
        /* For the other encaps the header has already been built */
1200
#ifdef CONFIG_ISDN_PPP
1201
        if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1202
                return isdn_ppp_xmit(skb, ndev);
1203
        }
1204
#endif
1205
        /* Reset hangup-timeout */
1206
        lp->huptimer = 0;
1207
        if (lp->cps > lp->triggercps) {
1208
                /* Device overloaded */
1209
 
1210
                /*
1211
                 * Packet-delivery via round-robin over master
1212
                 * and all connected slaves.
1213
                 */
1214
                if (lp->master)
1215
                        /* Slaves always deliver themselves */
1216
                        ret = isdn_net_send_skb(ndev, lp, skb);
1217
                else {
1218
                        isdn_net_local *slp = (isdn_net_local *) (lp->srobin->priv);
1219
                        /* Master delivers via srobin and maintains srobin */
1220
                        if (lp->srobin == ndev)
1221
                                ret = isdn_net_send_skb(ndev, lp, skb);
1222
                        else
1223
                                ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin);
1224
                        lp->srobin = (slp->slave) ? slp->slave : ndev;
1225
                        slp = (isdn_net_local *) (lp->srobin->priv);
1226
                        if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0)))
1227
                                lp->srobin = ndev;
1228
                }
1229
                /* Slave-startup using delay-variable */
1230
                if (lp->slave) {
1231
                        if (!lp->sqfull) {
1232
                                /* First time overload: set timestamp only */
1233
                                lp->sqfull = 1;
1234
                                lp->sqfull_stamp = jiffies;
1235
                        } else {
1236
                                /* subsequent overload: if slavedelay exceeded, start dialing */
1237
                                if ((jiffies - lp->sqfull_stamp) > lp->slavedelay)
1238
                                        isdn_net_force_dial_lp((isdn_net_local *) lp->slave->priv);
1239
                        }
1240
                }
1241
        } else {
1242
                /* Not overloaded, deliver locally */
1243
                ret = isdn_net_send_skb(ndev, lp, skb);
1244
                if (lp->sqfull && ((jiffies - lp->sqfull_stamp) > (lp->slavedelay + (10 * HZ))))
1245
                        lp->sqfull = 0;
1246
        }
1247
        return ret;
1248
}
1249
 
1250
/*
1251
 * Try sending a packet.
1252
 * If this interface isn't connected to a ISDN-Channel, find a free channel,
1253
 * and start dialing.
1254
 */
1255
int
1256
isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
1257
{
1258
        isdn_net_local *lp = (isdn_net_local *) ndev->priv;
1259
 
1260
        if (ndev->tbusy) {
1261
                if (jiffies - ndev->trans_start < (2 * HZ))
1262
                        return 1;
1263
 
1264
                if (!lp->dialstate)
1265
                        lp->stats.tx_errors++;
1266
 
1267
                ndev->tbusy = 0;
1268
                ndev->trans_start = jiffies;
1269
        }
1270
        if (skb == NULL) {
1271
                dev_tint(ndev);
1272
                return 0;
1273
        }
1274
        /* Avoid timer-based retransmission conflicts. */
1275
        if (test_and_set_bit(0, (void *) &ndev->tbusy) != 0)
1276
                printk(KERN_WARNING
1277
                       "%s: Transmitter access conflict.\n",
1278
                       ndev->name);
1279
        else {
1280
                u_char *buf = skb->data;
1281
#ifdef ISDN_DEBUG_NET_DUMP
1282
                isdn_dumppkt("S:", buf, skb->len, 40);
1283
#endif
1284
                if (!(lp->flags & ISDN_NET_CONNECTED)) {
1285
                        int chi;
1286
                        /* only do autodial if allowed by config */
1287
                        if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
1288
                                isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
1289
                                dev_kfree_skb(skb, FREE_WRITE);
1290
                                ndev->tbusy = 0;
1291
                                return 0;
1292
                        }
1293
                        if (lp->phone[1]) {
1294
                                ulong flags;
1295
                                save_flags(flags);
1296
                                cli();
1297
 
1298
                                if(lp->dialwait_timer <= 0)
1299
                                        if(lp->dialstarted > 0 && lp->dialtimeout > 0 && jiffies < lp->dialstarted + lp->dialtimeout + lp->dialwait)
1300
                                                lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
1301
 
1302
                                if(lp->dialwait_timer > 0) {
1303
                                        if(jiffies < lp->dialwait_timer) {
1304
/*
1305
printk("reject: jiffies=%ld, started=%ld, timeout=%d, wait=%ld, timer=%ld\n", jiffies, lp->dialstarted, lp->dialtimeout, lp->dialwait, lp->dialwait_timer);
1306
*/
1307
                                                /*
1308
                                                printk(KERN_WARNING "isdn_net: Dial rejected %s, packet dropped\n",
1309
                                                        ndev->name);
1310
                                                */
1311
                                                isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
1312
                                                dev_kfree_skb(skb, FREE_WRITE);
1313
                                                ndev->tbusy = 0;
1314
                                                restore_flags(flags);
1315
                                                return 0;
1316
                                        } else
1317
                                                lp->dialwait_timer = 0;
1318
                                }
1319
 
1320
                                /* Grab a free ISDN-Channel */
1321
                                if (((chi =
1322
                                     isdn_get_free_channel(ISDN_USAGE_NET,
1323
                                                           lp->l2_proto,
1324
                                                           lp->l3_proto,
1325
                                                           lp->pre_device,
1326
                                                 lp->pre_channel)) < 0) &&
1327
                                    ((chi =
1328
                                         isdn_get_free_channel(ISDN_USAGE_NET,
1329
                                                           lp->l2_proto,
1330
                                                           lp->l3_proto,
1331
                                                           lp->pre_device,
1332
                                                 lp->pre_channel^1)) < 0)) {
1333
                                        restore_flags(flags);
1334
#if 0
1335
                                        printk(KERN_WARNING
1336
                                               "isdn_net_start_xmit: No channel for %s\n",
1337
                                               ndev->name);
1338
                                        /* we probably should drop the skb here and return 0 to omit
1339
                                           'socket destroy delayed' messages */
1340
                                        return 1;
1341
#else
1342
                                        isdn_net_unreachable(ndev, skb,
1343
                                                           "No channel");
1344
                                        dev_kfree_skb(skb, FREE_WRITE);
1345
                                        ndev->tbusy = 0;
1346
                                        return 0;
1347
#endif
1348
                                }
1349
                                /* Log packet, which triggered dialing */
1350
                                if (dev->net_verbose)
1351
                                        isdn_net_log_packet(buf, lp);
1352
 
1353
                                lp->dialstate = 1;
1354
                                lp->flags |= ISDN_NET_CONNECTED;
1355
                                /* Connect interface with channel */
1356
                                isdn_net_bind_channel(lp, chi);
1357
#ifdef CONFIG_ISDN_PPP
1358
                                if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1359
                                        /* no 'first_skb' handling for syncPPP */
1360
                                        if (isdn_ppp_bind(lp) < 0) {
1361
                                                dev_kfree_skb(skb, FREE_WRITE);
1362
                                                isdn_net_unbind_channel(lp);
1363
                                                restore_flags(flags);
1364
                                                return 0;        /* STN (skb to nirvana) ;) */
1365
                                        }
1366
                                        restore_flags(flags);
1367
                                        isdn_net_dial();        /* Initiate dialing */
1368
                                        return 1;       /* let upper layer requeue skb packet */
1369
                                }
1370
#endif
1371
                                /* remember first skb to speed up arp
1372
                                 * when using encap ETHER
1373
                                 */
1374
                                if (lp->first_skb) {
1375
                                        printk(KERN_DEBUG "isdn_net_start_xmit: First skb already set!\n");
1376
                                        dev_kfree_skb(lp->first_skb, FREE_WRITE);
1377
                                        lp->first_skb = NULL;
1378
                                }
1379
                                lp->first_skb = skb;
1380
                                /* Initiate dialing */
1381
                                ndev->tbusy = 0;
1382
                                restore_flags(flags);
1383
                                isdn_net_dial();
1384
                                return 0;
1385
                        } else {
1386
                                isdn_net_unreachable(ndev, skb,
1387
                                                     "No phone number");
1388
                                dev_kfree_skb(skb, FREE_WRITE);
1389
                                ndev->tbusy = 0;
1390
                                return 0;
1391
                        }
1392
                } else {
1393
                        /* Connection is established, try sending */
1394
                        ndev->trans_start = jiffies;
1395
                        if (!lp->dialstate) {
1396
                                if (lp->first_skb) {
1397
                                        if (isdn_net_xmit(ndev, lp, lp->first_skb))
1398
                                                return 1;
1399
                                        lp->first_skb = NULL;
1400
                                }
1401
                                return (isdn_net_xmit(ndev, lp, skb));
1402
                        } else
1403
                                ndev->tbusy = 1;
1404
                }
1405
        }
1406
        return 1;
1407
}
1408
 
1409
/*
1410
 * Shutdown a net-interface.
1411
 */
1412
static int
1413
isdn_net_close(struct device *dev)
1414
{
1415
        struct device *p;
1416
 
1417
        dev->tbusy = 1;
1418
        dev->start = 0;
1419
        if ((p = (((isdn_net_local *) dev->priv)->slave))) {
1420
                /* If this interface has slaves, stop them also */
1421
                while (p) {
1422
                        isdn_net_hangup(p);
1423
                        p->tbusy = 1;
1424
                        p->start = 0;
1425
                        p = (((isdn_net_local *) p->priv)->slave);
1426
                }
1427
        }
1428
        isdn_net_hangup(dev);
1429
        isdn_MOD_DEC_USE_COUNT();
1430
        return 0;
1431
}
1432
 
1433
/*
1434
 * Get statistics
1435
 */
1436
static struct enet_statistics *
1437
isdn_net_get_stats(struct device *dev)
1438
{
1439
        isdn_net_local *lp = (isdn_net_local *) dev->priv;
1440
        return &lp->stats;
1441
}
1442
 
1443
/*      This is simply a copy from std. eth.c EXCEPT we pull ETH_HLEN
1444
 *      instead of dev->hard_header_len off. This is done because the
1445
 *      lowlevel-driver has already pulled off its stuff when we get
1446
 *      here and this routine only gets called with p_encap == ETHER.
1447
 *      Determine the packet's protocol ID. The rule here is that we
1448
 *      assume 802.3 if the type field is short enough to be a length.
1449
 *      This is normal practice and works for any 'now in use' protocol.
1450
 */
1451
 
1452
static unsigned short
1453
isdn_net_type_trans(struct sk_buff *skb, struct device *dev)
1454
{
1455
        struct ethhdr *eth;
1456
        unsigned char *rawp;
1457
 
1458
        skb_pull(skb, ETH_HLEN);
1459
        eth = skb->mac.ethernet;
1460
 
1461
        if (*eth->h_dest & 1) {
1462
                if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
1463
                        skb->pkt_type = PACKET_BROADCAST;
1464
                else
1465
                        skb->pkt_type = PACKET_MULTICAST;
1466
        }
1467
        /*
1468
         *      This ALLMULTI check should be redundant by 1.4
1469
         *      so don't forget to remove it.
1470
         */
1471
 
1472
        else if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
1473
                if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
1474
                        skb->pkt_type = PACKET_OTHERHOST;
1475
        }
1476
        if (ntohs(eth->h_proto) >= 1536)
1477
                return eth->h_proto;
1478
 
1479
        rawp = skb->data;
1480
 
1481
        /*
1482
         *      This is a magic hack to spot IPX packets. Older Novell breaks
1483
         *      the protocol design and runs IPX over 802.3 without an 802.2 LLC
1484
         *      layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
1485
         *      won't work for fault tolerant netware but does for the rest.
1486
         */
1487
        if (*(unsigned short *) rawp == 0xFFFF)
1488
                return htons(ETH_P_802_3);
1489
        /*
1490
         *      Real 802.2 LLC
1491
         */
1492
        return htons(ETH_P_802_2);
1493
}
1494
 
1495
/*
1496
 * Got a packet from ISDN-Channel.
1497
 */
1498
static void
1499
isdn_net_receive(struct device *ndev, struct sk_buff *skb)
1500
{
1501
        isdn_net_local *lp = (isdn_net_local *) ndev->priv;
1502
#ifdef CONFIG_ISDN_PPP
1503
        isdn_net_local *olp = lp;       /* original 'lp' */
1504
        int proto = PPP_PROTOCOL(skb->data);
1505
#endif
1506
 
1507
        lp->transcount += skb->len;
1508
        lp->stats.rx_packets++;
1509
#ifdef CONFIG_ISDN_PPP
1510
        /*
1511
         * If encapsulation is syncppp, don't reset
1512
         * huptimer on LCP packets.
1513
         */
1514
        if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP ||
1515
            (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && proto != PPP_LCP))
1516
#endif
1517
                lp->huptimer = 0;
1518
 
1519
        if (lp->master) {
1520
                /* Bundling: If device is a slave-device, deliver to master, also
1521
                 * handle master's statistics and hangup-timeout
1522
                 */
1523
                ndev = lp->master;
1524
                lp = (isdn_net_local *) ndev->priv;
1525
                lp->stats.rx_packets++;
1526
#ifdef CONFIG_ISDN_PPP
1527
                /*
1528
                 * If encapsulation is syncppp, don't reset
1529
                 * huptimer on LCP packets.
1530
                 */
1531
                if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP ||
1532
                    (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && proto != PPP_LCP))
1533
#endif
1534
                        lp->huptimer = 0;
1535
        }
1536
        skb->dev = ndev;
1537
        skb->pkt_type = PACKET_HOST;
1538
        skb->mac.raw = skb->data;
1539
#ifdef ISDN_DEBUG_NET_DUMP
1540
        isdn_dumppkt("R:", skb->data, skb->len, 40);
1541
#endif
1542
        switch (lp->p_encap) {
1543
                case ISDN_NET_ENCAP_ETHER:
1544
                        /* Ethernet over ISDN */
1545
                        skb->protocol = isdn_net_type_trans(skb, ndev);
1546
                        break;
1547
                case ISDN_NET_ENCAP_UIHDLC:
1548
                        /* HDLC with UI-frame (for ispa with -h1 option) */
1549
                        skb_pull(skb, 2);
1550
                        /* Fall through */
1551
                case ISDN_NET_ENCAP_RAWIP:
1552
                        /* RAW-IP without MAC-Header */
1553
                        skb->protocol = htons(ETH_P_IP);
1554
                        break;
1555
                case ISDN_NET_ENCAP_CISCOHDLC:
1556
                        /* CISCO-HDLC IP with type field and  fake I-frame-header */
1557
                        skb_pull(skb, 2);
1558
                        /* Fall through */
1559
                case ISDN_NET_ENCAP_IPTYP:
1560
                        /* IP with type field */
1561
                        skb->protocol = *(unsigned short *) &(skb->data[0]);
1562
                        skb_pull(skb, 2);
1563
                        if (*(unsigned short *) skb->data == 0xFFFF)
1564
                                skb->protocol = htons(ETH_P_802_3);
1565
                        break;
1566
#ifdef CONFIG_ISDN_PPP
1567
                case ISDN_NET_ENCAP_SYNCPPP:
1568
                        isdn_ppp_receive(lp->netdev, olp, skb);
1569
                        return;
1570
#endif
1571
                default:
1572
                        printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
1573
                               lp->name);
1574
                        kfree_skb(skb, FREE_READ);
1575
                        return;
1576
        }
1577
 
1578
        netif_rx(skb);
1579
        return;
1580
}
1581
 
1582
/*
1583
 * A packet arrived via ISDN. Search interface-chain for a corresponding
1584
 * interface. If found, deliver packet to receiver-function and return 1,
1585
 * else return 0.
1586
 */
1587
int
1588
isdn_net_rcv_skb(int idx, struct sk_buff *skb)
1589
{
1590
        isdn_net_dev *p = dev->rx_netdev[idx];
1591
 
1592
        if (p) {
1593
                isdn_net_local *lp = &p->local;
1594
                if ((lp->flags & ISDN_NET_CONNECTED) &&
1595
                    (!lp->dialstate)) {
1596
                        isdn_net_receive(&p->dev, skb);
1597
                        return 1;
1598
                }
1599
        }
1600
        return 0;
1601
}
1602
 
1603
static int
1604
my_eth_header(struct sk_buff *skb, struct device *dev, unsigned short type,
1605
              void *daddr, void *saddr, unsigned len)
1606
{
1607
        struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
1608
 
1609
        /*
1610
         * Set the protocol type. For a packet of type ETH_P_802_3 we
1611
         * put the length here instead. It is up to the 802.2 layer to
1612
         * carry protocol information.
1613
         */
1614
 
1615
        if (type != ETH_P_802_3)
1616
                eth->h_proto = htons(type);
1617
        else
1618
                eth->h_proto = htons(len);
1619
 
1620
        /*
1621
         * Set the source hardware address.
1622
         */
1623
        if (saddr)
1624
                memcpy(eth->h_source, saddr, dev->addr_len);
1625
        else
1626
                memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1627
 
1628
        /*
1629
         * Anyway, the loopback-device should never use this function...
1630
         */
1631
 
1632
        if (dev->flags & IFF_LOOPBACK) {
1633
                memset(eth->h_dest, 0, dev->addr_len);
1634
                return (dev->hard_header_len);
1635
        }
1636
        if (daddr) {
1637
                memcpy(eth->h_dest, daddr, dev->addr_len);
1638
                return dev->hard_header_len;
1639
        }
1640
        return -dev->hard_header_len;
1641
}
1642
 
1643
/*
1644
 *  build an header
1645
 *  depends on encaps that is being used.
1646
 */
1647
 
1648
static int
1649
isdn_net_header(struct sk_buff *skb, struct device *dev, unsigned short type,
1650
                void *daddr, void *saddr, unsigned plen)
1651
{
1652
        isdn_net_local *lp = dev->priv;
1653
        ushort len = 0;
1654
 
1655
        switch (lp->p_encap) {
1656
                case ISDN_NET_ENCAP_ETHER:
1657
                        len = my_eth_header(skb, dev, type, daddr, saddr, plen);
1658
                        break;
1659
            break;
1660
#ifdef CONFIG_ISDN_PPP
1661
                case ISDN_NET_ENCAP_SYNCPPP:
1662
                        /* stick on a fake header to keep fragmentation code happy. */
1663
                        len = IPPP_MAX_HEADER;
1664
                        skb_push(skb,len);
1665
                        break;
1666
#endif
1667
                case ISDN_NET_ENCAP_RAWIP:
1668
                        printk(KERN_WARNING "isdn_net_header called with RAW_IP!\n");
1669
                        len = 0;
1670
                        break;
1671
                case ISDN_NET_ENCAP_IPTYP:
1672
                        /* ethernet type field */
1673
                        *((ushort *) skb_push(skb, 2)) = htons(type);
1674
                        len = 2;
1675
                        break;
1676
                case ISDN_NET_ENCAP_UIHDLC:
1677
                        /* HDLC with UI-Frames (for ispa with -h1 option) */
1678
                        *((ushort *) skb_push(skb, 2)) = htons(0x0103);
1679
                        len = 2;
1680
                        break;
1681
                case ISDN_NET_ENCAP_CISCOHDLC:
1682
                        skb_push(skb, 4);
1683
                        skb->data[0] = 0x0f;
1684
                        skb->data[1] = 0x00;
1685
                        *((ushort *) & skb->data[2]) = htons(type);
1686
                        len = 4;
1687
                        break;
1688
        }
1689
        return len;
1690
}
1691
 
1692
/* We don't need to send arp, because we have point-to-point connections. */
1693
#if (LINUX_VERSION_CODE < 0x02010F)
1694
static int
1695
isdn_net_rebuild_header(void *buff, struct device *dev, unsigned long dst,
1696
                        struct sk_buff *skb)
1697
{
1698
        isdn_net_local *lp = dev->priv;
1699
        int ret = 0;
1700
 
1701
        if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
1702
                struct ethhdr *eth = (struct ethhdr *) buff;
1703
 
1704
                /*
1705
                 *      Only ARP/IP is currently supported
1706
                 */
1707
 
1708
                if (eth->h_proto != htons(ETH_P_IP)) {
1709
                        printk(KERN_WARNING
1710
                               "isdn_net: %s don't know how to resolve type %d addresses?\n",
1711
                               dev->name, (int) eth->h_proto);
1712
                        memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1713
                        return 0;
1714
                }
1715
                /*
1716
                 *      Try to get ARP to resolve the header.
1717
                 */
1718
#ifdef CONFIG_INET
1719
                ret = arp_find(eth->h_dest, dst, dev, dev->pa_addr, skb) ? 1 : 0;
1720
#endif
1721
        }
1722
        return ret;
1723
}
1724
#else
1725
static int
1726
isdn_net_rebuild_header(struct sk_buff *skb)
1727
{
1728
        struct device *dev = skb->dev;
1729
        isdn_net_local *lp = dev->priv;
1730
        int ret = 0;
1731
 
1732
        if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
1733
                struct ethhdr *eth = (struct ethhdr *) skb->data;
1734
 
1735
                /*
1736
                 *      Only ARP/IP is currently supported
1737
                 */
1738
 
1739
                if (eth->h_proto != htons(ETH_P_IP)) {
1740
                        printk(KERN_WARNING
1741
                               "isdn_net: %s don't know how to resolve type %d addresses?\n",
1742
                               dev->name, (int) eth->h_proto);
1743
                        memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1744
                        return 0;
1745
                }
1746
                /*
1747
                 *      Try to get ARP to resolve the header.
1748
                 */
1749
#ifdef CONFIG_INET
1750
                ret = arp_find(eth->h_dest, skb) ? 1 : 0;
1751
#endif
1752
        }
1753
        return ret;
1754
}
1755
#endif
1756
/*
1757
 * Interface-setup. (called just after registering a new interface)
1758
 */
1759
static int
1760
isdn_net_init(struct device *ndev)
1761
{
1762
        ushort max_hlhdr_len = 0;
1763
        isdn_net_local *lp = (isdn_net_local *) ndev->priv;
1764
        int drvidx,
1765
         i;
1766
 
1767
        if (ndev == NULL) {
1768
                printk(KERN_WARNING "isdn_net_init: dev = NULL!\n");
1769
                return -ENODEV;
1770
        }
1771
        if (ndev->priv == NULL) {
1772
                printk(KERN_WARNING "isdn_net_init: dev->priv = NULL!\n");
1773
                return -ENODEV;
1774
        }
1775
        ether_setup(ndev);
1776
#if (LINUX_VERSION_CODE < 0x02010F)
1777
        lp->org_hcb = ndev->header_cache_bind;
1778
#else
1779
        lp->org_hhc = ndev->hard_header_cache;
1780
#endif
1781
        lp->org_hcu = ndev->header_cache_update;
1782
 
1783
        /* Setup the generic properties */
1784
 
1785
        ndev->hard_header = NULL;
1786
#if (LINUX_VERSION_CODE < 0x02010F)
1787
        ndev->header_cache_bind = NULL;
1788
#else
1789
        ndev->hard_header_cache = NULL;
1790
#endif
1791
        ndev->header_cache_update = NULL;
1792
        ndev->mtu = 1500;
1793
        ndev->flags = IFF_NOARP;
1794
        ndev->family = AF_INET;
1795
        ndev->type = ARPHRD_ETHER;
1796
        ndev->addr_len = ETH_ALEN;
1797
        ndev->pa_addr = 0;
1798
        ndev->pa_brdaddr = 0;
1799
        ndev->pa_mask = 0;
1800
        ndev->pa_alen = 4;
1801
 
1802
        /* for clients with MPPP maybe higher values better */
1803
        ndev->tx_queue_len = 30;
1804
 
1805
        for (i = 0; i < ETH_ALEN; i++)
1806
                ndev->broadcast[i] = 0xff;
1807
 
1808
        for (i = 0; i < DEV_NUMBUFFS; i++)
1809
                skb_queue_head_init(&ndev->buffs[i]);
1810
 
1811
        /* The ISDN-specific entries in the device structure. */
1812
        ndev->open = &isdn_net_open;
1813
        ndev->hard_start_xmit = &isdn_net_start_xmit;
1814
        /*
1815
         *  up till binding we ask the protocol layer to reserve as much
1816
         *  as we might need for HL layer
1817
         */
1818
 
1819
        for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
1820
                if (dev->drv[drvidx])
1821
                        if (max_hlhdr_len < dev->drv[drvidx]->interface->hl_hdrlen)
1822
                                max_hlhdr_len = dev->drv[drvidx]->interface->hl_hdrlen;
1823
 
1824
        ndev->hard_header_len = ETH_HLEN + max_hlhdr_len;
1825
        ndev->stop = &isdn_net_close;
1826
        ndev->get_stats = &isdn_net_get_stats;
1827
        ndev->rebuild_header = &isdn_net_rebuild_header;
1828
 
1829
#ifdef CONFIG_ISDN_PPP
1830
        ndev->do_ioctl = isdn_ppp_dev_ioctl;
1831
#endif
1832
        return 0;
1833
}
1834
 
1835
/*
1836
 * I picked the pattern-matching-functions from an old GNU-tar version (1.10)
1837
 * It was originally written and put to PD by rs@mirror.TMC.COM (Rich Salz)
1838
 */
1839
 
1840
static int
1841
isdn_net_Star(char *s, char *p)
1842
{
1843
        while (isdn_net_wildmat(s, p) == 0)
1844
                if (*++s == '\0')
1845
                        return (0);
1846
        return (1);
1847
}
1848
 
1849
/*
1850
 * Shell-type Pattern-matching for incoming caller-Ids
1851
 * This function gets a string in s and checks, if it matches the pattern
1852
 * given in p. It returns 1 on success, 0 otherwise.
1853
 *
1854
 * Possible Patterns:
1855
 *
1856
 * '?'     matches one character
1857
 * '*'     matches zero or more characters
1858
 * [xyz]   matches the set of characters in brackets.
1859
 * [^xyz]  matches any single character not in the set of characters
1860
 */
1861
 
1862
static int
1863
isdn_net_wildmat(char *s, char *p)
1864
{
1865
        register int last;
1866
        register int matched;
1867
        register int reverse;
1868
 
1869
        for (; *p; s++, p++)
1870
                switch (*p) {
1871
                        case '\\':
1872
                                /*
1873
                                 * Literal match with following character,
1874
                                 * fall through.
1875
                                 */
1876
                                p++;
1877
                        default:
1878
                                if (*s != *p)
1879
                                        return (0);
1880
                                continue;
1881
                        case '?':
1882
                                /* Match anything. */
1883
                                if (*s == '\0')
1884
                                        return (0);
1885
                                continue;
1886
                        case '*':
1887
                                /* Trailing star matches everything. */
1888
                                return (*++p ? isdn_net_Star(s, p) : 1);
1889
                        case '[':
1890
                                /* [^....] means inverse character class. */
1891
                                if ((reverse = (p[1] == '^')))
1892
                                        p++;
1893
                                for (last = 0, matched = 0; *++p && (*p != ']'); last = *p)
1894
                                        /* This next line requires a good C compiler. */
1895
                                        if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
1896
                                                matched = 1;
1897
                                if (matched == reverse)
1898
                                        return (0);
1899
                                continue;
1900
                }
1901
        return (*s == '\0');
1902
}
1903
 
1904
static void
1905
isdn_net_swapbind(int drvidx)
1906
{
1907
        isdn_net_dev *p;
1908
 
1909
#ifdef ISDN_DEBUG_NET_ICALL
1910
        printk(KERN_DEBUG "n_fi: swapping ch of %d\n", drvidx);
1911
#endif
1912
        p = dev->netdev;
1913
        while (p) {
1914
                if (p->local.pre_device == drvidx)
1915
                        switch (p->local.pre_channel) {
1916
                                case 0:
1917
                                        p->local.pre_channel = 1;
1918
                                        break;
1919
                                case 1:
1920
                                        p->local.pre_channel = 0;
1921
                                        break;
1922
                        }
1923
                p = (isdn_net_dev *) p->next;
1924
        }
1925
}
1926
 
1927
static void
1928
isdn_net_swap_usage(int i1, int i2)
1929
{
1930
        int u1 = dev->usage[i1] & ISDN_USAGE_EXCLUSIVE;
1931
        int u2 = dev->usage[i2] & ISDN_USAGE_EXCLUSIVE;
1932
 
1933
#ifdef ISDN_DEBUG_NET_ICALL
1934
        printk(KERN_DEBUG "n_fi: usage of %d and %d\n", i1, i2);
1935
#endif
1936
        dev->usage[i1] &= ~ISDN_USAGE_EXCLUSIVE;
1937
        dev->usage[i1] |= u2;
1938
        dev->usage[i2] &= ~ISDN_USAGE_EXCLUSIVE;
1939
        dev->usage[i2] |= u1;
1940
        isdn_info_update();
1941
}
1942
 
1943
/*
1944
 * An incoming call-request has arrived.
1945
 * Search the interface-chain for an appropriate interface.
1946
 * If found, connect the interface to the ISDN-channel and initiate
1947
 * D- and B-Channel-setup. If secure-flag is set, accept only
1948
 * configured phone-numbers. If callback-flag is set, initiate
1949
 * callback-dialing.
1950
 *
1951
 * Return-Value: 0 = No appropriate interface for this call.
1952
 *               1 = Call accepted
1953
 *               2 = Reject call, wait cbdelay, then call back
1954
 *               3 = Reject call
1955
 *               4 = Wait cbdelay, then call back
1956
 */
1957
int
1958
isdn_net_find_icall(int di, isdn_ctrl *c, int idx)
1959
{
1960
        char *eaz;
1961
        int ch = c->arg;
1962
        setup_parm *setup = &c->parm.setup;
1963
        int si1;
1964
        int si2;
1965
        int ematch;
1966
        int swapped;
1967
        int sidx = 0;
1968
        isdn_net_dev *p;
1969
        isdn_net_phone *n;
1970
        ulong flags;
1971
        char nr[32];
1972
 
1973
        /* Search name in netdev-chain */
1974
        save_flags(flags);
1975
        cli();
1976
        if (!setup->phone[0]) {
1977
                nr[0] = '0';
1978
                nr[1] = '\0';
1979
                printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
1980
        } else
1981
                strcpy(nr, setup->phone);
1982
        si1 = (int) setup->si1;
1983
        si2 = (int) setup->si2;
1984
        if (!setup->eazmsn[0]) {
1985
                printk(KERN_WARNING "isdn_net: Incoming call without CPN, assuming '0'\n");
1986
                eaz = "0";
1987
        } else
1988
                eaz = setup->eazmsn;
1989
        if (dev->net_verbose > 1)
1990
                printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
1991
        /* Accept only calls with Si1 = 7 (Data-Transmission) */
1992
        if (si1 != 7) {
1993
                if (dev->net_verbose > 1)
1994
                        printk(KERN_INFO "isdn_net: Service-Indicator not 7, ignored\n");
1995
                restore_flags(flags);
1996
                return 0;
1997
        }
1998
        n = (isdn_net_phone *) 0;
1999
        ematch = 0;
2000
#ifdef ISDN_DEBUG_NET_ICALL
2001
        printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
2002
               dev->usage[idx]);
2003
#endif
2004
        swapped = 0;
2005
 
2006
        for (p = dev->netdev; p; p = (isdn_net_dev *) p->next) {
2007
                /* If last check has triggered as binding-swap, revert it */
2008
                switch (swapped) {
2009
                        case 2:
2010
                                isdn_net_swap_usage(idx, sidx);
2011
                                /* fall through */
2012
                        case 1:
2013
                                isdn_net_swapbind(di);
2014
                                break;
2015
                }
2016
                swapped = 0;
2017
                if (strcmp(isdn_map_eaz2msn(p->local.msn, di), eaz))
2018
                        continue;       /* next loop for next device */
2019
                ematch = 1;     /* EAZ matches! */
2020
#ifdef ISDN_DEBUG_NET_ICALL
2021
                printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
2022
                       p->local.name, p->local.msn, p->local.flags, p->local.dialstate);
2023
#endif
2024
                if ( (!(p->local.flags & ISDN_NET_CONNECTED) && /* not connected  */
2025
                      USG_NONE(dev->usage[idx]))                /* and ch. unused */
2026
                    ||                                          /* or */
2027
                     (((p->local.dialstate == 4) || (p->local.dialstate == 12) ||
2028
               (p->local.dialstate == 13)) &&   /* if dialing        */
2029
                       !(p->local.flags & ISDN_NET_CALLBACK))                           /* but no callback   */
2030
                   ) /*if*/ {
2031
#ifdef ISDN_DEBUG_NET_ICALL
2032
                        printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
2033
                               p->local.pre_device, p->local.pre_channel);
2034
#endif
2035
                        if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
2036
                                if ((p->local.pre_channel != ch) ||
2037
                                    (p->local.pre_device != di)) {
2038
                                        /* Here we got a problem:
2039
                                         * If using an ICN-Card, an incoming call is always signaled on
2040
                                         * on the first channel of the card, if both channels are
2041
                                         * down. However this channel may be bound exclusive. If the
2042
                                         * second channel is free, this call should be accepted.
2043
                                         * The solution is horribly but it runs, so what:
2044
                                         * We exchange the exclusive bindings of the two channels, the
2045
                                         * corresponding variables in the interface-structs.
2046
                                         */
2047
                                        if (ch == 0) {
2048
                                                sidx = isdn_dc2minor(di, 1);
2049
#ifdef ISDN_DEBUG_NET_ICALL
2050
                                                printk(KERN_DEBUG "n_fi: ch is 0\n");
2051
#endif
2052
                                                if (USG_NONE(dev->usage[sidx])) {
2053
                                                        /* Second Channel is free, now see if it is bound
2054
                                                         * exclusive too. */
2055
                                                        if (dev->usage[sidx] & ISDN_USAGE_EXCLUSIVE) {
2056
#ifdef ISDN_DEBUG_NET_ICALL
2057
                                                                printk(KERN_DEBUG "n_fi: 2nd channel is down and bound\n");
2058
#endif
2059
                                                                /* Yes, swap bindings only, if the original
2060
                                                                 * binding is bound to channel 1 of this driver */
2061
                                                                if ((p->local.pre_device == di) &&
2062
                                                                    (p->local.pre_channel == 1)) {
2063
                                                                        isdn_net_swapbind(di);
2064
                                                                        swapped = 1;
2065
                                                                } else {
2066
                                                                        /* ... else iterate next device */
2067
                                                                        continue;
2068
                                                                }
2069
                                                        } else {
2070
#ifdef ISDN_DEBUG_NET_ICALL
2071
                                                                printk(KERN_DEBUG "n_fi: 2nd channel is down and unbound\n");
2072
#endif
2073
                                                                /* No, swap always and swap excl-usage also */
2074
                                                                isdn_net_swap_usage(idx, sidx);
2075
                                                                isdn_net_swapbind(di);
2076
                                                                swapped = 2;
2077
                                                        }
2078
                                                        /* Now check for exclusive binding again */
2079
#ifdef ISDN_DEBUG_NET_ICALL
2080
                                                        printk(KERN_DEBUG "n_fi: final check\n");
2081
#endif
2082
                                                        if ((dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) &&
2083
                                                            ((p->local.pre_channel != ch) ||
2084
                                                             (p->local.pre_device != di))) {
2085
#ifdef ISDN_DEBUG_NET_ICALL
2086
                                                                printk(KERN_DEBUG "n_fi: final check failed\n");
2087
#endif
2088
                                                                continue;
2089
                                                        }
2090
                                                }
2091
                                        } else {
2092
                                                /* We are already on the second channel, so nothing to do */
2093
#ifdef ISDN_DEBUG_NET_ICALL
2094
                                                printk(KERN_DEBUG "n_fi: already on 2nd channel\n");
2095
#endif
2096
                                                continue;
2097
                                        }
2098
                                }
2099
                        }
2100
#ifdef ISDN_DEBUG_NET_ICALL
2101
                        printk(KERN_DEBUG "n_fi: match2\n");
2102
#endif
2103
                        n = p->local.phone[0];
2104
                        if (p->local.flags & ISDN_NET_SECURE) {
2105
                                while (n) {
2106
                                        if (isdn_net_wildmat(nr, n->num))
2107
                                                break;
2108
                                        n = (isdn_net_phone *) n->next;
2109
                                }
2110
                        }
2111
                        if (n || (!(p->local.flags & ISDN_NET_SECURE))) {
2112
                                isdn_net_local *lp = &(p->local);
2113
#ifdef ISDN_DEBUG_NET_ICALL
2114
                                printk(KERN_DEBUG "n_fi: match3\n");
2115
#endif
2116
                                /* matching interface found */
2117
 
2118
                                /*
2119
                                 * Is the state STOPPED?
2120
                                 * If so, no dialin is allowed,
2121
                                 * so reject actively.
2122
                                 * */
2123
                                if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
2124
                                        restore_flags(flags);
2125
                                        printk(KERN_INFO "incoming call, interface `%s' dialmode `off' -> rejected\n",
2126
                                               lp->name);
2127
                                        return 3;
2128
                                }
2129
                                /*
2130
                                 * Is the interface up?
2131
                                 * If not, reject the call actively.
2132
                                 */
2133
                                if (!p->dev.start) {
2134
                                        restore_flags(flags);
2135
                                        printk(KERN_INFO "incoming call, interface `%s' down -> rejected\n",
2136
                                               lp->name);
2137
                                        return 3;
2138
                                }
2139
                                /* Interface is up, now see if it's a slave. If so, see if
2140
                                 * it's master and parent slave is online. If not, reject the call.
2141
                                 */
2142
                                if (lp->master) {
2143
                                        isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
2144
                                        printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
2145
                                        printk(KERN_DEBUG "master=%s\n", mlp->name);
2146
                                        if ((mlp->flags & ISDN_NET_CONNECTED) && (!mlp->dialstate)) {
2147
                                                printk(KERN_DEBUG "master online\n");
2148
                                                /* Master is online, find parent-slave (master if first slave) */
2149
                                                while (mlp->slave) {
2150
                                                        if ((isdn_net_local *) mlp->slave->priv == lp)
2151
                                                                break;
2152
                                                        mlp = (isdn_net_local *) mlp->slave->priv;
2153
                                                }
2154
                                        } else
2155
                                                printk(KERN_DEBUG "master offline\n");
2156
                                        /* Found parent, if it's offline iterate next device */
2157
                                        printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
2158
                                        if (!(mlp->flags & ISDN_NET_CONNECTED) || mlp->dialstate) {
2159
                                                continue;
2160
                                        }
2161
                                }
2162
                                if (lp->flags & ISDN_NET_CALLBACK) {
2163
                                        int chi;
2164
                                        /*
2165
                                         * Is the state MANUAL?
2166
                                         * If so, no callback can be made,
2167
                                         * so reject actively.
2168
                                         * */
2169
                                        if (ISDN_NET_DIALMODE(*lp) != ISDN_NET_DM_AUTO) {
2170
                                                restore_flags(flags);
2171
                                                printk(KERN_INFO "incoming call for callback, interface `%s' dialmode not `auto' -> rejected\n",
2172
                                                       lp->name);
2173
                                                return 3;
2174
                                        }
2175
                                        printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
2176
                                               lp->name, nr, eaz);
2177
                                        if (lp->phone[1]) {
2178
                                                /* Grab a free ISDN-Channel */
2179
                                                if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
2180
                                                            lp->l3_proto,
2181
                                                          lp->pre_device,
2182
                                                 lp->pre_channel)) < 0) {
2183
                                                        printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
2184
                                                        restore_flags(flags);
2185
                                                        return 0;
2186
                                                }
2187
                                                /* Setup dialstate. */
2188
                                                lp->dtimer = 0;
2189
                                                lp->dialstate = 11;
2190
                                                lp->flags |= ISDN_NET_CONNECTED;
2191
                                                /* Connect interface with channel */
2192
                                                isdn_net_bind_channel(lp, chi);
2193
#ifdef CONFIG_ISDN_PPP
2194
                                                if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2195
                                                        if (isdn_ppp_bind(lp) < 0) {
2196
                                                                isdn_net_unbind_channel(lp);
2197
                                                                restore_flags(flags);
2198
                                                                return 0;
2199
                                                        }
2200
#endif
2201
                                                /* Initiate dialing by returning 2 or 4 */
2202
                                                restore_flags(flags);
2203
                                                return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
2204
                                        } else
2205
                                                printk(KERN_WARNING "isdn_net: %s: No phone number\n", lp->name);
2206
                                        restore_flags(flags);
2207
                                        return 0;
2208
                                } else {
2209
                                        printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
2210
                                               eaz);
2211
                                        /* if this interface is dialing, it does it probably on a different
2212
                                           device, so free this device */
2213
                                        if (p->local.dialstate &&
2214
                                                ((p->local.isdn_device != di) || (p->local.isdn_channel != ch))) {
2215
#ifdef CONFIG_ISDN_PPP
2216
                                                if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2217
                                                        isdn_ppp_free(lp);
2218
#endif
2219
                                                isdn_net_unbind_ptr(lp->isdn_device, lp->isdn_channel);
2220
                                                isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
2221
                                                         ISDN_USAGE_NET);
2222
                                        }
2223
                                        dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
2224
                                        dev->usage[idx] |= ISDN_USAGE_NET;
2225
                                        strcpy(dev->num[idx], nr);
2226
                                        isdn_info_update();
2227
                                        dev->st_netdev[idx] = lp->netdev;
2228
                                        p->local.isdn_device = di;
2229
                                        p->local.isdn_channel = ch;
2230
                                        p->local.ppp_slot = -1;
2231
                                        p->local.flags |= ISDN_NET_CONNECTED;
2232
                                        p->local.dialstate = 7;
2233
                                        p->local.dtimer = 0;
2234
                                        p->local.outgoing = 0;
2235
                                        p->local.huptimer = 0;
2236
                                        p->local.hupflags |= ISDN_WAITCHARGE;
2237
                                        p->local.hupflags &= ~ISDN_HAVECHARGE;
2238
#ifdef CONFIG_ISDN_PPP
2239
                                        if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2240
                                                if (isdn_ppp_bind(lp) < 0) {
2241
                                                        isdn_net_unbind_channel(lp);
2242
                                                        restore_flags(flags);
2243
                                                        return 0;
2244
                                                }
2245
#endif
2246
                                        restore_flags(flags);
2247
                                        return 1;
2248
                                }
2249
                        }
2250
                }
2251
        }
2252
        /* If none of configured EAZ/MSN matched and not verbose, be silent */
2253
        if (!ematch || dev->net_verbose)
2254
                printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
2255
        restore_flags(flags);
2256
        return 0;
2257
}
2258
 
2259
/*
2260
 * Search list of net-interfaces for an interface with given name.
2261
 */
2262
isdn_net_dev *
2263
isdn_net_findif(char *name)
2264
{
2265
        isdn_net_dev *p = dev->netdev;
2266
 
2267
        while (p) {
2268
                if (!strcmp(p->local.name, name))
2269
                        return p;
2270
                p = (isdn_net_dev *) p->next;
2271
        }
2272
        return (isdn_net_dev *) NULL;
2273
}
2274
 
2275
/*
2276
 * Force a net-interface to dial out.
2277
 * This is called from the userlevel-routine below or
2278
 * from isdn_net_start_xmit().
2279
 */
2280
int
2281
isdn_net_force_dial_lp(isdn_net_local * lp)
2282
{
2283
        if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
2284
                int chi;
2285
                if (lp->phone[1]) {
2286
                        ulong flags;
2287
                        save_flags(flags);
2288
                        cli();
2289
                        /* Grab a free ISDN-Channel */
2290
                        if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
2291
                                                         lp->l3_proto,
2292
                                                         lp->pre_device,
2293
                                                 lp->pre_channel)) < 0) {
2294
                                printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
2295
                                restore_flags(flags);
2296
                                return -EAGAIN;
2297
                        }
2298
                        lp->dialstate = 1;
2299
                        lp->flags |= ISDN_NET_CONNECTED;
2300
                        /* Connect interface with channel */
2301
                        isdn_net_bind_channel(lp, chi);
2302
#ifdef CONFIG_ISDN_PPP
2303
                        if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2304
                                if (isdn_ppp_bind(lp) < 0) {
2305
                                        isdn_net_unbind_channel(lp);
2306
                                        restore_flags(flags);
2307
                                        return -EAGAIN;
2308
                                }
2309
#endif
2310
                        /* Initiate dialing */
2311
                        restore_flags(flags);
2312
                        isdn_net_dial();
2313
                        return 0;
2314
                } else
2315
                        return -EINVAL;
2316
        } else
2317
                return -EBUSY;
2318
}
2319
 
2320
/*
2321
 * Force a net-interface to dial out.
2322
 * This is always called from within userspace (ISDN_IOCTL_NET_DIAL).
2323
 */
2324
int
2325
isdn_net_force_dial(char *name)
2326
{
2327
        isdn_net_dev *p = isdn_net_findif(name);
2328
 
2329
        if (!p)
2330
                return -ENODEV;
2331
        return (isdn_net_force_dial_lp(&p->local));
2332
}
2333
 
2334
/*
2335
 * Allocate a new network-interface and initialize its data structures.
2336
 */
2337
char *
2338
isdn_net_new(char *name, struct device *master)
2339
{
2340
        isdn_net_dev *netdev;
2341
 
2342
        /* Avoid creating an existing interface */
2343
        if (isdn_net_findif(name)) {
2344
                printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
2345
                return NULL;
2346
        }
2347
        if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
2348
                printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
2349
                return NULL;
2350
        }
2351
        memset(netdev, 0, sizeof(isdn_net_dev));
2352
        if (name == NULL)
2353
                strcpy(netdev->local.name, "         ");
2354
        else
2355
                strcpy(netdev->local.name, name);
2356
        netdev->dev.name = netdev->local.name;
2357
        netdev->dev.priv = &netdev->local;
2358
        netdev->dev.init = isdn_net_init;
2359
        netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP;
2360
        if (master) {
2361
                /* Device shall be a slave */
2362
                struct device *p = (((isdn_net_local *) master->priv)->slave);
2363
                struct device *q = master;
2364
 
2365
                netdev->local.master = master;
2366
                /* Put device at end of slave-chain */
2367
                while (p) {
2368
                        q = p;
2369
                        p = (((isdn_net_local *) p->priv)->slave);
2370
                }
2371
                ((isdn_net_local *) q->priv)->slave = &(netdev->dev);
2372
                q->interrupt = 0;
2373
                q->tbusy = 0;
2374
                q->start = master->start;
2375
        } else {
2376
                /* Device shall be a master */
2377
                if (register_netdev(&netdev->dev) != 0) {
2378
                        printk(KERN_WARNING "isdn_net: Could not register net-device\n");
2379
                        kfree(netdev);
2380
                        return NULL;
2381
                }
2382
        }
2383
        netdev->local.magic = ISDN_NET_MAGIC;
2384
 
2385
#ifdef CONFIG_ISDN_PPP
2386
        netdev->mp_last = NULL; /* mpqueue is empty */
2387
        netdev->ib.next_num = 0;
2388
        netdev->ib.last = NULL;
2389
#endif
2390
        netdev->queue = &netdev->local;
2391
        netdev->local.last = &netdev->local;
2392
        netdev->local.netdev = netdev;
2393
        netdev->local.next = &netdev->local;
2394
 
2395
        netdev->local.isdn_device = -1;
2396
        netdev->local.isdn_channel = -1;
2397
        netdev->local.pre_device = -1;
2398
        netdev->local.pre_channel = -1;
2399
        netdev->local.exclusive = -1;
2400
        netdev->local.ppp_slot = -1;
2401
        netdev->local.pppbind = -1;
2402
        netdev->local.sav_skb = NULL;
2403
        netdev->local.first_skb = NULL;
2404
        netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
2405
        netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
2406
        netdev->local.triggercps = 6000;
2407
        netdev->local.slavedelay = 10 * HZ;
2408
        netdev->local.srobin = &netdev->dev;
2409
        netdev->local.hupflags = ISDN_INHUP;    /* Do hangup even on incoming calls */
2410
        netdev->local.onhtime = 10;     /* Default hangup-time for saving costs
2411
                                           of those who forget configuring this */
2412
        netdev->local.dialmax = 1;
2413
        netdev->local.flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL; /* Hangup before Callback, manual dial */
2414
        netdev->local.cbdelay = 25;     /* Wait 5 secs before Callback */
2415
        netdev->local.dialtimeout = -1;  /* Infinite Dial-Timeout */
2416
        netdev->local.dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
2417
        netdev->local.dialstarted = 0;   /* Jiffies of last dial-start */
2418
        netdev->local.dialwait_timer = 0;  /* Jiffies of earliest next dial-start */
2419
 
2420
        /* Put into to netdev-chain */
2421
        netdev->next = (void *) dev->netdev;
2422
        dev->netdev = netdev;
2423
        return netdev->dev.name;
2424
}
2425
 
2426
char *
2427
isdn_net_newslave(char *parm)
2428
{
2429
        char *p = strchr(parm, ',');
2430
        isdn_net_dev *n;
2431
        char newname[10];
2432
 
2433
        if (p) {
2434
                /* Slave-Name MUST not be empty */
2435
                if (!strlen(p + 1))
2436
                        return NULL;
2437
                strcpy(newname, p + 1);
2438
                *p = 0;
2439
                /* Master must already exist */
2440
                if (!(n = isdn_net_findif(parm)))
2441
                        return NULL;
2442
                /* Master must be a real interface, not a slave */
2443
                if (n->local.master)
2444
                        return NULL;
2445
                /* Master must not be started yet */
2446
                if (n->dev.start)
2447
                        return NULL;
2448
                return (isdn_net_new(newname, &(n->dev)));
2449
        }
2450
        return NULL;
2451
}
2452
 
2453
/*
2454
 * Set interface-parameters.
2455
 * Always set all parameters, so the user-level application is responsible
2456
 * for not overwriting existing setups. It has to get the current
2457
 * setup first, if only selected parameters are to be changed.
2458
 */
2459
int
2460
isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
2461
{
2462
        isdn_net_dev *p = isdn_net_findif(cfg->name);
2463
        ulong features;
2464
        int i;
2465
        int drvidx;
2466
        int chidx;
2467
        char drvid[25];
2468
 
2469
        if (p) {
2470
                /* See if any registered driver supports the features we want */
2471
                features = (1 << cfg->l2_proto) | (256 << cfg->l3_proto);
2472
                for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2473
                        if (dev->drv[i])
2474
                                if ((dev->drv[i]->interface->features & features) == features)
2475
                                        break;
2476
                if (i == ISDN_MAX_DRIVERS) {
2477
                        printk(KERN_WARNING "isdn_net: No driver with selected features\n");
2478
                        return -ENODEV;
2479
                }
2480
                if (p->local.p_encap != cfg->p_encap)
2481
                        if (p->dev.start) {
2482
                                printk(KERN_WARNING
2483
                                "%s: cannot change encap when if is up\n",
2484
                                       p->local.name);
2485
                                return -EBUSY;
2486
                        }
2487
                if (cfg->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
2488
#ifndef CONFIG_ISDN_PPP
2489
                        printk(KERN_WARNING "%s: SyncPPP support not configured\n",
2490
                               p->local.name);
2491
                        return -EINVAL;
2492
#else
2493
                        p->dev.type = ARPHRD_PPP;       /* change ARP type */
2494
                        p->dev.addr_len = 0;
2495
#endif
2496
                }
2497
                if (strlen(cfg->drvid)) {
2498
                        /* A bind has been requested ... */
2499
                        char *c,
2500
                        *e;
2501
 
2502
                        drvidx = -1;
2503
                        chidx = -1;
2504
                        strcpy(drvid, cfg->drvid);
2505
                        if ((c = strchr(drvid, ','))) {
2506
                                /* The channel-number is appended to the driver-Id with a comma */
2507
                                chidx = (int) simple_strtoul(c + 1, &e, 10);
2508
                                if (e == c)
2509
                                        chidx = -1;
2510
                                *c = '\0';
2511
                        }
2512
                        for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2513
                                /* Lookup driver-Id in array */
2514
                                if (!(strcmp(dev->drvid[i], drvid))) {
2515
                                        drvidx = i;
2516
                                        break;
2517
                                }
2518
                        if ((drvidx == -1) || (chidx == -1))
2519
                                /* Either driver-Id or channel-number invalid */
2520
                                return -ENODEV;
2521
                } else {
2522
                        /* Parameters are valid, so get them */
2523
                        drvidx = p->local.pre_device;
2524
                        chidx = p->local.pre_channel;
2525
                }
2526
                if (cfg->exclusive > 0) {
2527
                        int flags;
2528
 
2529
                        /* If binding is exclusive, try to grab the channel */
2530
                        save_flags(flags);
2531
                        if ((i = isdn_get_free_channel(ISDN_USAGE_NET, p->local.l2_proto,
2532
                                                       p->local.l3_proto,
2533
                                                       drvidx,
2534
                                                       chidx)) < 0) {
2535
                                /* Grab failed, because desired channel is in use */
2536
                                p->local.exclusive = -1;
2537
                                restore_flags(flags);
2538
                                return -EBUSY;
2539
                        }
2540
                        /* All went ok, so update isdninfo */
2541
                        dev->usage[i] = ISDN_USAGE_EXCLUSIVE;
2542
                        isdn_info_update();
2543
                        restore_flags(flags);
2544
                        p->local.exclusive = i;
2545
                } else {
2546
                        /* Non-exclusive binding or unbind. */
2547
                        p->local.exclusive = -1;
2548
                        if ((p->local.pre_device != -1) && (cfg->exclusive == -1)) {
2549
                                isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
2550
                                isdn_free_channel(p->local.pre_device, p->local.pre_channel, ISDN_USAGE_NET);
2551
                                drvidx = -1;
2552
                                chidx = -1;
2553
                        }
2554
                }
2555
                strcpy(p->local.msn, cfg->eaz);
2556
                p->local.pre_device = drvidx;
2557
                p->local.pre_channel = chidx;
2558
                p->local.onhtime = cfg->onhtime;
2559
                p->local.charge = cfg->charge;
2560
                p->local.l2_proto = cfg->l2_proto;
2561
                p->local.l3_proto = cfg->l3_proto;
2562
                p->local.cbdelay = cfg->cbdelay;
2563
                p->local.dialmax = cfg->dialmax;
2564
                p->local.triggercps = cfg->triggercps;
2565
                p->local.slavedelay = cfg->slavedelay * HZ;
2566
                p->local.pppbind = cfg->pppbind;
2567
                p->local.dialtimeout = cfg->dialtimeout >= 0 ? cfg->dialtimeout * HZ : -1;
2568
                p->local.dialwait    = cfg->dialwait * HZ;
2569
                if (cfg->secure)
2570
                        p->local.flags |= ISDN_NET_SECURE;
2571
                else
2572
                        p->local.flags &= ~ISDN_NET_SECURE;
2573
                if (cfg->cbhup)
2574
                        p->local.flags |= ISDN_NET_CBHUP;
2575
                else
2576
                        p->local.flags &= ~ISDN_NET_CBHUP;
2577
                switch (cfg->callback) {
2578
                        case 0:
2579
                                p->local.flags &= ~(ISDN_NET_CALLBACK | ISDN_NET_CBOUT);
2580
                                break;
2581
                        case 1:
2582
                                p->local.flags |= ISDN_NET_CALLBACK;
2583
                                p->local.flags &= ~ISDN_NET_CBOUT;
2584
                                break;
2585
                        case 2:
2586
                                p->local.flags |= ISDN_NET_CBOUT;
2587
                                p->local.flags &= ~ISDN_NET_CALLBACK;
2588
                                break;
2589
                }
2590
                p->local.flags &= ~ISDN_NET_DIALMODE_MASK;      /* first all bits off */
2591
                if (cfg->dialmode && !(cfg->dialmode & ISDN_NET_DIALMODE_MASK)) {
2592
                        /* old isdnctrl version, where only 0 or 1 is given */
2593
                        printk(KERN_WARNING
2594
                             "Old isdnctrl version detected! Please update.\n");
2595
                        p->local.flags |= ISDN_NET_DM_OFF; /* turn on 'off' bit */
2596
                }
2597
                else {
2598
                        p->local.flags |= cfg->dialmode;   /* turn on selected bits */
2599
                }
2600
                if (cfg->chargehup)
2601
                        p->local.hupflags |= ISDN_CHARGEHUP;
2602
                else
2603
                        p->local.hupflags &= ~ISDN_CHARGEHUP;
2604
                if (cfg->ihup)
2605
                        p->local.hupflags |= ISDN_INHUP;
2606
                else
2607
                        p->local.hupflags &= ~ISDN_INHUP;
2608
                if (cfg->chargeint > 10) {
2609
                        p->local.hupflags |= ISDN_CHARGEHUP | ISDN_HAVECHARGE | ISDN_MANCHARGE;
2610
                        p->local.chargeint = cfg->chargeint * HZ;
2611
                }
2612
                if (cfg->p_encap != p->local.p_encap) {
2613
                        if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
2614
                                p->dev.hard_header = NULL;
2615
#if (LINUX_VERSION_CODE < 0x02010F)
2616
                                p->dev.header_cache_bind = NULL;
2617
#else
2618
                                p->dev.hard_header_cache = NULL;
2619
#endif
2620
                                p->dev.header_cache_update = NULL;
2621
                                p->dev.flags = IFF_NOARP;
2622
                        } else {
2623
                                p->dev.hard_header = isdn_net_header;
2624
                                if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) {
2625
#if (LINUX_VERSION_CODE < 0x02010F)
2626
                                        p->dev.header_cache_bind = p->local.org_hcb;
2627
#else
2628
                                        p->dev.hard_header_cache = p->local.org_hhc;
2629
#endif
2630
                                        p->dev.header_cache_update = p->local.org_hcu;
2631
                                        p->dev.flags = IFF_BROADCAST | IFF_MULTICAST;
2632
                                } else {
2633
#if (LINUX_VERSION_CODE < 0x02010F)
2634
                                        p->dev.header_cache_bind = NULL;
2635
#else
2636
                                        p->dev.hard_header_cache = NULL;
2637
#endif
2638
                                        p->dev.header_cache_update = NULL;
2639
                                        /*
2640
                                         * paul: IFF_SOFTHEADERS was added in
2641
                                         * 2.0.33?? Does this make sense?
2642
                                         */
2643
                                        p->dev.flags = IFF_NOARP /* | IFF_SOFTHEADERS */;
2644
                                }
2645
                        }
2646
                }
2647
                p->local.p_encap = cfg->p_encap;
2648
                return 0;
2649
        }
2650
        return -ENODEV;
2651
}
2652
 
2653
/*
2654
 * Perform get-interface-parameters.ioctl
2655
 */
2656
int
2657
isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
2658
{
2659
        isdn_net_dev *p = isdn_net_findif(cfg->name);
2660
 
2661
        if (p) {
2662
                strcpy(cfg->eaz, p->local.msn);
2663
                cfg->exclusive = p->local.exclusive;
2664
                if (p->local.pre_device >= 0) {
2665
                        sprintf(cfg->drvid, "%s,%d", dev->drvid[p->local.pre_device],
2666
                                p->local.pre_channel);
2667
                } else
2668
                        cfg->drvid[0] = '\0';
2669
                cfg->onhtime = p->local.onhtime;
2670
                cfg->charge = p->local.charge;
2671
                cfg->l2_proto = p->local.l2_proto;
2672
                cfg->l3_proto = p->local.l3_proto;
2673
                cfg->p_encap = p->local.p_encap;
2674
                cfg->secure = (p->local.flags & ISDN_NET_SECURE) ? 1 : 0;
2675
                cfg->callback = 0;
2676
                if (p->local.flags & ISDN_NET_CALLBACK)
2677
                        cfg->callback = 1;
2678
                if (p->local.flags & ISDN_NET_CBOUT)
2679
                        cfg->callback = 2;
2680
                cfg->cbhup = (p->local.flags & ISDN_NET_CBHUP) ? 1 : 0;
2681
                cfg->dialmode = p->local.flags & ISDN_NET_DIALMODE_MASK;
2682
                cfg->chargehup = (p->local.hupflags & 4) ? 1 : 0;
2683
                cfg->ihup = (p->local.hupflags & 8) ? 1 : 0;
2684
                cfg->cbdelay = p->local.cbdelay;
2685
                cfg->dialmax = p->local.dialmax;
2686
        cfg->triggercps = p->local.triggercps;
2687
                cfg->slavedelay = p->local.slavedelay / HZ;
2688
                cfg->chargeint = (p->local.hupflags & ISDN_CHARGEHUP) ?
2689
                    (p->local.chargeint / HZ) : 0;
2690
                cfg->pppbind = p->local.pppbind;
2691
                cfg->dialtimeout = p->local.dialtimeout >= 0 ? p->local.dialtimeout / HZ : -1;
2692
                cfg->dialwait = p->local.dialwait / HZ;
2693
                if (p->local.slave)
2694
                        strcpy(cfg->slave, ((isdn_net_local *) p->local.slave->priv)->name);
2695
                else
2696
                        cfg->slave[0] = '\0';
2697
                if (p->local.master)
2698
                        strcpy(cfg->master, ((isdn_net_local *) p->local.master->priv)->name);
2699
                else
2700
                        cfg->master[0] = '\0';
2701
                return 0;
2702
        }
2703
        return -ENODEV;
2704
}
2705
 
2706
/*
2707
 * Add a phone-number to an interface.
2708
 */
2709
int
2710
isdn_net_addphone(isdn_net_ioctl_phone * phone)
2711
{
2712
        isdn_net_dev *p = isdn_net_findif(phone->name);
2713
        isdn_net_phone *n;
2714
 
2715
        if (isdn_net_checkwild(phone->phone) && (phone->outgoing & 1))
2716
                return -EINVAL;
2717
        if (p) {
2718
                if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
2719
                        return -ENOMEM;
2720
                strcpy(n->num, phone->phone);
2721
                n->next = p->local.phone[phone->outgoing & 1];
2722
                p->local.phone[phone->outgoing & 1] = n;
2723
                return 0;
2724
        }
2725
        return -ENODEV;
2726
}
2727
 
2728
/*
2729
 * Return a string of all phone-numbers of an interface.
2730
 */
2731
int
2732
isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones)
2733
{
2734
        isdn_net_dev *p = isdn_net_findif(phone->name);
2735
        int inout = phone->outgoing & 1;
2736
        int more = 0;
2737
        int count = 0;
2738
        isdn_net_phone *n;
2739
        int flags;
2740
        int ret;
2741
 
2742
        if (!p)
2743
                return -ENODEV;
2744
        save_flags(flags);
2745
        cli();
2746
        inout &= 1;
2747
        for (n = p->local.phone[inout]; n; n = n->next) {
2748
                if (more) {
2749
                        put_user(' ', phones++);
2750
                        count++;
2751
                }
2752
                if ((ret = copy_to_user(phones, n->num, strlen(n->num) + 1))) {
2753
                        restore_flags(flags);
2754
                        return ret;
2755
                }
2756
                phones += strlen(n->num);
2757
                count += strlen(n->num);
2758
                more = 1;
2759
        }
2760
        put_user(0, phones);
2761
        count++;
2762
        restore_flags(flags);
2763
        return count;
2764
}
2765
 
2766
/*
2767
 * Delete a phone-number from an interface.
2768
 */
2769
 
2770
int
2771
isdn_net_delphone(isdn_net_ioctl_phone * phone)
2772
{
2773
        isdn_net_dev *p = isdn_net_findif(phone->name);
2774
        int inout = phone->outgoing & 1;
2775
        isdn_net_phone *n;
2776
        isdn_net_phone *m;
2777
        int flags;
2778
 
2779
        if (p) {
2780
                save_flags(flags);
2781
                cli();
2782
                n = p->local.phone[inout];
2783
                m = NULL;
2784
                while (n) {
2785
                        if (!strcmp(n->num, phone->phone)) {
2786
                                if (p->local.dial == n)
2787
                                        p->local.dial = n->next;
2788
                                if (m)
2789
                                        m->next = n->next;
2790
                                else
2791
                                        p->local.phone[inout] = n->next;
2792
                                kfree(n);
2793
                                restore_flags(flags);
2794
                                return 0;
2795
                        }
2796
                        m = n;
2797
                        n = (isdn_net_phone *) n->next;
2798
                }
2799
                restore_flags(flags);
2800
                return -EINVAL;
2801
        }
2802
        return -ENODEV;
2803
}
2804
 
2805
/*
2806
 * Delete all phone-numbers of an interface.
2807
 */
2808
static int
2809
isdn_net_rmallphone(isdn_net_dev * p)
2810
{
2811
        isdn_net_phone *n;
2812
        isdn_net_phone *m;
2813
        int flags;
2814
        int i;
2815
 
2816
        save_flags(flags);
2817
        cli();
2818
        for (i = 0; i < 2; i++) {
2819
                n = p->local.phone[i];
2820
                while (n) {
2821
                        m = n->next;
2822
                        kfree(n);
2823
                        n = m;
2824
                }
2825
                p->local.phone[i] = NULL;
2826
        }
2827
        p->local.dial = NULL;
2828
        restore_flags(flags);
2829
        return 0;
2830
}
2831
 
2832
/*
2833
 * Force a hangup of a network-interface.
2834
 */
2835
int
2836
isdn_net_force_hangup(char *name)
2837
{
2838
        isdn_net_dev *p = isdn_net_findif(name);
2839
        struct device *q;
2840
 
2841
        if (p) {
2842
                if (p->local.isdn_device < 0)
2843
                        return 1;
2844
                q = p->local.slave;
2845
                /* If this interface has slaves, do a hangup for them also. */
2846
                while (q) {
2847
                        isdn_net_hangup(q);
2848
                        q = (((isdn_net_local *) q->priv)->slave);
2849
                }
2850
                isdn_net_hangup(&p->dev);
2851
                return 0;
2852
        }
2853
        return -ENODEV;
2854
}
2855
 
2856
/*
2857
 * Helper-function for isdn_net_rm: Do the real work.
2858
 */
2859
static int
2860
isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
2861
{
2862
        int flags;
2863
 
2864
        save_flags(flags);
2865
        cli();
2866
        if (p->local.master) {
2867
                /* If it's a slave, it may be removed even if it is busy. However
2868
                 * it has to be hung up first.
2869
                 */
2870
                isdn_net_hangup(&p->dev);
2871
                p->dev.start = 0;
2872
        }
2873
        if (p->dev.start) {
2874
                restore_flags(flags);
2875
                return -EBUSY;
2876
        }
2877
        /* Free all phone-entries */
2878
        isdn_net_rmallphone(p);
2879
        /* If interface is bound exclusive, free channel-usage */
2880
        if (p->local.exclusive != -1)
2881
                isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
2882
        if (p->local.master) {
2883
                /* It's a slave-device, so update master's slave-pointer if necessary */
2884
                if (((isdn_net_local *) (p->local.master->priv))->slave == &p->dev)
2885
                        ((isdn_net_local *) (p->local.master->priv))->slave = p->local.slave;
2886
        } else
2887
                /* Unregister only if it's a master-device */
2888
                unregister_netdev(&p->dev);
2889
        /* Unlink device from chain */
2890
        if (q)
2891
                q->next = p->next;
2892
        else
2893
                dev->netdev = p->next;
2894
        if (p->local.slave) {
2895
                /* If this interface has a slave, remove it also */
2896
                char *slavename = ((isdn_net_local *) (p->local.slave->priv))->name;
2897
                isdn_net_dev *n = dev->netdev;
2898
                q = NULL;
2899
                while (n) {
2900
                        if (!strcmp(n->local.name, slavename)) {
2901
                                isdn_net_realrm(n, q);
2902
                                break;
2903
                        }
2904
                        q = n;
2905
                        n = (isdn_net_dev *) n->next;
2906
                }
2907
        }
2908
        /* If no more net-devices remain, disable auto-hangup timer */
2909
        if (dev->netdev == NULL)
2910
                isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
2911
        restore_flags(flags);
2912
 
2913
        kfree(p);
2914
 
2915
        return 0;
2916
}
2917
 
2918
/*
2919
 * Remove a single network-interface.
2920
 */
2921
int
2922
isdn_net_rm(char *name)
2923
{
2924
        isdn_net_dev *p;
2925
        isdn_net_dev *q;
2926
 
2927
        /* Search name in netdev-chain */
2928
        p = dev->netdev;
2929
        q = NULL;
2930
        while (p) {
2931
                if (!strcmp(p->local.name, name))
2932
                        return (isdn_net_realrm(p, q));
2933
                q = p;
2934
                p = (isdn_net_dev *) p->next;
2935
        }
2936
        /* If no more net-devices remain, disable auto-hangup timer */
2937
        if (dev->netdev == NULL)
2938
                isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
2939
        return -ENODEV;
2940
}
2941
 
2942
/*
2943
 * Remove all network-interfaces
2944
 */
2945
int
2946
isdn_net_rmall(void)
2947
{
2948
        int flags;
2949
        int ret;
2950
 
2951
        /* Walk through netdev-chain */
2952
        save_flags(flags);
2953
        cli();
2954
        while (dev->netdev) {
2955
                if (!dev->netdev->local.master) {
2956
                        /* Remove master-devices only, slaves get removed with their master */
2957
                        if ((ret = isdn_net_realrm(dev->netdev, NULL))) {
2958
                                restore_flags(flags);
2959
                                return ret;
2960
                        }
2961
                }
2962
        }
2963
        dev->netdev = NULL;
2964
        restore_flags(flags);
2965
        return 0;
2966
}
2967
 
2968
/*
2969
 * helper function to flush device queues
2970
 * the better place would be net/core/dev.c
2971
 */
2972
static void
2973
dev_purge_queues(struct device *dev)
2974
{
2975
        int i;
2976
        for (i = 0; i < DEV_NUMBUFFS; i++) {
2977
                struct sk_buff *skb;
2978
                while ((skb = skb_dequeue(&dev->buffs[i])))
2979
                        dev_kfree_skb(skb, FREE_WRITE);
2980
        }
2981
 
2982
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.