root/drivers/net/slip.c

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

DEFINITIONS

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

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