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_send
  9. isdn_net_hangup
  10. isdn_net_log_packet
  11. isdn_net_send_skb
  12. isdn_net_xmit
  13. isdn_net_start_xmit
  14. isdn_net_close
  15. isdn_net_get_stats
  16. isdn_net_type_trans
  17. isdn_net_receive
  18. isdn_net_receive_callback
  19. isdn_net_rcv_skb
  20. my_eth_header
  21. isdn_net_header
  22. isdn_net_rebuild_header
  23. isdn_net_init
  24. isdn_net_Star
  25. isdn_net_wildmat
  26. isdn_net_swapbind
  27. isdn_net_swap_usage
  28. isdn_net_find_icall
  29. isdn_net_findif
  30. isdn_net_force_dial_lp
  31. isdn_net_force_dial
  32. isdn_net_new
  33. isdn_net_newslave
  34. isdn_net_setcfg
  35. isdn_net_getcfg
  36. isdn_net_addphone
  37. isdn_net_getphones
  38. isdn_net_delphone
  39. isdn_net_rmallphone
  40. isdn_net_force_hangup
  41. isdn_net_realrm
  42. isdn_net_rm
  43. isdn_net_rmall

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

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