1 /* $Id: isdn_net.c,v 1.4 1996/02/19 15:23:38 fritz Exp fritz $
2 *
3 * Linux ISDN subsystem, network interfaces and related functions (linklevel).
4 *
5 * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.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: isdn_net.c,v $
24 * Revision 1.4 1996/02/19 15:23:38 fritz
25 * Bugfix: Sync-PPP packets got compressed twice, when resent due to
26 * send-queue-full reject.
27 *
28 * Revision 1.3 1996/02/11 02:22:28 fritz
29 * Changed status- receive-callbacks to use pointer-arrays for finding
30 * a corresponding interface instead of looping over all interfaces.
31 * Activate Auto-hangup-timer only when interface is online.
32 * Some bugfixes in the dialing-statemachine.
33 * Lot of bugfixes in sk_buff'ized encapsulation handling.
34 * For speedup connection-setup after dialing, remember sk_buf that triggered
35 * dialing.
36 * Fixed isdn_net_log_packet according to different encapsulations.
37 * Correct ARP-handling for ETHERNET-encapsulation.
38 *
39 * Revision 1.2 1996/01/22 05:05:12 fritz
40 * Changed returncode-logic for isdn_net_start_xmit() and it's
41 * helper-functions.
42 * Changed handling of buildheader for RAWIP and ETHERNET-encapsulation.
43 *
44 * Revision 1.1 1996/01/09 04:12:34 fritz
45 * Initial revision
46 *
47 */
48
49 #ifndef STANDALONE
50 #include <linux/config.h>
51 #endif
52 #define __NO_VERSION__
53 #include <linux/module.h>
54 #include <linux/isdn.h>
55 #include <linux/if_arp.h>
56 #include "isdn_common.h"
57 #include "isdn_net.h"
58 #ifdef CONFIG_ISDN_PPP
59 #include "isdn_ppp.h"
60 #endif
61
62 /* In ksyms.c, but why not in some .h ??? */
63 extern int arp_find(unsigned char *, u32, struct device *, u32,
64 struct sk_buff *);
65
66 /* Prototypes */
67
68 int isdn_net_force_dial_lp(isdn_net_local *);
69 static int isdn_net_wildmat(char *s, char *p);
70 static int isdn_net_start_xmit(struct sk_buff *, struct device *);
71 static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
72
73 char *isdn_net_revision = "$Revision: 1.4 $";
74
75 /*
76 * Code for raw-networking over ISDN
77 */
78
79 static void
80 isdn_net_reset(struct device *dev)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
81 {
82 ulong flags;
83
84 save_flags(flags);
85 cli(); /* Avoid glitch on writes to CMD regs */
86 dev->interrupt = 0;
87 dev->tbusy = 0;
88 restore_flags(flags);
89 }
90
91 /* Open/initialize the board. */
92 static int
93 isdn_net_open(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
94 {
95 int i;
96 struct device *p;
97
98 isdn_net_reset(dev);
99 dev->start = 1;
100 /* Fill in the MAC-level header. */
101 for (i = 0; i < ETH_ALEN - sizeof(ulong); i++)
102 dev->dev_addr[i] = 0xfc;
103 memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(ulong));
104
105 /* If this interface has slaves, start them also */
106
107 if ((p = (((isdn_net_local *) dev->priv)->slave))) {
108 while (p) {
109 isdn_net_reset(p);
110 p->start = 1;
111 p = (((isdn_net_local *) p->priv)->slave);
112 }
113 }
114
115 isdn_MOD_INC_USE_COUNT();
116 return 0;
117 }
118
119 /*
120 * Assign an ISDN-channel to a net-interface
121 */
122 static void
123 isdn_net_bind_channel(isdn_net_local * lp, int idx)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
124 {
125 ulong flags;
126
127 save_flags(flags);
128 cli();
129 lp->isdn_device = dev->drvmap[idx];
130 lp->isdn_channel = dev->chanmap[idx];
131 dev->rx_netdev[idx] = lp->netdev;
132 dev->st_netdev[idx] = lp->netdev;
133 restore_flags(flags);
134 }
135
136 /*
137 * Perform auto-hangup and cps-calculation for net-interfaces.
138 *
139 * auto-hangup:
140 * Increment idle-counter (this counter is reset on any incoming or
141 * outgoing packet), if counter exceeds configured limit either do a
142 * hangup immediately or - if configured - wait until just before the next
143 * charge-info.
144 *
145 * cps-calculation (needed for dynamic channel-bundling):
146 * Since this function is called every second, simply reset the
147 * byte-counter of the interface after copying it to the cps-variable.
148 */
149 void
150 isdn_net_autohup()
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
151 {
152 isdn_net_dev *p = dev->netdev;
153 int anymore;
154 ulong flags;
155
156 save_flags(flags);
157 cli();
158 anymore = 0;
159 while (p) {
160 isdn_net_local *l = (isdn_net_local *) & (p->local);
161 l->cps = l->transcount;
162 l->transcount = 0;
163 if (dev->net_verbose > 3)
164 printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
165 if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
166 anymore = 1;
167 l->huptimer++;
168 if ((l->onhtime) && (l->huptimer > l->onhtime))
169 if (l->outgoing) {
170 if (l->hupflags & 4) {
171 if (l->hupflags & 1)
172 isdn_net_hangup(&p->dev);
173 else if (jiffies - l->chargetime > l->chargeint)
174 isdn_net_hangup(&p->dev);
175 } else
176 isdn_net_hangup(&p->dev);
177 } else if (l->hupflags & 8)
178 isdn_net_hangup(&p->dev);
179 }
180 p = (isdn_net_dev *) p->next;
181 }
182 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP,anymore);
183 restore_flags(flags);
184 }
185
186 /*
187 * Handle status-messages from ISDN-interfacecard.
188 * This function is called from within the main-status-dispatcher
189 * isdn_status_callback, which itself is called from the lowlevel-driver.
190 * Return: 1 = Event handled, 0 = not for us or unknown Event.
191 */
192 int
193 isdn_net_stat_callback(int idx, int cmd)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
194 {
195 isdn_net_dev *p = dev->st_netdev[idx];
196
197 if (p) {
198 isdn_net_local *lp = &(p->local);
199 switch (cmd) {
200 case ISDN_STAT_BSENT:
201 /* A packet has successfully been sent out */
202 if ((lp->flags & ISDN_NET_CONNECTED) &&
203 (!lp->dialstate)) {
204 lp->stats.tx_packets++;
205 if (clear_bit(0,(void*)&(p->dev.tbusy)))
206 mark_bh(NET_BH);
207 }
208 return 1;
209 case ISDN_STAT_DCONN:
210 /* D-Channel is up */
211 if (lp->dialstate == 4 || lp->dialstate == 7
212 || lp->dialstate == 8) {
213 lp->dialstate++;
214 return 1;
215 }
216 break;
217 case ISDN_STAT_DHUP:
218 /* Either D-Channel-hangup or error during dialout */
219 if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
220 lp->flags &= ~ISDN_NET_CONNECTED;
221 isdn_free_channel(lp->isdn_device, lp->isdn_channel,
222 ISDN_USAGE_NET);
223 #ifdef CONFIG_ISDN_PPP
224 isdn_ppp_free(lp);
225 #endif
226 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
227 printk(KERN_INFO "%s: remote hangup\n", lp->name);
228 printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
229 lp->charge);
230 lp->isdn_device = -1;
231 lp->isdn_channel = -1;
232 dev->st_netdev[idx] = NULL;
233 dev->rx_netdev[idx] = NULL;
234 return 1;
235 }
236 break;
237 case ISDN_STAT_BCONN:
238 /* B-Channel is up */
239 if (lp->dialstate >= 5 && lp->dialstate <= 10) {
240 if (lp->dialstate <= 6) {
241 dev->usage[idx] |= ISDN_USAGE_OUTGOING;
242 isdn_info_update();
243 } else
244 dev->rx_netdev[idx] = p;
245 lp->dialstate = 0;
246 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP,1);
247 printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
248 /* If first Chargeinfo comes before B-Channel connect,
249 * we correct the timestamp here.
250 */
251 lp->chargetime = jiffies;
252 /* Immediately send first skb to speed up arp */
253 if (lp->first_skb) {
254 if (!(isdn_net_xmit(&p->dev,lp,lp->first_skb)))
255 lp->first_skb = NULL;
256 }
257 return 1;
258 }
259 break;
260 case ISDN_STAT_NODCH:
261 /* No D-Channel avail. */
262 if (lp->dialstate == 4) {
263 lp->dialstate--;
264 return 1;
265 }
266 break;
267 case ISDN_STAT_CINF:
268 /* Charge-info from TelCo. Calculate interval between
269 * charge-infos and set timestamp for last info for
270 * usage by isdn_net_autohup()
271 */
272 lp->charge++;
273 if (lp->hupflags & 2) {
274 lp->hupflags &= ~1;
275 lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
276 }
277 if (lp->hupflags & 1)
278 lp->hupflags |= 2;
279 lp->chargetime = jiffies;
280 return 1;
281 }
282 }
283 return 0;
284 }
285
286 /*
287 * Check, if a numer contains wilcard-characters, in which case it
288 * is for incoming purposes only.
289 */
290 static int
291 isdn_net_checkwild(char *num)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
292 {
293 return ((strchr(num, '?')) ||
294 (strchr(num, '*')) ||
295 (strchr(num, '[')) ||
296 (strchr(num, ']')) ||
297 (strchr(num, '^')));
298 }
299
300 /*
301 * Perform dialout for net-interfaces and timeout-handling for
302 * D-Channel-up and B-Channel-up Messages.
303 * This function is initially called from within isdn_net_start_xmit() or
304 * or isdn_net_find_icall() after initializing the dialstate for an
305 * interface. If further calls are needed, the function schedules itself
306 * for a timer-callback via isdn_timer_function().
307 * The dialstate is also affected by incoming status-messages from
308 * the ISDN-Channel which are handled in isdn_net_stat_callback() above.
309 */
310 void
311 isdn_net_dial(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
312 {
313 isdn_net_dev *p = dev->netdev;
314 int anymore = 0;
315 int i;
316 isdn_ctrl cmd;
317
318 while (p) {
319 switch (p->local.dialstate) {
320 case 0:
321 /* Nothing to do for this interface */
322 break;
323 case 1:
324 /* Initiate dialout. Set phone-number-pointer to first number
325 * of interface.
326 */
327 p->local.dial = p->local.phone[1];
328 anymore = 1;
329 p->local.dialstate++;
330 break;
331 /* Prepare dialing. Clear EAZ, then set EAZ. */
332 case 2:
333 cmd.driver = p->local.isdn_device;
334 cmd.arg = p->local.isdn_channel;
335 cmd.command = ISDN_CMD_CLREAZ;
336 dev->drv[p->local.isdn_device]->interface->command(&cmd);
337 sprintf(cmd.num, "%s", isdn_map_eaz2msn(p->local.msn, cmd.driver));
338 cmd.command = ISDN_CMD_SETEAZ;
339 dev->drv[p->local.isdn_device]->interface->command(&cmd);
340 p->local.dialretry = 0;
341 anymore = 1;
342 p->local.dialstate++;
343 break;
344 case 3:
345 /* Setup interface, dial current phone-number, switch to next number.
346 * If list of phone-numbers is exhausted, increment
347 * retry-counter.
348 */
349 cmd.driver = p->local.isdn_device;
350 cmd.command = ISDN_CMD_SETL2;
351 cmd.arg = p->local.isdn_channel + (p->local.l2_proto << 8);
352 dev->drv[p->local.isdn_device]->interface->command(&cmd);
353 cmd.driver = p->local.isdn_device;
354 cmd.command = ISDN_CMD_SETL3;
355 cmd.arg = p->local.isdn_channel + (p->local.l3_proto << 8);
356 dev->drv[p->local.isdn_device]->interface->command(&cmd);
357 cmd.driver = p->local.isdn_device;
358 cmd.arg = p->local.isdn_channel;
359 p->local.huptimer = 0;
360 p->local.outgoing = 1;
361 p->local.hupflags |= 1;
362 if (!strcmp(p->local.dial->num, "LEASED")) {
363 p->local.dialstate = 4;
364 printk(KERN_INFO "%s: Open leased line ...\n", p->local.name);
365 } else {
366 cmd.command = ISDN_CMD_DIAL;
367 sprintf(cmd.num, "%s,%s,7,0", p->local.dial->num,
368 isdn_map_eaz2msn(p->local.msn, cmd.driver));
369 i = isdn_dc2minor(p->local.isdn_device, p->local.isdn_channel);
370 if (i >= 0) {
371 strcpy(dev->num[i], p->local.dial->num);
372 isdn_info_update();
373 }
374 printk(KERN_INFO "%s: dialing %d %s...\n", p->local.name,
375 p->local.dialretry, p->local.dial->num);
376 /*
377 * Switch to next number or back to start if at end of list.
378 */
379 if (!(p->local.dial = (isdn_net_phone *) p->local.dial->next)) {
380 p->local.dial = p->local.phone[1];
381 p->local.dialretry++;
382 }
383 p->local.dtimer = 0;
384 #ifdef ISDN_DEBUG_NET_DIAL
385 printk(KERN_DEBUG "dial: d=%d c=%d\n", p->local.isdn_device,
386 p->local.isdn_channel);
387 #endif
388 dev->drv[p->local.isdn_device]->interface->command(&cmd);
389 }
390 anymore = 1;
391 p->local.dialstate++;
392 break;
393 case 4:
394 /* Wait for D-Channel-connect or incoming call, if passive
395 * callback configured. If timeout and max retries not
396 * reached, switch back to state 3.
397 */
398 if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT10)
399 if (p->local.dialretry < p->local.dialmax) {
400 p->local.dialstate = 3;
401 } else
402 isdn_net_hangup(&p->dev);
403 anymore = 1;
404 break;
405 case 5:
406 /* Got D-Channel-Connect, send B-Channel-request */
407 cmd.driver = p->local.isdn_device;
408 cmd.arg = p->local.isdn_channel;
409 cmd.command = ISDN_CMD_ACCEPTB;
410 anymore = 1;
411 p->local.dtimer = 0;
412 p->local.dialstate++;
413 dev->drv[p->local.isdn_device]->interface->command(&cmd);
414 break;
415 case 6:
416 /* Wait for B- or D-Channel-connect. If timeout,
417 * switch back to state 3.
418 */
419 #ifdef ISDN_DEBUG_NET_DIAL
420 printk(KERN_DEBUG "dialtimer2: %d\n", p->local.dtimer);
421 #endif
422 if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT10)
423 p->local.dialstate = 3;
424 anymore = 1;
425 break;
426 case 7:
427 /* Got incoming Call, setup L2 and L3 protocols,
428 * then wait for D-Channel-connect
429 */
430 #ifdef ISDN_DEBUG_NET_DIAL
431 printk(KERN_DEBUG "dialtimer4: %d\n", p->local.dtimer);
432 #endif
433 cmd.driver = p->local.isdn_device;
434 cmd.command = ISDN_CMD_SETL2;
435 cmd.arg = p->local.isdn_channel + (p->local.l2_proto << 8);
436 dev->drv[p->local.isdn_device]->interface->command(&cmd);
437 cmd.driver = p->local.isdn_device;
438 cmd.command = ISDN_CMD_SETL3;
439 cmd.arg = p->local.isdn_channel + (p->local.l3_proto << 8);
440 dev->drv[p->local.isdn_device]->interface->command(&cmd);
441 if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT15)
442 isdn_net_hangup(&p->dev);
443 else {
444 anymore = 1;
445 p->local.dialstate++;
446 }
447 break;
448 case 9:
449 /* Got incoming D-Channel-Connect, send B-Channel-request */
450 cmd.driver = p->local.isdn_device;
451 cmd.arg = p->local.isdn_channel;
452 cmd.command = ISDN_CMD_ACCEPTB;
453 dev->drv[p->local.isdn_device]->interface->command(&cmd);
454 anymore = 1;
455 p->local.dtimer = 0;
456 p->local.dialstate++;
457 break;
458 case 8:
459 case 10:
460 /* Wait for B- or D-channel-connect */
461 #ifdef ISDN_DEBUG_NET_DIAL
462 printk(KERN_DEBUG "dialtimer4: %d\n", p->local.dtimer);
463 #endif
464 if (p->local.dtimer++ > ISDN_TIMER_DTIMEOUT10)
465 isdn_net_hangup(&p->dev);
466 else
467 anymore = 1;
468 break;
469 default:
470 printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
471 p->local.dialstate, p->local.name);
472 }
473 p = (isdn_net_dev *) p->next;
474 }
475 isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);
476 }
477
478 /*
479 * Send-data-helpfunction for net-interfaces
480 */
481 int
482 isdn_net_send(u_char * buf, int di, int ch, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
483 {
484 int l;
485
486 if ((l = dev->drv[di]->interface->writebuf(di, ch, buf, len, 0)) == len)
487 return 1;
488 /* Device driver queue full (or packet > 4000 bytes, should never
489 * happen)
490 */
491 if (l == -EINVAL)
492 printk(KERN_ERR "isdn_net: Huh, sending pkt too big!\n");
493 return 0;
494 }
495
496 /*
497 * Perform hangup for a net-interface.
498 */
499 void
500 isdn_net_hangup(struct device *d)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
501 {
502 isdn_net_local *lp = (isdn_net_local *) d->priv;
503 isdn_ctrl cmd;
504 ulong flags;
505
506 save_flags(flags);
507 cli();
508 if (lp->flags & ISDN_NET_CONNECTED) {
509 printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
510 lp->dialstate = 0;
511 dev->rx_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
512 dev->st_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
513 isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
514 #ifdef CONFIG_ISDN_PPP
515 isdn_ppp_free(lp);
516 #endif
517 lp->flags &= ~ISDN_NET_CONNECTED;
518 cmd.driver = lp->isdn_device;
519 cmd.command = ISDN_CMD_HANGUP;
520 cmd.arg = lp->isdn_channel;
521 (void) dev->drv[cmd.driver]->interface->command(&cmd);
522 printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
523 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
524 lp->isdn_device = -1;
525 lp->isdn_channel = -1;
526 }
527 restore_flags(flags);
528 }
529
530 typedef struct {
531 unsigned short source;
532 unsigned short dest;
533 } ip_ports;
534
535 static void
536 isdn_net_log_packet(u_char * buf, isdn_net_local * lp)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
537 {
538 u_char *p = buf;
539 unsigned short proto = ETH_P_IP;
540 int data_ofs;
541 int len;
542 ip_ports *ipp;
543 char addinfo[100];
544
545 addinfo[0] = '\0';
546 switch (lp->p_encap) {
547 case ISDN_NET_ENCAP_IPTYP:
548 proto = ntohs(*(unsigned short *)&buf[0]);
549 p = &buf[2];
550 break;
551 case ISDN_NET_ENCAP_ETHER:
552 proto = ntohs(*(unsigned short *)&buf[12]);
553 p = &buf[14];
554 break;
555 case ISDN_NET_ENCAP_CISCOHDLC:
556 proto = ntohs(*(unsigned short *)&buf[2]);
557 p = &buf[4];
558 break;
559 case ISDN_NET_ENCAP_SYNCPPP:
560 len = 4;
561 #ifdef CONFIG_ISDN_MPP
562 if (lp->ppp_minor!=-1) {
563 if (ippp_table[lp->ppp_minor].mpppcfg &
564 SC_MP_PROT) {
565 if (ippp_table[lp->ppp_minor].mpppcfg &
566 SC_OUT_SHORT_SEQ)
567 len = 7;
568 else
569 len = 9;
570 }
571 }
572 #endif
573 p = &buf[len];
574 break;
575 }
576 data_ofs = ((p[0] & 15) * 4);
577 switch (proto) {
578 case ETH_P_IP:
579 switch (p[9]) {
580 case 1:
581 strcpy(addinfo, " ICMP");
582 break;
583 case 2:
584 strcpy(addinfo, " IGMP");
585 break;
586 case 4:
587 strcpy(addinfo, " IPIP");
588 break;
589 case 6:
590 ipp = (ip_ports *) (&p[data_ofs]);
591 sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
592 ntohs(ipp->dest));
593 break;
594 case 8:
595 strcpy(addinfo, " EGP");
596 break;
597 case 12:
598 strcpy(addinfo, " PUP");
599 break;
600 case 17:
601 ipp = (ip_ports *) (&p[data_ofs]);
602 sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
603 ntohs(ipp->dest));
604 break;
605 case 22:
606 strcpy(addinfo, " IDP");
607 break;
608 }
609 printk(KERN_INFO "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
610 p[12], p[13], p[14], p[15],
611 p[16], p[17], p[18], p[19],
612 addinfo);
613 break;
614 case ETH_P_ARP:
615 printk(KERN_INFO "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
616 p[14], p[15], p[16], p[17],
617 p[24], p[25], p[26], p[27]);
618 break;
619 }
620 }
621
622 /*
623 * Generic routine to send out an skbuf.
624 * If lowlevel-device does not support supports skbufs, use
625 * standard send-routine, else sind directly.
626 *
627 * Return: 0 on success, !0 on failure.
628 * Side-effects: ndev->tbusy is cleared on success.
629 */
630 int
631 isdn_net_send_skb(struct device *ndev, isdn_net_local *lp,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
632 struct sk_buff *skb)
633 {
634 int ret;
635
636 lp->transcount += skb->len;
637 if (dev->drv[lp->isdn_device]->interface->writebuf_skb)
638 ret = dev->drv[lp->isdn_device]->interface->
639 writebuf_skb(lp->isdn_device, lp->isdn_channel, skb);
640 else {
641 if ((ret = isdn_net_send(skb->data, lp->isdn_device,
642 lp->isdn_channel, skb->len)))
643 dev_kfree_skb(skb, FREE_WRITE);
644 }
645
646 if (ret)
647 clear_bit(0, (void *)&(ndev->tbusy));
648 return (!ret);
649 }
650
651
652 /*
653 * Helper function for isdn_net_start_xmit.
654 * When called, the connection is already established.
655 * Based on cps-calculation, check if device is overloaded.
656 * If so, and if a slave exists, trigger dialing for it.
657 * If any slave is online, deliver packets using a simple round robin
658 * scheme.
659 *
660 * Return: 0 on success, !0 on failure.
661 */
662
663 static int
664 isdn_net_xmit(struct device *ndev, isdn_net_local *lp, struct sk_buff *skb)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
665 {
666 int ret;
667
668 /* For the other encaps the header has allready been built */
669 #ifdef CONFIG_ISDN_PPP
670 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
671 return (isdn_ppp_xmit(skb, ndev));
672 #endif
673 /* Reset hangup-timeout */
674 lp->huptimer = 0;
675 if (lp->cps > 7000) {
676 /* Device overloaded */
677
678 /*
679 * Packet-delivery via round-robin over master
680 * and all connected slaves.
681 */
682 if (lp->master)
683 /* Slaves always deliver themselves */
684 ret = isdn_net_send_skb(ndev, lp, skb);
685 else {
686 isdn_net_local *slp = (isdn_net_local *) (lp->srobin->priv);
687 /* Master delivers via srobin and maintains srobin */
688 if (lp->srobin == ndev)
689 ret = isdn_net_send_skb(ndev, lp, skb);
690 else
691 ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin);
692 lp->srobin = (slp->slave) ? slp->slave : ndev;
693 slp = (isdn_net_local *) (lp->srobin->priv);
694 if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0)))
695 lp->srobin = ndev;
696 }
697 /* Slave-startup using delay-variable */
698 if (lp->slave) {
699 if (!lp->sqfull) {
700 /* First time overload: set timestamp only */
701 lp->sqfull = 1;
702 lp->sqfull_stamp = jiffies;
703 }
704 else {
705 /* subsequent overload: if slavedelay exceeded, start dialing */
706 if ((jiffies - lp->sqfull_stamp) > lp->slavedelay)
707 isdn_net_force_dial_lp((isdn_net_local *) lp->slave->priv);
708 }
709 }
710 }
711 else {
712 /* Not overloaded, deliver locally */
713 ret = isdn_net_send_skb(ndev, lp, skb);
714 if (lp->sqfull && ((jiffies - lp->sqfull_stamp) > (lp->slavedelay + (10*HZ) )))
715 lp->sqfull = 0;
716 }
717 return ret;
718 }
719
720 /*
721 * Try sending a packet.
722 * If this interface isn't connected to a ISDN-Channel, find a free channel,
723 * and start dialing.
724 */
725 int
726 isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
727 {
728 isdn_net_local *lp = (isdn_net_local *) ndev->priv;
729
730
731 if (ndev->tbusy) {
732 if (jiffies - ndev->trans_start < 20)
733 return 1;
734 if (!lp->dialstate)
735 lp->stats.tx_errors++;
736 ndev->tbusy = 0;
737 ndev->trans_start = jiffies;
738 }
739 if (skb == NULL) {
740 dev_tint(ndev);
741 return 0;
742 }
743 /* Avoid timer-based retransmission conflicts. */
744 if (set_bit(0, (void *) &ndev->tbusy) != 0)
745 printk(KERN_WARNING
746 "%s: Transmitter access conflict.\n",
747 ndev->name);
748 else {
749 u_char *buf = skb->data;
750 #ifdef ISDN_DEBUG_NET_DUMP
751 isdn_dumppkt("S:", buf, skb->len, 40);
752 #endif
753 if (!(lp->flags & ISDN_NET_CONNECTED)) {
754 int chi;
755 if (lp->phone[1]) {
756 ulong flags;
757 save_flags(flags);
758 cli();
759 /* Grab a free ISDN-Channel */
760 if ((chi =
761 isdn_get_free_channel(ISDN_USAGE_NET,
762 lp->l2_proto,
763 lp->l3_proto,
764 lp->pre_device,
765 lp->pre_channel)) < 0) {
766 printk(KERN_WARNING
767 "isdn_net_start_xmit: No channel for %s\n",
768 ndev->name);
769 restore_flags(flags);
770 return 1;
771 }
772 /* Log packet, which triggered dialing */
773 if (dev->net_verbose)
774 isdn_net_log_packet(buf, lp);
775 lp->dialstate = 1;
776 lp->flags |= ISDN_NET_CONNECTED;
777 /* Connect interface with channel */
778 isdn_net_bind_channel(lp, chi);
779 #ifdef CONFIG_ISDN_PPP
780 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
781 if (isdn_ppp_bind(lp) < 0) {
782 lp->dialstate = 0;
783 isdn_free_channel(lp->isdn_device,
784 lp->isdn_channel,
785 ISDN_USAGE_NET);
786 restore_flags(flags);
787 return 1;
788 }
789 #endif
790 /* remember first skb to speed up arp
791 * when using encap ETHER
792 */
793 lp->first_skb = skb;
794 /* Initiate dialing */
795 isdn_net_dial();
796 ndev->tbusy = 0;
797 restore_flags(flags);
798 return 0;
799 } else {
800 /*
801 * Having no phone-number is a permanent
802 * failure or misconfiguration.
803 * Instead of just dropping, we should also
804 * have the upper layers to respond
805 * with an ICMP No route to host in the
806 * future, however at the moment, i don't
807 * know a simple way to do that.
808 * The same applies, when the telecom replies
809 * "no destination" to our dialing-attempt.
810 */
811 printk(KERN_WARNING
812 "isdn_net: No phone number for %s, packet dropped\n",
813 ndev->name);
814 dev_kfree_skb(skb, FREE_WRITE);
815 ndev->tbusy = 0;
816 return 0;
817 }
818 } else {
819 /* Connection is established, try sending */
820 ndev->trans_start = jiffies;
821 if (!lp->dialstate) {
822 if (lp->first_skb) {
823 if (isdn_net_xmit(ndev,lp,lp->first_skb))
824 return 1;
825 lp->first_skb = NULL;
826 }
827 return(isdn_net_xmit(ndev, lp, skb));
828 } else
829 ndev->tbusy = 1;
830 }
831 }
832 return 1;
833 }
834
835 /*
836 * Shutdown a net-interface.
837 */
838 static int
839 isdn_net_close(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
840 {
841 struct device *p;
842
843 dev->tbusy = 1;
844 dev->start = 0;
845 isdn_net_hangup(dev);
846 if ((p = (((isdn_net_local *) dev->priv)->slave))) {
847 /* If this interface has slaves, stop them also */
848 while (p) {
849 isdn_net_hangup(p);
850 p->tbusy = 1;
851 p->start = 0;
852 p = (((isdn_net_local *) p->priv)->slave);
853 }
854 }
855 isdn_MOD_DEC_USE_COUNT();
856 return 0;
857 }
858
859 /*
860 * Get statistics
861 */
862 static struct enet_statistics *
863 isdn_net_get_stats(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
864 {
865 isdn_net_local *lp = (isdn_net_local *) dev->priv;
866 return &lp->stats;
867 }
868
869 /* This is simply a copy from std. eth.c EXCEPT we pull ETH_HLEN
870 * instead of dev->hard_header_len off. This is done, because the
871 * lowlevel-driver has already pulled of it's stuff, when we get
872 * here and this routine only get's called whit p_encap == ETHER.
873 * Determine the packet's protocol ID. The rule here is that we
874 * assume 802.3 if the type field is short enough to be a length.
875 * This is normal practice and works for any 'now in use' protocol.
876 */
877
878 unsigned short isdn_net_type_trans(struct sk_buff *skb, struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
879 {
880 struct ethhdr *eth;
881 unsigned char *rawp;
882
883 skb_pull(skb,ETH_HLEN);
884 eth= skb->mac.ethernet;
885
886 if(*eth->h_dest&1) {
887 if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
888 skb->pkt_type=PACKET_BROADCAST;
889 else
890 skb->pkt_type=PACKET_MULTICAST;
891 }
892
893 /*
894 * This ALLMULTI check should be redundant by 1.4
895 * so don't forget to remove it.
896 */
897
898 else if (dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) {
899 if (memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
900 skb->pkt_type=PACKET_OTHERHOST;
901 }
902
903 if (ntohs(eth->h_proto) >= 1536)
904 return eth->h_proto;
905
906 rawp = skb->data;
907
908 /*
909 * This is a magic hack to spot IPX packets. Older Novell breaks
910 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
911 * layer. We look for FFFF which isnt a used 802.2 SSAP/DSAP. This
912 * won't work for fault tolerant netware but does for the rest.
913 */
914 if (*(unsigned short *)rawp == 0xFFFF)
915 return htons(ETH_P_802_3);
916 /*
917 * Real 802.2 LLC
918 */
919 return htons(ETH_P_802_2);
920 }
921
922 /*
923 * Got a packet from ISDN-Channel.
924 */
925 static void
926 isdn_net_receive(struct device *ndev, struct sk_buff *skb)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
927 {
928 isdn_net_local *lp = (isdn_net_local *) ndev->priv;
929 #ifdef CONFIG_ISDN_PPP
930 isdn_net_local *olp = lp; /* original 'lp' */
931 #endif
932
933 lp->transcount += skb->len;
934 lp->stats.rx_packets++;
935 lp->huptimer = 0;
936
937 if (lp->master) {
938 /* Bundling: If device is a slave-device, deliver to master, also
939 * handle master's statistics and hangup-timeout
940 */
941 ndev = lp->master;
942 lp = (isdn_net_local *) ndev->priv;
943 lp->stats.rx_packets++;
944 lp->huptimer = 0;
945 }
946
947 skb->dev = ndev;
948 skb->pkt_type = PACKET_HOST;
949 skb->mac.raw = skb->data;
950 #ifdef ISDN_DEBUG_NET_DUMP
951 isdn_dumppkt("R:", skb->data, skb->len, 40);
952 #endif
953 switch (lp->p_encap) {
954 case ISDN_NET_ENCAP_ETHER:
955 /* Ethernet over ISDN */
956 skb->protocol = isdn_net_type_trans(skb,ndev);
957 break;
958 case ISDN_NET_ENCAP_RAWIP:
959 /* RAW-IP without MAC-Header */
960 skb->protocol = htons(ETH_P_IP);
961 break;
962 case ISDN_NET_ENCAP_CISCOHDLC:
963 /* CISCO-HDLC IP with type field and fake I-frame-header */
964 skb_pull(skb, 2);
965 /* Fall through */
966 case ISDN_NET_ENCAP_IPTYP:
967 /* IP with type field */
968 skb->protocol = *(unsigned short *)&(skb->data[0]);
969 skb_pull(skb, 2);
970 if (*(unsigned short *)skb->data == 0xFFFF)
971 skb->protocol = htons(ETH_P_802_3);
972 break;
973 #ifdef CONFIG_ISDN_PPP
974 case ISDN_NET_ENCAP_SYNCPPP:
975 isdn_ppp_receive(lp->netdev, olp, skb);
976 return;
977 #endif
978 default:
979 printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
980 lp->name);
981 kfree_skb(skb,FREE_READ);
982 return;
983 }
984 netif_rx(skb);
985 return;
986 }
987
988 /*
989 * A packet arrived via ISDN. Search interface-chain for a corresponding
990 * interface. If found, deliver packet to receiver-function and return 1,
991 * else return 0.
992 */
993 int
994 isdn_net_receive_callback(int idx, u_char * buf, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
995 {
996 isdn_net_dev *p = dev->rx_netdev[idx];
997 struct sk_buff *skb;
998
999 if (p) {
1000 isdn_net_local *lp = &p->local;
1001 if ((lp->flags & ISDN_NET_CONNECTED) &&
1002 (!lp->dialstate)) {
1003 skb = dev_alloc_skb(len);
1004 if (skb == NULL) {
1005 printk(KERN_WARNING "out of memory\n");
1006 return 0;
1007 }
1008 memcpy(skb_put(skb, len), buf, len);
1009 isdn_net_receive(&p->dev, skb);
1010 return 1;
1011 }
1012 }
1013 return 0;
1014 }
1015
1016 /*
1017 * receive callback for lovlevel drivers, which support skb's
1018 */
1019
1020 int
1021 isdn_net_rcv_skb(int idx, struct sk_buff *skb)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1022 {
1023 isdn_net_dev *p = dev->rx_netdev[idx];
1024
1025 if (p) {
1026 isdn_net_local *lp = &p->local;
1027 if ((lp->flags & ISDN_NET_CONNECTED) &&
1028 (!lp->dialstate)) {
1029 isdn_net_receive(&p->dev, skb);
1030 return 1;
1031 }
1032 }
1033 return 0;
1034 }
1035
1036 static int
1037 my_eth_header(struct sk_buff *skb, struct device *dev, unsigned short type,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1038 void *daddr, void *saddr, unsigned len)
1039 {
1040 struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);
1041
1042 /*
1043 * Set the protocol type. For a packet of type ETH_P_802_3 we
1044 * put the length here instead. It is up to the 802.2 layer to
1045 * carry protocol information.
1046 */
1047
1048 if(type!=ETH_P_802_3)
1049 eth->h_proto = htons(type);
1050 else
1051 eth->h_proto = htons(len);
1052
1053 /*
1054 * Set the source hardware address.
1055 */
1056 if(saddr)
1057 memcpy(eth->h_source,saddr,dev->addr_len);
1058 else
1059 memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
1060
1061 /*
1062 * Anyway, the loopback-device should never use this function...
1063 */
1064
1065 if (dev->flags & IFF_LOOPBACK) {
1066 memset(eth->h_dest, 0, dev->addr_len);
1067 return(dev->hard_header_len);
1068 }
1069
1070 if(daddr) {
1071 memcpy(eth->h_dest,daddr,dev->addr_len);
1072 return dev->hard_header_len;
1073 }
1074
1075 return -dev->hard_header_len;
1076 }
1077
1078 /*
1079 * build an header
1080 * depends on encaps that is beeing used.
1081 */
1082
1083 static int
1084 isdn_net_header(struct sk_buff *skb, struct device *dev, unsigned short type,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1085 void *daddr, void *saddr, unsigned plen)
1086 {
1087 isdn_net_local *lp = dev->priv;
1088 ushort len = 0;
1089
1090 switch (lp->p_encap) {
1091 case ISDN_NET_ENCAP_ETHER:
1092 len = my_eth_header(skb, dev, type, daddr, saddr, plen);
1093 break;
1094 case ISDN_NET_ENCAP_RAWIP:
1095 printk(KERN_WARNING "isdn_net_header called with RAW_IP!\n");
1096 len = 0;
1097 break;
1098 case ISDN_NET_ENCAP_IPTYP:
1099 /* ethernet type field */
1100 *((ushort*) skb_push(skb, 2)) = htons(type);
1101 len = 2;
1102 break;
1103 case ISDN_NET_ENCAP_CISCOHDLC:
1104 skb_push(skb, 4);
1105 skb->data[0] = 0x0f;
1106 skb->data[1] = 0x00;
1107 *((ushort*)&skb->data[2]) = htons(type);
1108 len = 4;
1109 break;
1110 #ifdef CONFIG_ISDN_PPP
1111 case ISDN_NET_ENCAP_SYNCPPP:
1112 /* reserve space to be filled in isdn_ppp_xmit */
1113 len = 4;
1114 #ifdef CONFIG_ISDN_MPP
1115 if (lp->ppp_minor!=-1) {
1116 if (ippp_table[lp->ppp_minor].mpppcfg &
1117 SC_MP_PROT) {
1118 if (ippp_table[lp->ppp_minor].mpppcfg &
1119 SC_OUT_SHORT_SEQ)
1120 len = 7;
1121 else
1122 len = 9;
1123 }
1124 }
1125 #endif
1126 /* Initialize first 4 bytes to a value, which is
1127 * guaranteed to be invalid. Need that to check
1128 * for already compressed packets in isdn_ppp_xmit().
1129 */
1130 *((unsigned long *)skb_push(skb, len)) = 0;
1131 break;
1132 #endif
1133 }
1134 return len;
1135 }
1136
1137 /* We don't need to send arp, because we have point-to-point connections. */
1138
1139 static int
1140 isdn_net_rebuild_header(void *buff, struct device *dev, ulong dst,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1141 struct sk_buff *skb)
1142 {
1143 isdn_net_local *lp = dev->priv;
1144 int ret = 0;
1145
1146 if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
1147 struct ethhdr *eth = (struct ethhdr *)buff;
1148
1149 /*
1150 * Only ARP/IP is currently supported
1151 */
1152
1153 if(eth->h_proto != htons(ETH_P_IP)) {
1154 printk(KERN_WARNING
1155 "isdn_net_rebuild_header: Don't know how to resolve type %d addresses?\n",
1156 (int)eth->h_proto);
1157 memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1158 return 0;
1159 }
1160 /*
1161 * Try and get ARP to resolve the header.
1162 */
1163 #ifdef CONFIG_INET
1164 ret = arp_find((unsigned char *)&(eth->h_dest), dst, dev, dev->pa_addr,skb)? 1 : 0;
1165 #endif
1166 }
1167 return ret;
1168 }
1169
1170 /*
1171 * Interface-setup. (called just after registering a new interface)
1172 */
1173 static int
1174 isdn_net_init(struct device *ndev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1175 {
1176 ushort max_hlhdr_len = 0;
1177 isdn_net_local *lp = (isdn_net_local *)ndev->priv;
1178 int drvidx, i;
1179
1180 if (ndev == NULL) {
1181 printk(KERN_WARNING "isdn_net_init: dev = NULL!\n");
1182 return -ENODEV;
1183 }
1184 if (ndev->priv == NULL) {
1185 printk(KERN_WARNING "isdn_net_init: dev->priv = NULL!\n");
1186 return -ENODEV;
1187 }
1188
1189 ether_setup(ndev);
1190 lp->org_hcb = ndev->header_cache_bind;
1191 lp->org_hcu = ndev->header_cache_update;
1192
1193 /* Setup the generic properties */
1194
1195 ndev->hard_header = NULL;
1196 ndev->header_cache_bind = NULL;
1197 ndev->header_cache_update = NULL;
1198 ndev->mtu = 1500;
1199 ndev->flags = IFF_NOARP;
1200 ndev->family = AF_INET;
1201 ndev->type = ARPHRD_ETHER;
1202 ndev->addr_len = ETH_ALEN;
1203 ndev->pa_addr = 0;
1204 ndev->pa_brdaddr = 0;
1205 ndev->pa_mask = 0;
1206 ndev->pa_alen = 4;
1207
1208 for (i = 0; i < ETH_ALEN; i++)
1209 ndev->broadcast[i]=0xff;
1210
1211 for (i = 0; i < DEV_NUMBUFFS; i++)
1212 skb_queue_head_init(&ndev->buffs[i]);
1213
1214 /* The ISDN-specific entries in the device structure. */
1215 ndev->open = &isdn_net_open;
1216 ndev->hard_start_xmit = &isdn_net_start_xmit;
1217
1218 /*
1219 * up till binding we ask the protocol layer to reserve as much
1220 * as we migth need for HL layer
1221 */
1222
1223 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
1224 if (dev->drv[drvidx])
1225 if (max_hlhdr_len < dev->drv[drvidx]->interface->hl_hdrlen)
1226 max_hlhdr_len = dev->drv[drvidx]->interface->hl_hdrlen;
1227
1228 ndev->hard_header_len = ETH_HLEN + max_hlhdr_len;
1229
1230 ndev->stop = &isdn_net_close;
1231 ndev->get_stats = &isdn_net_get_stats;
1232 ndev->rebuild_header = &isdn_net_rebuild_header;
1233
1234 #ifdef CONFIG_ISDN_PPP
1235 ndev->do_ioctl = isdn_ppp_dev_ioctl;
1236 #endif
1237 return 0;
1238 }
1239
1240 /*
1241 * I picked the pattern-matching-functions from an old GNU-tar version (1.10)
1242 * It was originaly written and put to PD by rs@mirror.TMC.COM (Rich Salz)
1243 */
1244
1245 static int
1246 isdn_net_Star(char *s, char *p)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1247 {
1248 while (isdn_net_wildmat(s, p) == 0)
1249 if (*++s == '\0')
1250 return (0);
1251 return (1);
1252 }
1253
1254 /*
1255 * Shell-type Pattern-matching for incoming caller-Ids
1256 * This function gets a string in s and checks, if it matches the pattern
1257 * given in p. It returns 1 on success, 0 otherwise.
1258 *
1259 * Posible Patterns:
1260 *
1261 * '?' matches one character
1262 * '*' matches zero or more characters
1263 * [xyz] matches the set of charcters in brackets.
1264 * [^xyz] matches any single character not in the set of characters
1265 */
1266
1267 static int
1268 isdn_net_wildmat(char *s, char *p)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1269 {
1270 register int last;
1271 register int matched;
1272 register int reverse;
1273
1274 for (; *p; s++, p++)
1275 switch (*p) {
1276 case '\\':
1277 /*
1278 * Literal match with following character,
1279 * fall through.
1280 */
1281 p++;
1282 default:
1283 if (*s != *p)
1284 return (0);
1285 continue;
1286 case '?':
1287 /* Match anything. */
1288 if (*s == '\0')
1289 return (0);
1290 continue;
1291 case '*':
1292 /* Trailing star matches everything. */
1293 return (*++p ? isdn_net_Star(s, p) : 1);
1294 case '[':
1295 /* [^....] means inverse character class. */
1296 if ((reverse = (p[1] == '^')))
1297 p++;
1298 for (last = 0, matched = 0; *++p && (*p != ']'); last = *p)
1299 /* This next line requires a good C compiler. */
1300 if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
1301 matched = 1;
1302 if (matched == reverse)
1303 return (0);
1304 continue;
1305 }
1306 return (*s == '\0');
1307 }
1308
1309 static void
1310 isdn_net_swapbind(int drvidx)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1311 {
1312 isdn_net_dev *p;
1313
1314 #ifdef ISDN_DEBUG_NET_ICALL
1315 printk(KERN_DEBUG "n_fi: swapping ch of %d\n", drvidx);
1316 #endif
1317 p = dev->netdev;
1318 while (p) {
1319 if (p->local.pre_device == drvidx)
1320 switch (p->local.pre_channel) {
1321 case 0:
1322 p->local.pre_channel = 1;
1323 break;
1324 case 1:
1325 p->local.pre_channel = 0;
1326 break;
1327 }
1328 p = (isdn_net_dev *) p->next;
1329 }
1330 }
1331
1332 static void
1333 isdn_net_swap_usage(int i1, int i2)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1334 {
1335 int u1 = dev->usage[i1] & ISDN_USAGE_EXCLUSIVE;
1336 int u2 = dev->usage[i2] & ISDN_USAGE_EXCLUSIVE;
1337
1338 #ifdef ISDN_DEBUG_NET_ICALL
1339 printk(KERN_DEBUG "n_fi: usage of %d and %d\n", i1, i2);
1340 #endif
1341 dev->usage[i1] &= ~ISDN_USAGE_EXCLUSIVE;
1342 dev->usage[i1] |= u2;
1343 dev->usage[i2] &= ~ISDN_USAGE_EXCLUSIVE;
1344 dev->usage[i2] |= u1;
1345 isdn_info_update();
1346 }
1347
1348 /*
1349 * An incoming call-request has arrived.
1350 * Search the interface-chain for an aproppriate interface.
1351 * If found, connect the interface to the ISDN-channel and initiate
1352 * D- and B-Channel-setup. If secure-flag is set, accept only
1353 * configured phone-numbers. If callback-flag is set, initiate
1354 * callback-dialing.
1355 *
1356 * Return-Value: 0 = No appropriate interface for this call.
1357 * 1 = Call accepted
1358 * 2 = Do callback
1359 */
1360 int
1361 isdn_net_find_icall(int di, int ch, int idx, char *num)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1362 {
1363 char *eaz;
1364 int si1;
1365 int si2;
1366 int ematch;
1367 int swapped;
1368 int sidx = 0;
1369 isdn_net_dev *p;
1370 isdn_net_phone *n;
1371 ulong flags;
1372 char nr[31];
1373 char *s;
1374
1375 /* Search name in netdev-chain */
1376 save_flags(flags);
1377 cli();
1378 if (num[0] == ',') {
1379 nr[0] = '0';
1380 strncpy(&nr[1], num, 30);
1381 printk(KERN_WARNING "isdn_net: Incoming call without OAD, assuming '0'\n");
1382 } else
1383 strncpy(nr, num, 30);
1384 s = strtok(nr, ",");
1385 s = strtok(NULL, ",");
1386 if (!s) {
1387 printk(KERN_WARNING "isdn_net: Incoming callinfo garbled, ignored: %s\n",
1388 num);
1389 restore_flags(flags);
1390 return 0;
1391 }
1392 si1 = (int)simple_strtoul(s,NULL,10);
1393 s = strtok(NULL, ",");
1394 if (!s) {
1395 printk(KERN_WARNING "isdn_net: Incoming callinfo garbled, ignored: %s\n",
1396 num);
1397 restore_flags(flags);
1398 return 0;
1399 }
1400 si2 = (int)simple_strtoul(s,NULL,10);
1401 eaz = strtok(NULL, ",");
1402 if (!eaz) {
1403 printk(KERN_WARNING "isdn_net: Incoming call without CPN, assuming '0'\n");
1404 eaz = "0";
1405 }
1406 if (dev->net_verbose > 1)
1407 printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
1408 /* Accept only calls with Si1 = 7 (Data-Transmission) */
1409 if (si1 != 7) {
1410 if (dev->net_verbose > 1)
1411 printk(KERN_INFO "isdn_net: Service-Indicator not 7, ignored\n");
1412 return 0;
1413 }
1414 n = (isdn_net_phone *) 0;
1415 p = dev->netdev;
1416 ematch = 0;
1417 #ifdef ISDN_DEBUG_NET_ICALL
1418 printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
1419 dev->usage[idx]);
1420 #endif
1421 swapped = 0;
1422 while (p) {
1423 /* If last check has trigered as binding-swap, revert it */
1424 switch (swapped) {
1425 case 2:
1426 isdn_net_swap_usage(idx, sidx);
1427 /* fall through */
1428 case 1:
1429 isdn_net_swapbind(di);
1430 break;
1431 }
1432 swapped = 0;
1433 if (!strcmp(isdn_map_eaz2msn(p->local.msn, di), eaz))
1434 ematch = 1;
1435 #ifdef ISDN_DEBUG_NET_ICALL
1436 printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
1437 p->local.name, p->local.msn, p->local.flags, p->local.dialstate);
1438 #endif
1439 if ((!strcmp(isdn_map_eaz2msn(p->local.msn, di), eaz)) && /* EAZ is matching */
1440 (((!(p->local.flags & ISDN_NET_CONNECTED)) && /* but not connected */
1441 (USG_NONE(dev->usage[idx]))) || /* and ch. unused or */
1442 (((p->local.dialstate == 4) && /* if dialing */
1443 (!(p->local.flags & ISDN_NET_CALLBACK))) /* but no callback */
1444 ))) {
1445 #ifdef ISDN_DEBUG_NET_ICALL
1446 printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
1447 p->local.pre_device, p->local.pre_channel);
1448 #endif
1449 if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
1450 if ((p->local.pre_channel != ch) ||
1451 (p->local.pre_device != di)) {
1452 /* Here we got a problem:
1453 If using an ICN-Card, an incoming call is always signaled on
1454 on the first channel of the card, if both channels are
1455 down. However this channel may be bound exclusive. If the
1456 second channel is free, this call should be accepted.
1457 The solution is horribly but it runs, so what:
1458 We exchange the exclusive bindings of the two channels, the
1459 corresponding variables in the interface-structs.
1460 */
1461 if (ch == 0) {
1462 sidx = isdn_dc2minor(di, 1);
1463 #ifdef ISDN_DEBUG_NET_ICALL
1464 printk(KERN_DEBUG "n_fi: ch is 0\n");
1465 #endif
1466 if (USG_NONE(dev->usage[sidx])) {
1467 /* Second Channel is free, now see if it is bound
1468 exclusive too. */
1469 if (dev->usage[sidx] & ISDN_USAGE_EXCLUSIVE) {
1470 #ifdef ISDN_DEBUG_NET_ICALL
1471 printk(KERN_DEBUG "n_fi: 2nd channel is down and bound\n");
1472 #endif
1473 /* Yes, swap bindings only, if the original
1474 binding is bound to channel 1 of this driver */
1475 if ((p->local.pre_device == di) &&
1476 (p->local.pre_channel == 1)) {
1477 isdn_net_swapbind(di);
1478 swapped = 1;
1479 } else {
1480 /* ... else iterate next device */
1481 p = (isdn_net_dev *) p->next;
1482 continue;
1483 }
1484 } else {
1485 #ifdef ISDN_DEBUG_NET_ICALL
1486 printk(KERN_DEBUG "n_fi: 2nd channel is down and unbound\n");
1487 #endif
1488 /* No, swap always and swap excl-usage also */
1489 isdn_net_swap_usage(idx, sidx);
1490 isdn_net_swapbind(di);
1491 swapped = 2;
1492 }
1493 /* Now check for exclusive binding again */
1494 #ifdef ISDN_DEBUG_NET_ICALL
1495 printk(KERN_DEBUG "n_fi: final check\n");
1496 #endif
1497 if ((dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) &&
1498 ((p->local.pre_channel != ch) ||
1499 (p->local.pre_device != di))) {
1500 #ifdef ISDN_DEBUG_NET_ICALL
1501 printk(KERN_DEBUG "n_fi: final check failed\n");
1502 #endif
1503 p = (isdn_net_dev *) p->next;
1504 continue;
1505 }
1506 }
1507 } else {
1508 /* We are already on the second channel, so nothing to do */
1509 #ifdef ISDN_DEBUG_NET_ICALL
1510 printk(KERN_DEBUG "n_fi: already on 2nd channel\n");
1511 #endif
1512 p = (isdn_net_dev *) p->next;
1513 continue;
1514 }
1515 }
1516 }
1517 #ifdef ISDN_DEBUG_NET_ICALL
1518 printk(KERN_DEBUG "n_fi: match2\n");
1519 #endif
1520 n = p->local.phone[0];
1521 if (p->local.flags & ISDN_NET_SECURE) {
1522 while (n) {
1523 if (isdn_net_wildmat(nr, n->num))
1524 break;
1525 n = (isdn_net_phone *) n->next;
1526 }
1527 }
1528 if (n || (!(p->local.flags & ISDN_NET_SECURE))) {
1529 isdn_net_local *lp = &(p->local);
1530 #ifdef ISDN_DEBUG_NET_ICALL
1531 printk(KERN_DEBUG "n_fi: match3\n");
1532 #endif
1533 /* Here we got an interface matched, now see if it is up.
1534 * If not, reject the call actively.
1535 */
1536 if (!p->dev.start) {
1537 restore_flags(flags);
1538 printk(KERN_INFO "%s: incoming call, if down -> rejected\n",
1539 lp->name);
1540 return 3;
1541 }
1542 /* Interface is up, now see if it's a slave. If so, see if
1543 * it's master and parent slave is online. If not, reject the call.
1544 */
1545 if (lp->master) {
1546 isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
1547 printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
1548 printk(KERN_DEBUG "master=%s\n", mlp->name);
1549 if (mlp->flags & ISDN_NET_CONNECTED) {
1550 printk(KERN_DEBUG "master online\n");
1551 /* Master is online, find parent-slave (master if first slave) */
1552 while (mlp->slave) {
1553 if ((isdn_net_local *) mlp->slave->priv == lp)
1554 break;
1555 mlp = (isdn_net_local *) mlp->slave->priv;
1556 }
1557 } else
1558 printk(KERN_DEBUG "master offline\n");
1559 /* Found parent, if it's offline iterate next device */
1560 printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
1561 if (!(mlp->flags & ISDN_NET_CONNECTED)) {
1562 p = (isdn_net_dev *) p->next;
1563 continue;
1564 }
1565 }
1566 if (lp->flags & ISDN_NET_CALLBACK) {
1567 int chi;
1568 printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
1569 lp->name, nr, eaz);
1570 if (lp->phone[1]) {
1571 /* Grab a free ISDN-Channel */
1572 if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
1573 lp->l3_proto,
1574 lp->pre_device,
1575 lp->pre_channel)) < 0) {
1576 printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
1577 restore_flags(flags);
1578 return 0;
1579 }
1580 /* Setup dialstate. */
1581 lp->dialstate = 1;
1582 lp->flags |= ISDN_NET_CONNECTED;
1583 /* Connect interface with channel */
1584 isdn_net_bind_channel(lp, chi);
1585 #ifdef CONFIG_ISDN_PPP
1586 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
1587 if (isdn_ppp_bind(lp) < 0) {
1588 isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
1589 ISDN_USAGE_NET);
1590 lp->dialstate = 0;
1591 restore_flags(flags);
1592 return 0;
1593 }
1594 #endif
1595 /* Initiate dialing by returning 2 */
1596 restore_flags(flags);
1597 return 2;
1598 } else
1599 printk(KERN_WARNING "isdn_net: %s: No phone number\n", lp->name);
1600 restore_flags(flags);
1601 return 0;
1602 } else {
1603 printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
1604 eaz);
1605 #if 0
1606 /* why is this a CONFIG_ISDN_PPP feature ??? */
1607 #ifdef CONFIG_ISDN_PPP
1608 if (p->local.isdn_device != -1) {
1609 isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
1610 ISDN_USAGE_NET);
1611 }
1612 #endif
1613 #endif
1614 /* if this interface is dialing, it does it probably on a different
1615 device, so free this device */
1616 if (p->local.dialstate == 4)
1617 isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
1618 ISDN_USAGE_NET);
1619 dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
1620 dev->usage[idx] |= ISDN_USAGE_NET;
1621 strcpy(dev->num[idx], nr);
1622 isdn_info_update();
1623 dev->st_netdev[idx] = lp->netdev;
1624 p->local.isdn_device = di;
1625 p->local.isdn_channel = ch;
1626 p->local.ppp_minor = -1;
1627 p->local.flags |= ISDN_NET_CONNECTED;
1628 p->local.dialstate = 7;
1629 p->local.dtimer = 0;
1630 p->local.outgoing = 0;
1631 p->local.huptimer = 0;
1632 p->local.hupflags |= 1;
1633 #ifdef CONFIG_ISDN_PPP
1634 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
1635 if (isdn_ppp_bind(lp) < 0) {
1636 isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
1637 ISDN_USAGE_NET);
1638 lp->dialstate = 0;
1639 restore_flags(flags);
1640 return 0;
1641 }
1642 #endif
1643 restore_flags(flags);
1644 return 1;
1645 }
1646 }
1647 }
1648 p = (isdn_net_dev *) p->next;
1649 }
1650 /* If none of configured EAZ/MSN matched and not verbose, be silent */
1651 if (ematch || dev->net_verbose)
1652 printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
1653 restore_flags(flags);
1654 return 0;
1655 }
1656
1657 /*
1658 * Search list of net-interfaces for an interface with given name.
1659 */
1660 isdn_net_dev *
1661 isdn_net_findif(char *name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1662 {
1663 isdn_net_dev *p = dev->netdev;
1664
1665 while (p) {
1666 if (!strcmp(p->local.name, name))
1667 return p;
1668 p = (isdn_net_dev *) p->next;
1669 }
1670 return (isdn_net_dev *) NULL;
1671 }
1672
1673 /*
1674 * Force a net-interface to dial out.
1675 * This is called from the userlevel-routine below or
1676 * from isdn_net_start_xmit().
1677 */
1678 int isdn_net_force_dial_lp(isdn_net_local * lp)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1679 {
1680 if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
1681 int chi;
1682 if (lp->phone[1]) {
1683 ulong flags;
1684 save_flags(flags);
1685 cli();
1686 /* Grab a free ISDN-Channel */
1687 if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
1688 lp->l3_proto,
1689 lp->pre_device,
1690 lp->pre_channel)) < 0) {
1691 printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
1692 restore_flags(flags);
1693 return -EAGAIN;
1694 }
1695 lp->dialstate = 1;
1696 lp->flags |= ISDN_NET_CONNECTED;
1697 /* Connect interface with channel */
1698 isdn_net_bind_channel(lp, chi);
1699 #ifdef CONFIG_ISDN_PPP
1700 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
1701 if (isdn_ppp_bind(lp) < 0) {
1702 lp->dialstate = 0;
1703 isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
1704 return 1;
1705 }
1706 #endif
1707 /* Initiate dialing */
1708 isdn_net_dial();
1709 restore_flags(flags);
1710 return 0;
1711 } else
1712 return -EINVAL;
1713 } else
1714 return -EBUSY;
1715 }
1716
1717 /*
1718 * Force a net-interface to dial out.
1719 * This is always called from within userspace (ISDN_IOCTL_NET_DIAL).
1720 */
1721 int
1722 isdn_net_force_dial(char *name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1723 {
1724 isdn_net_dev *p = isdn_net_findif(name);
1725
1726 if (!p)
1727 return -ENODEV;
1728 return (isdn_net_force_dial_lp(&p->local));
1729 }
1730
1731 /*
1732 * Allocate a new network-interface and initialize it's data structures.
1733 */
1734 char *
1735 isdn_net_new(char *name, struct device *master)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1736 {
1737 isdn_net_dev *netdev;
1738
1739 /* Avoid creating an existing interface */
1740 if (isdn_net_findif(name)) {
1741 printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
1742 return NULL;
1743 }
1744 if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
1745 printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
1746 return NULL;
1747 }
1748 memset(netdev, 0, sizeof(isdn_net_dev));
1749 if (name == NULL)
1750 strcpy(netdev->local.name, " ");
1751 else
1752 strcpy(netdev->local.name, name);
1753 netdev->dev.name = netdev->local.name;
1754 netdev->dev.priv = &netdev->local;
1755 netdev->dev.init = isdn_net_init;
1756 netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP;
1757 if (master) {
1758 /* Device shall be a slave */
1759 struct device *p = (((isdn_net_local *) master->priv)->slave);
1760 struct device *q = master;
1761
1762 netdev->local.master = master;
1763 /* Put device at end of slave-chain */
1764 while (p) {
1765 q = p;
1766 p = (((isdn_net_local *) p->priv)->slave);
1767 }
1768 ((isdn_net_local *) q->priv)->slave = &(netdev->dev);
1769 q->interrupt = 0;
1770 q->tbusy = 0;
1771 q->start = master->start;
1772 } else {
1773 /* Device shall be a master */
1774 if (register_netdev(&netdev->dev) != 0) {
1775 printk(KERN_WARNING "isdn_net: Could not register net-device\n");
1776 kfree(netdev);
1777 return NULL;
1778 }
1779 }
1780 netdev->local.magic = ISDN_NET_MAGIC;
1781
1782 #ifdef CONFIG_ISDN_PPP
1783 netdev->mp_last = NULL; /* mpqueue is empty */
1784 netdev->ib.next_num = 0;
1785 netdev->ib.last = NULL;
1786 #endif
1787 netdev->queue = &netdev->local;
1788 netdev->local.last = &netdev->local;
1789 netdev->local.netdev = netdev;
1790 netdev->local.next = &netdev->local;
1791
1792 netdev->local.isdn_device = -1;
1793 netdev->local.isdn_channel = -1;
1794 netdev->local.pre_device = -1;
1795 netdev->local.pre_channel = -1;
1796 netdev->local.exclusive = -1;
1797 netdev->local.ppp_minor = -1;
1798 netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
1799 netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
1800 netdev->local.slavedelay = 10 * HZ;
1801 netdev->local.srobin = &netdev->dev;
1802 netdev->local.hupflags = 8; /* Do hangup even on incoming calls */
1803 netdev->local.onhtime = 10; /* Default hangup-time for saving costs
1804 of those who forget configuring this */
1805 /* The following should be configurable via ioctl */
1806 netdev->local.dialmax = 1;
1807 /* Put into to netdev-chain */
1808 netdev->next = (void *) dev->netdev;
1809 dev->netdev = netdev;
1810 return netdev->dev.name;
1811 }
1812
1813 char *
1814 isdn_net_newslave(char *parm)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1815 {
1816 char *p = strchr(parm, ',');
1817 isdn_net_dev *n;
1818 char newname[10];
1819
1820 if (p) {
1821 /* Slave-Name MUST not be empty */
1822 if (!strlen(p + 1))
1823 return NULL;
1824 strcpy(newname, p + 1);
1825 *p = 0;
1826 /* Master must already exist */
1827 if (!(n = isdn_net_findif(parm)))
1828 return NULL;
1829 /* Master must be a real interface, not a slave */
1830 if (n->local.master)
1831 return NULL;
1832 return (isdn_net_new(newname, &(n->dev)));
1833 }
1834 return NULL;
1835 }
1836
1837 /*
1838 * Set interface-parameters.
1839 * Allways set all parameters, so the user-level application is responsible
1840 * for not overwriting existing setups. It has to get the current
1841 * setup first, if only selected parameters are to be changed.
1842 */
1843 int isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1844 {
1845 isdn_net_dev *p = isdn_net_findif(cfg->name);
1846 ulong features;
1847 int i;
1848 int drvidx;
1849 int chidx;
1850 char drvid[25];
1851
1852 if (p) {
1853 /* See if any registered driver supports the features we want */
1854 features = (1 << cfg->l2_proto) | (256 << cfg->l3_proto);
1855 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1856 if (dev->drv[i])
1857 if ((dev->drv[i]->interface->features & features) == features)
1858 break;
1859 if (i == ISDN_MAX_DRIVERS) {
1860 printk(KERN_WARNING "isdn_net: No driver with selected features\n");
1861 return -ENODEV;
1862 }
1863 if ((p->local.p_encap != cfg->p_encap) &&
1864 ((p->local.p_encap == ISDN_NET_ENCAP_RAWIP) ||
1865 (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) ))
1866 if (p->dev.start) {
1867 printk(KERN_WARNING
1868 "%s: cannot change encap when if is up\n",
1869 p->local.name);
1870 return -EBUSY;
1871 }
1872 #ifndef CONFIG_ISDN_PPP
1873 if (cfg->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1874 printk(KERN_WARNING "%s: SyncPPP not configured\n",
1875 p->local.name);
1876 return -EINVAL;
1877 }
1878 #endif
1879 if (strlen(cfg->drvid)) {
1880 /* A bind has been requested ... */
1881 char *c,*e;
1882
1883 drvidx = -1;
1884 chidx = -1;
1885 strcpy(drvid, cfg->drvid);
1886 if ((c = strchr(drvid, ','))) {
1887 /* The channel-number is appended to the driver-Id with a comma */
1888 chidx = (int)simple_strtoul(c + 1,&e,10);
1889 if (e == c)
1890 chidx = -1;
1891 *c = '\0';
1892 }
1893 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
1894 /* Lookup driver-Id in array */
1895 if (!(strcmp(dev->drvid[i], drvid))) {
1896 drvidx = i;
1897 break;
1898 }
1899 if ((drvidx == -1) || (chidx == -1))
1900 /* Either driver-Id or channel-number invalid */
1901 return -ENODEV;
1902 } else {
1903 /* Parameters are valid, so get them */
1904 drvidx = p->local.pre_device;
1905 chidx = p->local.pre_channel;
1906 }
1907 if (cfg->exclusive > 0) {
1908 int flags;
1909
1910 /* If binding is exclusive, try to grab the channel */
1911 save_flags(flags);
1912 if ((i = isdn_get_free_channel(ISDN_USAGE_NET, p->local.l2_proto,
1913 p->local.l3_proto,
1914 drvidx,
1915 chidx)) < 0) {
1916 /* Grab failed, because desired channel is in use */
1917 p->local.exclusive = -1;
1918 restore_flags(flags);
1919 return -EBUSY;
1920 }
1921 /* All went ok, so update isdninfo */
1922 dev->usage[i] = ISDN_USAGE_EXCLUSIVE;
1923 isdn_info_update();
1924 restore_flags(flags);
1925 p->local.exclusive = i;
1926 } else {
1927 /* Non-exclusive binding or unbind. */
1928 p->local.exclusive = -1;
1929 if ((p->local.pre_device != -1) && (cfg->exclusive == -1)) {
1930 isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
1931 drvidx = -1;
1932 chidx = -1;
1933 }
1934 }
1935 strcpy(p->local.msn, cfg->eaz);
1936 p->local.pre_device = drvidx;
1937 p->local.pre_channel = chidx;
1938 p->local.onhtime = cfg->onhtime;
1939 p->local.charge = cfg->charge;
1940 p->local.l2_proto = cfg->l2_proto;
1941 p->local.l3_proto = cfg->l3_proto;
1942 p->local.slavedelay = cfg->slavedelay * HZ;
1943 p->local.p_encap = cfg->p_encap;
1944 if (cfg->secure)
1945 p->local.flags |= ISDN_NET_SECURE;
1946 else
1947 p->local.flags &= ~ISDN_NET_SECURE;
1948 if (cfg->callback)
1949 p->local.flags |= ISDN_NET_CALLBACK;
1950 else
1951 p->local.flags &= ~ISDN_NET_CALLBACK;
1952 if (cfg->chargehup)
1953 p->local.hupflags |= 4;
1954 else
1955 p->local.hupflags &= ~4;
1956 if (cfg->ihup)
1957 p->local.hupflags |= 8;
1958 else
1959 p->local.hupflags &= ~8;
1960 if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
1961 p->dev.hard_header = NULL;
1962 p->dev.header_cache_bind = NULL;
1963 p->dev.header_cache_update = NULL;
1964 p->dev.flags = IFF_NOARP;
1965 } else {
1966 p->dev.hard_header = isdn_net_header;
1967 if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) {
1968 p->dev.header_cache_bind = p->local.org_hcb;
1969 p->dev.header_cache_update = p->local.org_hcu;
1970 p->dev.flags = IFF_BROADCAST | IFF_MULTICAST;
1971 } else {
1972 p->dev.header_cache_bind = NULL;
1973 p->dev.header_cache_update = NULL;
1974 p->dev.flags = IFF_NOARP;
1975 }
1976 }
1977 return 0;
1978 }
1979 return -ENODEV;
1980 }
1981
1982 /*
1983 * Perform get-interface-parameters.ioctl
1984 */
1985 int isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
1986 {
1987 isdn_net_dev *p = isdn_net_findif(cfg->name);
1988
1989 if (p) {
1990 strcpy(cfg->eaz, p->local.msn);
1991 cfg->exclusive = p->local.exclusive;
1992 if (p->local.pre_device >= 0) {
1993 sprintf(cfg->drvid, "%s,%d", dev->drvid[p->local.pre_device],
1994 p->local.pre_channel);
1995 } else
1996 cfg->drvid[0] = '\0';
1997 cfg->onhtime = p->local.onhtime;
1998 cfg->charge = p->local.charge;
1999 cfg->l2_proto = p->local.l2_proto;
2000 cfg->l3_proto = p->local.l3_proto;
2001 cfg->p_encap = p->local.p_encap;
2002 cfg->secure = (p->local.flags & ISDN_NET_SECURE) ? 1 : 0;
2003 cfg->callback = (p->local.flags & ISDN_NET_CALLBACK) ? 1 : 0;
2004 cfg->chargehup = (p->local.hupflags & 4) ? 1 : 0;
2005 cfg->ihup = (p->local.hupflags & 8) ? 1 : 0;
2006 cfg->slavedelay = p->local.slavedelay / HZ;
2007 if (p->local.slave)
2008 strcpy(cfg->slave, ((isdn_net_local *) p->local.slave->priv)->name);
2009 else
2010 cfg->slave[0] = '\0';
2011 if (p->local.master)
2012 strcpy(cfg->master, ((isdn_net_local *) p->local.master->priv)->name);
2013 else
2014 cfg->master[0] = '\0';
2015 return 0;
2016 }
2017 return -ENODEV;
2018 }
2019
2020 /*
2021 * Add a phone-number to an interface.
2022 */
2023 int isdn_net_addphone(isdn_net_ioctl_phone * phone)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2024 {
2025 isdn_net_dev *p = isdn_net_findif(phone->name);
2026 isdn_net_phone *n;
2027
2028 if (isdn_net_checkwild(phone->phone) && (phone->outgoing & 1))
2029 return -EINVAL;
2030 if (p) {
2031 if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
2032 return -ENOMEM;
2033 strcpy(n->num, phone->phone);
2034 n->next = p->local.phone[phone->outgoing & 1];
2035 p->local.phone[phone->outgoing & 1] = n;
2036 return 0;
2037 }
2038 return -ENODEV;
2039 }
2040
2041 /*
2042 * Return a string of all phone-numbers of an interface.
2043 */
2044 int isdn_net_getphones(isdn_net_ioctl_phone * phone, char *phones)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2045 {
2046 isdn_net_dev *p = isdn_net_findif(phone->name);
2047 int inout = phone->outgoing & 1;
2048 int more = 0;
2049 int count = 0;
2050 isdn_net_phone *n;
2051 int flags;
2052 int ret;
2053
2054 if (!p)
2055 return -ENODEV;
2056 save_flags(flags);
2057 cli();
2058 inout &= 1;
2059 n = p->local.phone[inout];
2060 if (n)
2061 count++;
2062 while (n) {
2063 if (more) {
2064 put_fs_byte(' ', phones++);
2065 count++;
2066 }
2067 if ((ret = verify_area(VERIFY_WRITE, (void *) phones, strlen(n->num) + 1))) {
2068 restore_flags(flags);
2069 return ret;
2070 }
2071 memcpy_tofs(phones, n->num, strlen(n->num) + 1);
2072 phones += strlen(n->num);
2073 count += strlen(n->num);
2074 n = n->next;
2075 more = 1;
2076 }
2077 restore_flags(flags);
2078 return count;
2079 }
2080
2081 /*
2082 * Delete a phone-number from an interface.
2083 */
2084
2085 int isdn_net_delphone(isdn_net_ioctl_phone * phone)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2086 {
2087 isdn_net_dev *p = isdn_net_findif(phone->name);
2088 int inout = phone->outgoing & 1;
2089 isdn_net_phone *n;
2090 isdn_net_phone *m;
2091
2092 if (p) {
2093 n = p->local.phone[inout];
2094 m = NULL;
2095 while (n) {
2096 if (!strcmp(n->num, phone->phone)) {
2097 if (m)
2098 m->next = n->next;
2099 else
2100 p->local.phone[inout] = n->next;
2101 kfree(n);
2102 return 0;
2103 }
2104 m = n;
2105 n = (isdn_net_phone *) n->next;
2106 }
2107 return -EINVAL;
2108 }
2109 return -ENODEV;
2110 }
2111
2112 /*
2113 * Delete all phone-numbers of an interface.
2114 */
2115 static int isdn_net_rmallphone(isdn_net_dev * p)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2116 {
2117 isdn_net_phone *n;
2118 isdn_net_phone *m;
2119 int flags;
2120 int i;
2121
2122 save_flags(flags);
2123 cli();
2124 for (i = 0; i < 2; i++) {
2125 n = p->local.phone[i];
2126 while (n) {
2127 m = n->next;
2128 kfree(n);
2129 n = m;
2130 }
2131 p->local.phone[i] = NULL;
2132 }
2133 restore_flags(flags);
2134 return 0;
2135 }
2136
2137 /*
2138 * Force a hangup of a network-interface.
2139 */
2140 int isdn_net_force_hangup(char *name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2141 {
2142 isdn_net_dev *p = isdn_net_findif(name);
2143 int flags;
2144 struct device *q;
2145
2146 if (p) {
2147 save_flags(flags);
2148 cli();
2149 if (p->local.isdn_device < 0) {
2150 restore_flags(flags);
2151 return 1;
2152 }
2153 isdn_net_hangup(&p->dev);
2154 q = p->local.slave;
2155 /* If this interface has slaves, do a hangup for them also. */
2156 while (q) {
2157 isdn_net_hangup(q);
2158 q = (((isdn_net_local *) q->priv)->slave);
2159 }
2160 restore_flags(flags);
2161 return 0;
2162 }
2163 return -ENODEV;
2164 }
2165
2166 /*
2167 * Helper-function for isdn_net_rm: Do the real work.
2168 */
2169 static int isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2170 {
2171 int flags;
2172
2173 save_flags(flags);
2174 cli();
2175 if (p->local.master) {
2176 /* If it's a slave, it may be removed even if it is busy. However
2177 * it has to be hung up first.
2178 */
2179 isdn_net_hangup(&p->dev);
2180 p->dev.start = 0;
2181 }
2182 if (p->dev.start) {
2183 restore_flags(flags);
2184 return -EBUSY;
2185 }
2186 /* Free all phone-entries */
2187 isdn_net_rmallphone(p);
2188 /* If interface is bound exclusive, free channel-usage */
2189 if (p->local.exclusive != -1)
2190 isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
2191 if (p->local.master) {
2192 /* It's a slave-device, so update master's slave-pointer if necessary */
2193 if (((isdn_net_local *) (p->local.master->priv))->slave == &p->dev)
2194 ((isdn_net_local *) (p->local.master->priv))->slave = p->local.slave;
2195 } else
2196 /* Unregister only if it's a master-device */
2197 unregister_netdev(&p->dev);
2198 /* Unlink device from chain */
2199 if (q)
2200 q->next = p->next;
2201 else
2202 dev->netdev = p->next;
2203 if (p->local.slave) {
2204 /* If this interface has a slave, remove it also */
2205 char *slavename = ((isdn_net_local *) (p->local.slave->priv))->name;
2206 isdn_net_dev *n = dev->netdev;
2207 q = NULL;
2208 while (n) {
2209 if (!strcmp(n->local.name, slavename)) {
2210 isdn_net_realrm(n, q);
2211 break;
2212 }
2213 q = n;
2214 n = (isdn_net_dev *) n->next;
2215 }
2216 }
2217 /* If no more net-devices remain, disable auto-hangup timer */
2218 if (dev->netdev == NULL)
2219 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
2220 restore_flags(flags);
2221
2222 #ifdef CONFIG_ISDN_PPP
2223 isdn_ppp_free_mpqueue(p);
2224 #endif
2225 kfree(p);
2226
2227 return 0;
2228 }
2229
2230 /*
2231 * Remove a single network-interface.
2232 */
2233 int isdn_net_rm(char *name)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2234 {
2235 isdn_net_dev *p;
2236 isdn_net_dev *q;
2237
2238 /* Search name in netdev-chain */
2239 p = dev->netdev;
2240 q = NULL;
2241 while (p) {
2242 if (!strcmp(p->local.name, name))
2243 return (isdn_net_realrm(p, q));
2244 q = p;
2245 p = (isdn_net_dev *) p->next;
2246 }
2247 /* If no more net-devices remain, disable auto-hangup timer */
2248 if (dev->netdev == NULL)
2249 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
2250 return -ENODEV;
2251 }
2252
2253 /*
2254 * Remove all network-interfaces
2255 */
2256 int isdn_net_rmall(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
2257 {
2258 int flags;
2259 int ret;
2260
2261 /* Walk through netdev-chain */
2262 save_flags(flags);
2263 cli();
2264 while (dev->netdev) {
2265 if (!dev->netdev->local.master) {
2266 /* Remove master-devices only, slaves get removed with their master */
2267 if ((ret = isdn_net_realrm(dev->netdev, NULL))) {
2268 restore_flags(flags);
2269 return ret;
2270 }
2271 }
2272 }
2273 dev->netdev = NULL;
2274 restore_flags(flags);
2275 return 0;
2276 }
2277
2278
2279
2280
2281
2282
2283