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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [isdn_net.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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