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

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