root/drivers/net/slip.c

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

DEFINITIONS

This source file includes following definitions.
  1. sl_initialize
  2. sl_alloc
  3. sl_free
  4. sl_changedmtu
  5. sl_enqueue
  6. sl_dequeue
  7. sl_lock
  8. sl_unlock
  9. sl_bump
  10. sl_encaps
  11. slip_write_wakeup
  12. sl_xmit
  13. sl_type_trans
  14. sl_header
  15. sl_rebuild_header
  16. sl_open
  17. sl_close
  18. slip_receive_room
  19. slip_receive_buf
  20. slip_open
  21. sl_get_stats
  22. slip_close
  23. slip_esc
  24. slip_unesc
  25. slip_esc6
  26. slip_unesc6
  27. sl_set_mac_address
  28. sl_set_dev_mac_address
  29. slip_ioctl
  30. slip_init

   1 /*
   2  * slip.c       This module implements the SLIP protocol for kernel-based
   3  *              devices like TTY.  It interfaces between a raw TTY, and the
   4  *              kernel's INET protocol layers (via DDI).
   5  *
   6  * Version:     @(#)slip.c      0.7.6   05/25/93
   7  *
   8  * Authors:     Laurence Culhane, <loz@holmes.demon.co.uk>
   9  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  10  *
  11  * Fixes:
  12  *              Alan Cox        :       Sanity checks and avoid tx overruns.
  13  *                                      Has a new sl->mtu field.
  14  *              Alan Cox        :       Found cause of overrun. ifconfig sl0 mtu upwards.
  15  *                                      Driver now spots this and grows/shrinks its buffers(hack!).
  16  *                                      Memory leak if you run out of memory setting up a slip driver fixed.
  17  *              Matt Dillon     :       Printable slip (borrowed from NET2E)
  18  *      Pauline Middelink       :       Slip driver fixes.
  19  *              Alan Cox        :       Honours the old SL_COMPRESSED flag
  20  *              Alan Cox        :       KISS AX.25 and AXUI IP support
  21  *              Michael Riepe   :       Automatic CSLIP recognition added
  22  *              Charles Hedrick :       CSLIP header length problem fix.
  23  *              Alan Cox        :       Corrected non-IP cases of the above.
  24  *              Alan Cox        :       Now uses hardware type as per FvK.
  25  *              Alan Cox        :       Default to 192.168.0.0 (RFC 1597)
  26  *
  27  *
  28  *      FIXME:  This driver still makes some IP'ish assumptions. It should build cleanly KISS TNC only without
  29  *      CONFIG_INET defined.
  30  */
  31  
  32 #include <asm/segment.h>
  33 #include <asm/system.h>
  34 
  35 #include <linux/config.h>
  36 #include <linux/types.h>
  37 #include <linux/kernel.h>
  38 #include <linux/sched.h>
  39 #include <linux/string.h>
  40 #include <linux/mm.h>
  41 #include <linux/socket.h>
  42 #include <linux/sockios.h>
  43 #include <linux/interrupt.h>
  44 #include <linux/tty.h>
  45 #include <linux/errno.h>
  46 #include <linux/stat.h>
  47 #include <linux/in.h>
  48 #include <linux/inet.h>
  49 #include <linux/netdevice.h>
  50 #ifdef CONFIG_AX25
  51 #include "ax25.h"
  52 #endif
  53 #include <linux/etherdevice.h>
  54 #ifdef CONFIG_INET
  55 #include "ip.h"
  56 #include "route.h"
  57 #include "protocol.h"
  58 #include "tcp.h"
  59 #endif
  60 #include <linux/skbuff.h>
  61 #include <linux/if_arp.h>
  62 #include "sock.h"
  63 #include "slip.h"
  64 #ifdef CONFIG_INET
  65 #include "slhc.h"
  66 #endif
  67 
  68 #define SLIP_VERSION    "0.7.5-NET3.014-NEWTTY"
  69 
  70 
  71 static struct slip      sl_ctrl[SL_NRUNIT];
  72 static struct tty_ldisc sl_ldisc;
  73 static int              already = 0;
  74 
  75 /* Initialize a SLIP control block for use. */
  76 static void
  77 sl_initialize(struct slip *sl, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79   sl->magic             = SLIP_MAGIC;
  80   sl->inuse             = 0;
  81   sl->sending           = 0;
  82   sl->escape            = 0;
  83   sl->flags             = 0;
  84 #ifdef SL_ADAPTIVE
  85   sl->mode              = SL_MODE_ADAPTIVE;     /* automatic CSLIP recognition */
  86 #else
  87 #ifdef SL_COMPRESSED
  88   sl->mode              = SL_MODE_CSLIP | SL_MODE_ADAPTIVE;     /* Default */
  89 #else
  90   sl->mode              = SL_MODE_SLIP;         /* Default for non compressors */
  91 #endif
  92 #endif  
  93 
  94   sl->line              = dev->base_addr;
  95   sl->tty               = NULL;
  96   sl->dev               = dev;
  97   sl->slcomp            = NULL;
  98 
  99   /* Clear all pointers. */
 100   sl->rbuff             = NULL;
 101   sl->xbuff             = NULL;
 102   sl->cbuff             = NULL;
 103 
 104   sl->rhead             = NULL;
 105   sl->rend              = NULL;
 106   dev->rmem_end         = (unsigned long) NULL;
 107   dev->rmem_start       = (unsigned long) NULL;
 108   dev->mem_end          = (unsigned long) NULL;
 109   dev->mem_start        = (unsigned long) NULL;
 110   dev->type             = ARPHRD_SLIP + sl->mode;
 111   if(dev->type == 260)  /* KISS */
 112         dev->type=ARPHRD_AX25;
 113 }
 114 
 115 /* Find a free SLIP channel, and link in this `tty' line. */
 116 static inline struct slip *
 117 sl_alloc(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119   unsigned long flags;
 120   struct slip *sl;
 121   int i;
 122 
 123   save_flags (flags);
 124   cli();
 125   for (i = 0; i < SL_NRUNIT; i++) {
 126         sl = &sl_ctrl[i];
 127         if (sl->inuse == 0) {
 128                 sl->inuse = 1;
 129                 sl->tty = NULL;
 130                 restore_flags(flags);
 131                 return(sl);
 132         }
 133   }
 134   restore_flags(flags);
 135   return(NULL);
 136 }
 137 
 138 
 139 /* Free a SLIP channel. */
 140 static inline void
 141 sl_free(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143   unsigned long flags;
 144 
 145   if (sl->inuse) {
 146         save_flags(flags);
 147         cli();
 148         sl->inuse = 0;
 149         sl->tty = NULL;
 150         restore_flags(flags);
 151   }
 152 }
 153 
 154 /* MTU has been changed by the IP layer. Unfortunately we are not told about this, but
 155    we spot it ourselves and fix things up. We could be in an upcall from the tty
 156    driver, or in an ip packet queue. */
 157    
 158 static void sl_changedmtu(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         struct device *dev=sl->dev;
 161         unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
 162         int l;
 163         int omtu=sl->mtu;
 164         
 165         sl->mtu=dev->mtu;
 166         l=(dev->mtu *2);
 167 /*
 168  * allow for arrival of larger UDP packets, even if we say not to
 169  * also fixes a bug in which SunOS sends 512-byte packets even with
 170  * an MSS of 128
 171  */
 172         if (l < (576 * 2))
 173           l = 576 * 2;
 174         
 175         tb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 176         rb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 177         cb= (unsigned char *) kmalloc(l + 4, GFP_ATOMIC);
 178         
 179         if(tb==NULL || rb==NULL || cb==NULL)
 180         {
 181                 printk("Unable to grow slip buffers. MTU change cancelled.\n");
 182                 sl->mtu=omtu;
 183                 dev->mtu=omtu;
 184                 if(tb!=NULL)
 185                         kfree(tb);
 186                 if(rb!=NULL)
 187                         kfree(rb);
 188                 if(cb!=NULL)
 189                         kfree(cb);
 190                 return;
 191         }
 192         
 193         cli();
 194         
 195         tf=(unsigned char *)sl->dev->mem_start;
 196         sl->dev->mem_start=(unsigned long)tb;
 197         sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
 198         rf=(unsigned char *)sl->dev->rmem_start;
 199         sl->dev->rmem_start=(unsigned long)rb;
 200         sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
 201         
 202         sl->xbuff = (unsigned char *) sl->dev->mem_start;
 203         sl->rbuff = (unsigned char *) sl->dev->rmem_start;
 204         sl->rend  = (unsigned char *) sl->dev->rmem_end;
 205         sl->rhead = sl->rbuff;
 206         
 207         cf=sl->cbuff;
 208         sl->cbuff=cb;
 209         
 210         sl->escape=0;
 211         sl->sending=0;
 212         sl->rcount=0;
 213 
 214         sti();  
 215         
 216         if(rf!=NULL)
 217                 kfree(rf);
 218         if(tf!=NULL)
 219                 kfree(tf);
 220         if(cf!=NULL)
 221                 kfree(cf);
 222 }
 223 
 224 
 225 /* Stuff one byte into a SLIP receiver buffer. */
 226 static inline void
 227 sl_enqueue(struct slip *sl, unsigned char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229   unsigned long flags;
 230 
 231   save_flags(flags);
 232   cli();
 233   if (sl->rhead < sl->rend) {
 234         *sl->rhead = c;
 235         sl->rhead++;
 236         sl->rcount++;
 237   } else sl->roverrun++;
 238   restore_flags(flags);
 239 }
 240 
 241 /* Release 'i' bytes from a SLIP receiver buffer. */
 242 static inline void
 243 sl_dequeue(struct slip *sl, int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245   unsigned long flags;
 246 
 247   save_flags(flags);
 248   cli();
 249   if (sl->rhead > sl->rbuff) {
 250         sl->rhead -= i;
 251         sl->rcount -= i;
 252   }
 253   restore_flags(flags);
 254 }
 255 
 256 
 257 /* Set the "sending" flag.  This must be atomic, hence the ASM. */
 258 static inline void
 259 sl_lock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261   unsigned long flags;
 262 
 263   save_flags(flags);
 264   cli();
 265   sl->sending = 1;
 266   sl->dev->tbusy = 1;
 267   restore_flags(flags);
 268 }
 269 
 270 
 271 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
 272 static inline void
 273 sl_unlock(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 274 {
 275   unsigned long flags;
 276 
 277   save_flags(flags);
 278   cli();
 279   sl->sending = 0;
 280   sl->dev->tbusy = 0;
 281   restore_flags(flags);
 282 }
 283 
 284 
 285 /* Send one completely decapsulated IP datagram to the IP layer. */
 286 static void
 287 sl_bump(struct slip *sl)
     /* [previous][next][first][last][top][bottom][index][help] */
 288 {
 289   int done;
 290   unsigned char c;
 291   unsigned long flags;
 292   int count;
 293 
 294   count = sl->rcount;
 295 #ifdef CONFIG_INET  
 296   if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
 297     if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
 298 #if 1
 299       /* ignore compressed packets when CSLIP is off */
 300       if (!(sl->mode & SL_MODE_CSLIP)) {
 301         printk("SLIP: compressed packet ignored\n");
 302         return;
 303       }
 304 #endif
 305       /* make sure we've reserved enough space for uncompress to use */
 306       save_flags(flags);
 307       cli();
 308       if ((sl->rhead + 80) < sl->rend) {
 309         sl->rhead += 80;
 310         sl->rcount += 80;
 311         done = 1;
 312       } else {
 313         sl->roverrun++;
 314         done = 0;
 315       }
 316       restore_flags(flags);
 317       if (! done)  /* not enough space available */
 318         return;
 319 
 320       count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
 321       if (count <= 0) {
 322         sl->errors++;
 323         return;
 324       }
 325     } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
 326       if (!(sl->mode & SL_MODE_CSLIP)) {
 327         /* turn on header compression */
 328         sl->mode |= SL_MODE_CSLIP;
 329         printk("SLIP: header compression turned on\n");
 330       }
 331       sl->rbuff[0] &= 0x4f;
 332       if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
 333         sl->errors++;
 334         return;
 335       }
 336     }
 337   }
 338 
 339 #endif
 340   /* Bump the datagram to the upper layers... */
 341   do {
 342         /* clh_dump(sl->rbuff, count); */
 343         done = dev_rint(sl->rbuff, count, 0, sl->dev);
 344         if (done == 0 || done == 1) break;
 345   } while(1);
 346 
 347   sl->rpacket++;
 348 }
 349 
 350 /* Encapsulate one IP datagram and stuff into a TTY queue. */
 351 static void
 352 sl_encaps(struct slip *sl, unsigned char *icp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354   unsigned char *p;
 355   int actual, count;
 356 
 357   
 358   if(sl->mtu != sl->dev->mtu)   /* Someone has been ifconfigging */
 359         sl_changedmtu(sl);
 360   
 361   if(len>sl->mtu)               /* Sigh, shouldn't occur BUT ... */
 362   {
 363         len=sl->mtu;
 364         printk("slip: truncating oversized transmit packet!\n");
 365   }
 366 
 367   p = icp;
 368 #ifdef CONFIG_INET  
 369   if(sl->mode & SL_MODE_CSLIP)
 370           len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
 371 #endif
 372   if(sl->mode & SL_MODE_SLIP6)
 373         count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
 374   else
 375         count=slip_esc(p, (unsigned char *)sl->xbuff,len);
 376   sl->spacket++;
 377 
 378   /* Tell TTY to send it on its way. */
 379   actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count);
 380   if (actual == count) {
 381           sl_unlock(sl);
 382           dev_tint(sl->dev);
 383   } else {
 384           sl->xhead = sl->xbuff + count;
 385           sl->xtail = sl->xbuff + actual;
 386           sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 387   }
 388 }
 389 
 390 /*
 391  * Called by the driver when there's room for more data.  If we have
 392  * more packets to send, we send them here.
 393  */
 394 static void slip_write_wakeup(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 395 {
 396         register int count, answer;
 397         struct slip *sl = (struct slip *) tty->disc_data;
 398 
 399         /* First make sure we're connected. */
 400         if (!sl || sl->magic != SLIP_MAGIC) {
 401                 return;
 402         }
 403 
 404         if (!sl->xtail)
 405                 return;
 406 
 407         cli();
 408         if (sl->flags & SLF_XMIT_BUSY) {
 409                 sti();
 410                 return;
 411         }
 412         sl->flags |= SLF_XMIT_BUSY;
 413         sti();
 414         
 415         count = sl->xhead - sl->xtail;
 416 
 417         answer = tty->driver.write(tty, 0, sl->xtail, count);
 418         if (answer == count) {
 419                 sl->xtail = 0;
 420                 tty->flags &= ~TTY_DO_WRITE_WAKEUP;
 421 
 422                 sl_unlock(sl);
 423                 dev_tint(sl->dev);
 424         } else {
 425                 sl->xtail += answer;
 426         }
 427         sl->flags &= ~SLF_XMIT_BUSY;
 428 }
 429 
 430 /*static void sl_hex_dump(unsigned char *x,int l)
 431 {
 432         int n=0;
 433         printk("sl_xmit: (%d bytes)\n",l);
 434         while(l)
 435         {
 436                 printk("%2X ",(int)*x++);
 437                 l--;
 438                 n++;
 439                 if(n%32==0)
 440                         printk("\n");
 441         }
 442         if(n%32)
 443                 printk("\n");
 444 }*/
 445 
 446 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 447 static int
 448 sl_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450   struct tty_struct *tty;
 451   struct slip *sl;
 452   int size;
 453 
 454   /* Find the correct SLIP channel to use. */
 455   sl = &sl_ctrl[dev->base_addr];
 456   tty = sl->tty;
 457 
 458   /*
 459    * If we are busy already- too bad.  We ought to be able
 460    * to queue things at this point, to allow for a little
 461    * frame buffer.  Oh well...
 462    */
 463   if (sl->sending) {
 464         sl->sbusy++;
 465         return(1);
 466   }
 467 
 468   /* We were not, so we are now... :-) */
 469   if (skb != NULL) {
 470         sl_lock(sl);
 471         
 472         size=skb->len;
 473         sl_encaps(sl, skb->data, size);
 474         dev_kfree_skb(skb, FREE_WRITE);
 475   }
 476   return(0);
 477 }
 478 
 479 
 480 /* Return the frame type ID.  This is normally IP but maybe be AX.25. */
 481 static unsigned short
 482 sl_type_trans (struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484 #ifdef CONFIG_AX25
 485         struct slip *sl=&sl_ctrl[dev->base_addr];
 486         if(sl->mode&SL_MODE_AX25)
 487                 return htons(ETH_P_AX25);
 488 #endif
 489   return htons(ETH_P_IP);
 490 }
 491 
 492 
 493 /* Fill in the MAC-level header. Not used by SLIP. */
 494 static int
 495 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
     /* [previous][next][first][last][top][bottom][index][help] */
 496           void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
 497 {
 498 #ifdef CONFIG_AX25
 499 #ifdef CONFIG_INET
 500   struct slip *sl=&sl_ctrl[dev->base_addr];
 501   if((sl->mode&SL_MODE_AX25) && type!=htons(ETH_P_AX25))
 502         return ax25_encapsulate(buff,dev,type,daddr,saddr,len,skb);
 503 #endif  
 504 #endif
 505 
 506   return(0);
 507 }
 508 
 509 
 510 /* Rebuild the MAC-level header.  Not used by SLIP. */
 511 static int
 512 sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 513                 struct sk_buff *skb)
 514 {
 515 #ifdef CONFIG_AX25
 516 #ifdef CONFIG_INET
 517   struct slip *sl=&sl_ctrl[dev->base_addr];
 518   
 519   if(sl->mode&SL_MODE_AX25)
 520         return ax25_rebuild_header(buff,dev,raddr, skb);
 521 #endif          
 522 #endif  
 523   return(0);
 524 }
 525 
 526 
 527 /* Open the low-level part of the SLIP channel. Easy! */
 528 static int
 529 sl_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531   struct slip *sl;
 532   unsigned char *p;
 533   unsigned long l;
 534 
 535   sl = &sl_ctrl[dev->base_addr];
 536   if (sl->tty == NULL) {
 537         return(-ENXIO);
 538   }
 539   sl->dev = dev;
 540 
 541   /*
 542    * Allocate the SLIP frame buffers:
 543    *
 544    * mem_end    Top of frame buffers
 545    * mem_start  Start of frame buffers
 546    * rmem_end   Top of RECV frame buffer
 547    * rmem_start Start of RECV frame buffer
 548    */
 549   l = (dev->mtu * 2);
 550 /*
 551  * allow for arrival of larger UDP packets, even if we say not to
 552  * also fixes a bug in which SunOS sends 512-byte packets even with
 553  * an MSS of 128
 554  */
 555   if (l < (576 * 2))
 556     l = 576 * 2;
 557 
 558   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 559   if (p == NULL) {
 560         return(-ENOMEM);
 561   }
 562   
 563   sl->mtu               = dev->mtu;
 564   sl->dev->mem_start    = (unsigned long) p;
 565   sl->dev->mem_end      = (unsigned long) (sl->dev->mem_start + l);
 566 
 567   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 568   if (p == NULL) {
 569         kfree_s((void *)sl->dev->mem_start,l+4);
 570         return(-ENOMEM);
 571   }
 572   sl->dev->rmem_start   = (unsigned long) p;
 573   sl->dev->rmem_end     = (unsigned long) (sl->dev->rmem_start + l);
 574 
 575   sl->xbuff             = (unsigned char *) sl->dev->mem_start;
 576   sl->rbuff             = (unsigned char *) sl->dev->rmem_start;
 577   sl->rend              = (unsigned char *) sl->dev->rmem_end;
 578   sl->rhead             = sl->rbuff;
 579 
 580   sl->escape            = 0;
 581   sl->sending           = 0;
 582   sl->rcount            = 0;
 583 
 584   p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
 585   if (p == NULL) {
 586         kfree((unsigned char *)sl->dev->mem_start);
 587         return(-ENOMEM);
 588   }
 589   sl->cbuff             = p;
 590 #ifdef CONFIG_INET
 591   sl->slcomp = slhc_init(16, 16);
 592   if (sl->slcomp == NULL) {
 593         kfree((unsigned char *)sl->dev->mem_start);
 594         kfree((unsigned char *)sl->dev->rmem_start);
 595         kfree(sl->cbuff);
 596         return(-ENOMEM);
 597   }
 598 #endif
 599   dev->flags|=IFF_UP;
 600   /* Needed because address '0' is special */
 601   if(dev->pa_addr==0)
 602         dev->pa_addr=ntohl(0xC0A80001);
 603   return(0);
 604 }
 605 
 606 
 607 /* Close the low-level part of the SLIP channel. Easy! */
 608 static int
 609 sl_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611   struct slip *sl;
 612 
 613   sl = &sl_ctrl[dev->base_addr];
 614   if (sl->tty == NULL) {
 615         return(-EBUSY);
 616   }
 617   sl->tty->disc_data = 0;
 618   sl_free(sl);
 619 
 620   /* Free all SLIP frame buffers. */
 621   kfree(sl->rbuff);
 622   kfree(sl->xbuff);
 623   kfree(sl->cbuff);
 624 #ifdef CONFIG_INET  
 625   slhc_free(sl->slcomp);
 626 #endif
 627   sl_initialize(sl, dev);
 628 
 629   return(0);
 630 }
 631 
 632 static int slip_receive_room(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 633 {
 634         return 65536;  /* We can handle an infinite amount of data. :-) */
 635 }
 636 
 637 /*
 638  * Handle the 'receiver data ready' interrupt.
 639  * This function is called by the 'tty_io' module in the kernel when
 640  * a block of SLIP data has been received, which can now be decapsulated
 641  * and sent on to some IP layer for further processing.
 642  */
 643 static void slip_receive_buf(struct tty_struct *tty, unsigned char *cp,
     /* [previous][next][first][last][top][bottom][index][help] */
 644                                char *fp, int count)
 645 {
 646         struct slip *sl = (struct slip *) tty->disc_data;
 647   
 648         if (!sl || sl->magic != SLIP_MAGIC)
 649                 return;
 650   
 651         /*
 652          * Argh! mtu change time! - costs us the packet part received
 653          * at the change
 654          */
 655         if(sl->mtu!=sl->dev->mtu)
 656                 sl_changedmtu(sl);
 657         
 658         /* Read the characters out of the buffer */
 659         while (count--) {
 660                 if (fp && *fp++) {
 661                         sl->flags |= SLF_ERROR;
 662                         cp++;
 663                         continue;
 664                 }
 665                 if (sl->mode & SL_MODE_SLIP6)
 666                         slip_unesc6(sl,*cp++);
 667                 else
 668                         slip_unesc(sl,*cp++);
 669         }
 670 }
 671 
 672 /*
 673  * Open the high-level part of the SLIP channel.  
 674  * This function is called by the TTY module when the
 675  * SLIP line discipline is called for.  Because we are
 676  * sure the tty line exists, we only have to link it to
 677  * a free SLIP channel...
 678  */
 679 static int
 680 slip_open(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 681 {
 682   struct slip *sl = (struct slip *) tty->disc_data;
 683 
 684   /* First make sure we're not already connected. */
 685   if (sl && sl->magic == SLIP_MAGIC) {
 686         return(-EEXIST);
 687   }
 688 
 689   /* OK.  Find a free SLIP channel to use. */
 690   if ((sl = sl_alloc()) == NULL) {
 691         return(-ENFILE);
 692   }
 693   sl->tty = tty;
 694   tty->disc_data = sl;
 695   if (tty->driver.flush_buffer)
 696           tty->driver.flush_buffer(tty);
 697   if (tty->ldisc.flush_buffer)
 698           tty->ldisc.flush_buffer(tty);
 699 
 700   /* Perform the low-level SLIP initialization. */
 701   (void) sl_open(sl->dev);
 702 
 703   /* Done.  We have linked the TTY line to a channel. */
 704   return(sl->line);
 705 }
 706 
 707  
 708 static struct enet_statistics *
 709 sl_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 710 {
 711     static struct enet_statistics stats;
 712     struct slip *sl;
 713     struct slcompress *comp;
 714 
 715     /* Find the correct SLIP channel to use. */
 716     sl = &sl_ctrl[dev->base_addr];
 717     if (! sl)
 718       return NULL;
 719 
 720     memset(&stats, 0, sizeof(struct enet_statistics));
 721 
 722     stats.rx_packets = sl->rpacket;
 723     stats.rx_over_errors = sl->roverrun;
 724     stats.tx_packets = sl->spacket;
 725     stats.tx_dropped = sl->sbusy;
 726     stats.rx_errors = sl->errors;
 727 #ifdef CONFIG_INET
 728     comp = sl->slcomp;
 729     if (comp) {
 730       stats.rx_fifo_errors = comp->sls_i_compressed;
 731       stats.rx_dropped = comp->sls_i_tossed;
 732       stats.tx_fifo_errors = comp->sls_o_compressed;
 733       stats.collisions = comp->sls_o_misses;
 734     }
 735 #endif
 736     return (&stats);
 737 }
 738 
 739 /*
 740  * Close down a SLIP channel.
 741  * This means flushing out any pending queues, and then restoring the
 742  * TTY line discipline to what it was before it got hooked to SLIP
 743  * (which usually is TTY again).
 744  */
 745 static void
 746 slip_close(struct tty_struct *tty)
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748   struct slip *sl = (struct slip *) tty->disc_data;
 749 
 750   /* First make sure we're connected. */
 751   if (!sl || sl->magic != SLIP_MAGIC) {
 752         return;
 753   }
 754 
 755   (void) dev_close(sl->dev);
 756 }
 757 
 758 
 759  /************************************************************************
 760   *                     STANDARD SLIP ENCAPSULATION                     *
 761   ************************************************************************
 762   *
 763   */
 764  
 765  int
 766  slip_esc(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 767  {
 768      int count = 0;
 769  
 770      /*
 771       * Send an initial END character to flush out any
 772       * data that may have accumulated in the receiver
 773       * due to line noise.
 774       */
 775  
 776      d[count++] = END;
 777  
 778      /*
 779       * For each byte in the packet, send the appropriate
 780       * character sequence, according to the SLIP protocol.
 781       */
 782  
 783      while(len-- > 0) {
 784         switch(*s) {
 785         case END:
 786             d[count++] = ESC;
 787             d[count++] = ESC_END;
 788             break;
 789         case ESC:
 790             d[count++] = ESC;
 791             d[count++] = ESC_ESC;
 792             break;
 793         default:
 794             d[count++] = *s;
 795         }
 796         ++s;
 797      }
 798      d[count++] = END;
 799      return(count);
 800  }
 801  
 802  void
 803  slip_unesc(struct slip *sl, unsigned char s)
     /* [previous][next][first][last][top][bottom][index][help] */
 804  {
 805      switch(s) {
 806      case ESC:
 807              sl->flags |= SLF_ESCAPE;
 808              break;
 809      case ESC_ESC:
 810              if (sl->flags & SLF_ESCAPE)
 811                      sl_enqueue(sl, ESC);
 812              else
 813                      sl_enqueue(sl, s);
 814              sl->flags &= ~SLF_ESCAPE;
 815              break;
 816      case ESC_END:
 817              if (sl->flags & SLF_ESCAPE)
 818                      sl_enqueue(sl, END);
 819              else
 820                      sl_enqueue(sl, s);
 821              sl->flags &= ~SLF_ESCAPE;
 822              break;
 823      case END:
 824              if (sl->rcount > 2) 
 825                      sl_bump(sl);
 826              sl_dequeue(sl, sl->rcount);
 827              sl->rcount = 0;
 828              sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
 829              break;
 830      default:
 831              sl_enqueue(sl, s);
 832              sl->flags &= ~SLF_ESCAPE;
 833      }
 834  }
 835 
 836  
 837  /************************************************************************
 838   *                      6 BIT SLIP ENCAPSULATION                       *
 839   ************************************************************************
 840   *
 841   */
 842  
 843  int
 844  slip_esc6(unsigned char *s, unsigned char *d, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 845  {
 846      int count = 0;
 847      int i;
 848      unsigned short v = 0;
 849      short bits = 0;
 850  
 851      /*
 852       * Send an initial END character to flush out any
 853       * data that may have accumulated in the receiver
 854       * due to line noise.
 855       */
 856  
 857      d[count++] = 0x70;
 858  
 859      /*
 860       * Encode the packet into printable ascii characters
 861       */
 862  
 863      for (i = 0; i < len; ++i) {
 864         v = (v << 8) | s[i];
 865         bits += 8;
 866         while (bits >= 6) {
 867             unsigned char c;
 868  
 869             bits -= 6;
 870             c = 0x30 + ((v >> bits) & 0x3F);
 871             d[count++] = c;
 872         }
 873      }
 874      if (bits) {
 875         unsigned char c;
 876  
 877         c = 0x30 + ((v << (6 - bits)) & 0x3F);
 878         d[count++] = c;
 879      }
 880      d[count++] = 0x70;
 881      return(count);
 882  }
 883  
 884  void
 885  slip_unesc6(struct slip *sl, unsigned char s)
     /* [previous][next][first][last][top][bottom][index][help] */
 886  {
 887      unsigned char c;
 888  
 889      if (s == 0x70) {
 890              if (sl->rcount > 8) {      /* XXX must be 2 for compressed slip */
 891  #ifdef NOTDEF
 892                      printk("rbuff %02x %02x %02x %02x\n",
 893                             sl->rbuff[0],
 894                             sl->rbuff[1],
 895                             sl->rbuff[2],
 896                             sl->rbuff[3]
 897                             );
 898  #endif
 899                      sl_bump(sl);
 900              }
 901             sl_dequeue(sl, sl->rcount);
 902             sl->rcount = 0;
 903             sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
 904             sl->xbits = 0;
 905         } else if (s >= 0x30 && s < 0x70) {
 906                 sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
 907                 sl->xbits += 6;
 908                 if (sl->xbits >= 8) {
 909                         sl->xbits -= 8;
 910                         c = (unsigned char)(sl->xdata >> sl->xbits);
 911                         sl_enqueue(sl, c);
 912                 }
 913         }
 914  }
 915 
 916 
 917 
 918 #ifdef CONFIG_AX25
 919 
 920 int sl_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 921 {
 922         int err=verify_area(VERIFY_READ,addr,7);
 923         if(err)
 924                 return err;
 925         memcpy_fromfs(dev->dev_addr,addr,7);    /* addr is an AX.25 shifted ASCII mac address */
 926         return 0;
 927 }
 928 
 929 static int sl_set_dev_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 930 {
 931         memcpy(dev->dev_addr,addr,7);
 932         return 0;
 933 }
 934 #endif
 935 
 936 
 937 /* Perform I/O control on an active SLIP channel. */
 938 static int
 939 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 940 {
 941   struct slip *sl = (struct slip *) tty->disc_data;
 942   int err;
 943 
 944   /* First make sure we're connected. */
 945   if (!sl || sl->magic != SLIP_MAGIC) {
 946         return(-EINVAL);
 947   }
 948 
 949   switch(cmd) {
 950         case SIOCGIFNAME:
 951                 err=verify_area(VERIFY_WRITE, arg, 16);
 952                 if(err)
 953                         return -err;
 954                 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
 955                 return(0);
 956         case SIOCGIFENCAP:
 957                 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
 958                 put_fs_long(sl->mode,(long *)arg);
 959                 return(0);
 960         case SIOCSIFENCAP:
 961                 err=verify_area(VERIFY_READ,arg,sizeof(long));
 962                 sl->mode=get_fs_long((long *)arg);
 963 #ifdef CONFIG_AX25              
 964                 if(sl->mode & SL_MODE_AX25)
 965                 {
 966                         sl->dev->addr_len=7;    /* sizeof an AX.25 addr */
 967                         sl->dev->hard_header_len=17;    /* We don't do digipeaters */
 968                 }
 969                 else
 970                 {
 971                         sl->dev->addr_len=0;    /* No mac addr in slip mode */
 972                         sl->dev->hard_header_len=0;
 973                 }
 974 #endif          
 975                 sl->dev->type=ARPHRD_SLIP+sl->mode;
 976                 if(sl->dev->type==260)
 977                         sl->dev->type=ARPHRD_AX25;
 978                 return(0);
 979         case SIOCSIFHWADDR:
 980 #ifdef CONFIG_AX25      
 981                 return sl_set_mac_address(sl->dev,arg);
 982 #endif
 983         /* Allow stty to read, but not set, the serial port */
 984         case TCGETS:
 985         case TCGETA:
 986                 return n_tty_ioctl(tty, file, cmd, (unsigned long) arg);
 987                 
 988         default:
 989                 return -ENOIOCTLCMD;
 990   }
 991 }
 992 
 993 
 994 /* Initialize the SLIP driver.  Called by DDI. */
 995 int
 996 slip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 997 {
 998   struct slip *sl;
 999   int i;
1000 #ifdef CONFIG_AX25  
1001   static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1002   static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1003 #endif
1004 
1005   sl = &sl_ctrl[dev->base_addr];
1006 
1007   if (already++ == 0) {
1008         printk("SLIP: version %s (%d channels)\n",
1009                                 SLIP_VERSION, SL_NRUNIT);
1010 #ifdef CONFIG_INET                              
1011         printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1012 #endif  
1013 #ifdef CONFIG_AX25
1014         printk("AX25: KISS encapsulation enabled\n");
1015 #endif  
1016         /* Fill in our LDISC request block. */
1017         memset(&sl_ldisc, 0, sizeof(sl_ldisc));
1018         sl_ldisc.magic  = TTY_LDISC_MAGIC;
1019         sl_ldisc.flags  = 0;
1020         sl_ldisc.open   = slip_open;
1021         sl_ldisc.close  = slip_close;
1022         sl_ldisc.read   = NULL;
1023         sl_ldisc.write  = NULL;
1024         sl_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
1025                                    unsigned int, unsigned long)) slip_ioctl;
1026         sl_ldisc.select = NULL;
1027         sl_ldisc.receive_buf = slip_receive_buf;
1028         sl_ldisc.receive_room = slip_receive_room;
1029         sl_ldisc.write_wakeup = slip_write_wakeup;
1030         if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
1031                 printk("ERROR: %d\n", i);
1032   }
1033 
1034   /* Set up the "SLIP Control Block". */
1035   sl_initialize(sl, dev);
1036 
1037   /* Clear all statistics. */
1038   sl->rcount            = 0;                    /* SLIP receiver count  */
1039   sl->rpacket           = 0;                    /* #frames received     */
1040   sl->roverrun          = 0;                    /* "overrun" counter    */
1041   sl->spacket           = 0;                    /* #frames sent out     */
1042   sl->sbusy             = 0;                    /* "xmit busy" counter  */
1043   sl->errors            = 0;                    /* not used at present  */
1044 
1045   /* Finish setting up the DEVICE info. */
1046   dev->mtu              = SL_MTU;
1047   dev->hard_start_xmit  = sl_xmit;
1048   dev->open             = sl_open;
1049   dev->stop             = sl_close;
1050   dev->hard_header      = sl_header;
1051   dev->type_trans       = sl_type_trans;
1052   dev->get_stats        = sl_get_stats;
1053 #ifdef HAVE_SET_MAC_ADDR
1054 #ifdef CONFIG_AX25
1055   dev->set_mac_address  = sl_set_dev_mac_address;
1056 #endif
1057 #endif
1058   dev->hard_header_len  = 0;
1059   dev->addr_len         = 0;
1060   dev->type             = 0;
1061 #ifdef CONFIG_AX25  
1062   memcpy(dev->broadcast,ax25_bcast,7);          /* Only activated in AX.25 mode */
1063   memcpy(dev->dev_addr,ax25_test,7);            /*    ""      ""       ""    "" */
1064 #endif  
1065   dev->rebuild_header   = sl_rebuild_header;
1066   for (i = 0; i < DEV_NUMBUFFS; i++)
1067         skb_queue_head_init(&dev->buffs[i]);
1068 
1069   /* New-style flags. */
1070   dev->flags            = 0;
1071   dev->family           = AF_INET;
1072   dev->pa_addr          = 0;
1073   dev->pa_brdaddr       = 0;
1074   dev->pa_mask          = 0;
1075   dev->pa_alen          = sizeof(unsigned long);
1076 
1077   return(0);
1078 }

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