root/drivers/isdn/isdn_net.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isdn_net_reset
  2. isdn_net_open
  3. isdn_net_bind_channel
  4. isdn_net_autohup
  5. isdn_net_stat_callback
  6. isdn_net_checkwild
  7. isdn_net_dial
  8. isdn_net_hangup
  9. isdn_net_log_packet
  10. isdn_net_send_skb
  11. isdn_net_xmit
  12. isdn_net_start_xmit
  13. isdn_net_close
  14. isdn_net_get_stats
  15. isdn_net_type_trans
  16. isdn_net_receive
  17. isdn_net_receive_callback
  18. isdn_net_rcv_skb
  19. my_eth_header
  20. isdn_net_header
  21. isdn_net_rebuild_header
  22. isdn_net_init
  23. isdn_net_Star
  24. isdn_net_wildmat
  25. isdn_net_swapbind
  26. isdn_net_swap_usage
  27. isdn_net_find_icall
  28. isdn_net_findif
  29. isdn_net_force_dial_lp
  30. isdn_net_force_dial
  31. isdn_net_new
  32. isdn_net_newslave
  33. isdn_net_setcfg
  34. isdn_net_getcfg
  35. isdn_net_addphone
  36. isdn_net_getphones
  37. isdn_net_delphone
  38. isdn_net_rmallphone
  39. isdn_net_force_hangup
  40. isdn_net_realrm
  41. isdn_net_rm
  42. isdn_net_rmall

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

/* [previous][next][first][last][top][bottom][index][help] */